从0到1搭建webpack2+vue2自定义模板细致教程

媒介

webpack2和vue2已不是新颖东西了,满大街的文章在解说webpack和vue,然则很多内容写的不是很细致,关于很多个性化设置照样须要自身过一遍文档。Vue官方供应了多个vue-templates,基于vue-cli用官方的webpack模板占多半,不过关于很多人来讲,官方的webpack模板的设置照样过于庞杂,关于我们相识细节完成不是很好,所以想自身从零最先搭建一个模板工程,也趁便从新认识一下webpack和vue工程化的细节。

webpack 中心观点

Webpack 是当下最热点的前端资本模块化治理和打包东西。它可以将很多松懈的模块依据依靠和划定规矩打包成相符临盆环境布置的前端资本。还可以将按需加载的模块举行代码离开,比及现实须要的时刻再异步加载。经由历程 loader 的转换,任何情势的资本都可以视作模块,比方 CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、Coffeescript、 LESS 等。

《从0到1搭建webpack2+vue2自定义模板细致教程》

官方网站:https://webpack.js.org/

装置

在最先前,先要确认你已装置Node.js的最新版本。运用 Node.js 最新的 LTS 版本,是抱负的起步。运用旧版本,你可以碰到种种题目,因为它们可以缺乏 webpack 功用或缺乏相干 package 包。

当地部分装置:

# 装置 latest release
npm install --save-dev webpack
# 简写形式
npm install -D webpack
# 装置特定版本
npm install --save-dev webpack@<version> 

全局装置:

npm install -g webpack

注重:不引荐全局装置 webpack。这会锁定 webpack 到指定版本,而且在运用差别的 webpack 版本的项目中可以会致使构建失利。然则全局装置可以在敕令行挪用 webpack 敕令。

【补充】npm install 装置模块参数申明:

-g, --global 全局装置(global)
-S, --save 装置包信息将加入到dependencies(临盆阶段的依靠)
-D, --save-dev 装置包信息将加入到devDependencies(开辟阶段的依靠),所以开辟阶段平常运用它
-O, --save-optional 装置包信息将加入到optionalDependencies(可选阶段的依靠)
-E, --save-exact 准确装置指定模块版本

npm 相干的更多敕令参考这篇文章:npm 经常使用敕令详解

然后在根目次下竖立一个 webpack.config.js 文件后,你可以经由历程设置定义webpack的相干操纵。

进口(Entry)

进口出发点通知 webpack 从那里最先,并遵照着依靠关联图表晓得要打包什么。可以将您运用顺序的进口出发点认为是根上下文(contextual root)或 app 第一个启动文件。

单个进口(简写)语法:
用法:entry: string|Array<string>

webpack.config.js:

module.exports = {
  entry: './src/main.js'
};

对象语法:
用法:entry: {[entryChunkName: string]: string|Array<string>}

webpack.config.js:

module.exports = {
  entry: {
    app: './src/main.js',
    vendor: ['vue']
  }
};

这里我们将vue作为库vendor打包,营业逻辑代码作为app打包,完成了多个进口,同时也可以将多个页面离开打包。

多页面运用顺序一般运用对象语法构建。对象语法是“可扩大的 webpack 设置”,可重用而且可以与其他设置组合运用。这是一种盛行的手艺,用于将关注点(concern)从环境(environment)、构建目标(build target)、运转时(runtime)中星散。然后运用特地的东西(如webpack-merge)将它们兼并。

注:vue-cli 天生的模板中build文件夹下有四个设置文件:

后三个文件经由历程webpack-merge插件兼并了基本设置,将差别环境下的设置拆分多个文件,如许越发轻易治理。

出口(Output)

将一切的资本(assets)归拢在一起后,还须要通知 webpack 在那里打包运用顺序。webpack 的 output 属性形貌了怎样处置惩罚归拢在一起的代码(bundled code)。output 选项掌握 webpack 怎样向硬盘写入编译文件。注重,纵然可以存在多个进口出发点,但只指定一个输出设置。

在 webpack 中设置output 属性的最低要求是,将它的值设置为一个对象,包括以下两点:

  • output.filename:编译文件的文件名;

  • output.path对应一个绝对途径,此途径是你愿望一次性打包的目次。

单个进口:

const path = require('path');
module.exports = {
  entry: './src/app.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'build')  //__dirname + '/build'
  }
}

多个进口:
假如你的设置竖立了多个 “chunk”(比方运用多个进口出发点或运用相似CommonsChunkPlugin 的插件),你应当运用以下的替换体式格局来确保每一个文件名都不反复。

  • [name] 被 chunk 的 name 替换。

  • [hash] 被 compilation 生命周期的 hash 替换。

  • [chunkhash] 被 chunk 的 hash 替换。

const path = require('path');
module.exports = {
  entry: {
    app: './src/main.js',
    vendor: ['vue']
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'build')
  }
}

// 写入到硬盘:./build/app.js, ./build/vendor.js

加载器(Loaders)

loader 用于对模块的源代码举行转换。loader 可以使你在 require() 或”加载”模块时预处置惩罚文件。因而,loader 相似于其他构建东西中“使命(task)”,并供应了处置惩罚前端构建步骤的壮大要领。loader 可以将文件从差别的言语(如 TypeScript)转换为 JavaScript,或将内联图象转换为 data URL。loader 以至许可你在 JavaScript 中 require() CSS文件!

在你的运用顺序中,有三种体式格局运用 loader:

这里我们主要申明一下运用webpack.config.js设置,运用loader须要在module的rules下设置相应的划定规矩,以css-loader的webpack.config.js为例申明:

module.exports = { 
    module: { 
        rules: [
            {test: /\.css$/, use: 'css-loader'}
        ]
    }
};

这三种设置体式格局等效:

{test: /\.css$/, use: 'css-loader'}
{test: /\.css$/, loader: 'css-loader',options: { modules: true }}
{test: /\.css$/, use: {
    loader: 'css-loader',
    options: {
      modules: true
    }
}}

注:loader/query可以和options可以在统一级运用,然则不要运用use和options在统一级运用。

CSS款式星散

为了用 webpack 对 CSS 文件举行打包,你可以像别的模块一样将 CSS 引入到你的 JavaScript 代码中,同时用css-loader(像 JS 模块一样输出 CSS),也可以挑选运用ExtractTextWebpackPlugin(将打好包的 CSS 提出出来并输出成 CSS 文件)。

引入 CSS:

import 'bootstrap/dist/css/bootstrap.css';

装置css-loader和style-loader:

npm install --save-dev css-loader style-loader

在 webpack.config.js 中设置以下:

module.exports = {
    module: {
        rules: [{
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
        }]
    }
}

资本途径处置惩罚

因为.png等图片文件不是一个 JavaScript 文件,你须要设置 Webpack 运用file-loader或许url-loader去处置惩罚它们。运用它们的长处:

  • file-loader 可以指定要复制和安排资本文件的位置,以及怎样运用版本哈希定名以取得更好的缓存。别的,这意味着 你可以就近治理你的图片文件,可以运用相对途径而没必要忧郁布署时URL题目。运用准确的设置,Webpack 将会在打包输出中自动重写文件途径为准确的URL。

  • url-loader 许可你有条件将文件转换为内联的 base-64 URL(当文件小于给定的阈值),这会削减小文件的 HTTP 要求。假如文件大于该阈值,会自动的交给 file-loader 处置惩罚。

装置 file-loader 和 url-loader:

npm install --save-dev file-loader url-loader

设置申明:

{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        limit: 10000,
        name: 'img/[name]_[hash:7].[ext]'
    }
},
{
    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
    loader: 'url-loader',
    options: {
        limit: 10000,
        name: 'fonts/[name].[hash:7].[ext]'
    }
}

插件(Plugins)

因为 loader 仅在每一个文件的基本上实行转换,而插件(plugins)最经常使用于(但不限于)在打包模块的“compilation”和“chunk”生命周期实行操纵和自定义功用(检察更多)。webpack 的插件体系极为壮大和可定制化

想要运用一个插件,你只须要 require() 它,然后把它增加到 plugins 数组中。多半插件可以经由历程选项(option)自定义。你也可以在一个设置文件中因为差别目标而屡次运用统一个插件,你须要运用 new 竖立实例来挪用它。

临盆环境构建

关于Vue临盆环境构建历程当中紧缩运用代码和运用Vue.js 指南 – 删除正告去除 Vue.js 中的正告,这里我们参考vue-loader文档中的设置申明:

if (process.env.NODE_ENV === 'production') {
    // http://vue-loader.vuejs.org/zh-cn/workflow/production.html
    module.exports.plugins = (module.exports.plugins || []).concat([
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: '"production"'
            }
        }),
        new webpack.optimize.UglifyJsPlugin({
            sourceMap: false,
            compress: {
                warnings: false
            }
        }),
        new webpack.LoaderOptionsPlugin({
            minimize: true
        })
    ])
}

明显我们不想在开辟历程当中运用这些设置,所以这里我们须要运用环境变量动态构建,我们也可以运用两个离开的 Webpack 设置文件,一个用于开辟环境,一个用于临盆环境,相似于vue-cli中运用 webpack-merge 兼并设置的体式格局。

可以运用 Node.js 模块的范例体式格局:在运转 webpack 时设置环境变量,而且运用 Node.js 的process.env来援用变量。NODE_ENV变量一般被视为事实范例(检察这里)。运用cross-env包来跨平台设置(cross-platform-set)环境变量。

装置cross-env:

npm install --save-dev cross-env

设置package.json中的scripts字段:

"scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
}

这里我们运用了cross-env插件,cross-env使得你可以运用单个敕令,而无需忧郁为平台准确设置或运用环境变量。

模块热替换

模块热替换功用会在运用顺序运转历程当中替换、增加或删除模块,而无需从新加载页面。这使得你可以在自力模块变动后,无需革新全部页面,就可以更新这些模块,极大地加快了开辟时候。

这里我们运用webpack-dev-server插件,webpack-dev-server 为你供应了一个效劳器和及时重载(live reloading)功用。webpack-dev-server是一个小型的node.js Express效劳器,它运用webpack-dev-middleware中间件来为经由历程webpack打包天生的资本文件供应Web效劳。它还有一个经由历程Socket.IO连接着webpack-dev-server效劳器的小型运转时顺序。webpack-dev-server发送关于编译状况的音讯到客户端,客户端依据音讯作出相应。

装置 webpack-dev-server:

npm install --save-dev webpack-dev-server

装置完成以后,你应当可以运用 webpack-dev-server 了,体式格局以下:

webpack-dev-server --open

上述敕令应当自动在浏览器中翻开 http://localhost:8080

webpack.config.js设置:

module.exports = {
    ...
    devServer: {
        historyApiFallback: true, // 恣意的 404 相应都替换为 index.html
        hot: true, // 启用 webpack 的模块热替换特征
        inline: true // 启用内联形式
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ]
    ...
}

更多的设置申明可以看文档:DevServer

动态天生 html 文件

该插件将为你天生一个HTML5文件,个中包括运用script标签的body中的一切webpack包,也就是我们不须要手动经由历程script去引入打包天生的js,特别是假如我们天生的文件名是动态变化的,运用这个插件就可以轻松的处理,只需增加插件到您的webpack设置以下:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    ...
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: true
        })
    ]
    ...
}

提取 CSS 文件

extract-text-webpack-plugin是一个 可以将 *.vue 文件内的 <style> 提取,以及JavaScript 中导入的 CSS 提取为单个 CSS 文件。设置文档详细见这里:extract-text-webpack-plugin

装置:

npm install --save-dev extract-text-webpack-plugin

设置:

const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("styles.css"),
  ]
}

同时支撑我们可以设置天生多个css文件,如许我们可以将营业逻辑代码和援用的款式组件库星散。

const ExtractTextPlugin = require('extract-text-webpack-plugin');

// Create multiple instances
const extractCSS = new ExtractTextPlugin('stylesheets/[name]-one.css');
const extractLESS = new ExtractTextPlugin('stylesheets/[name]-two.css');

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: extractCSS.extract([ 'css-loader', 'postcss-loader' ])
      },
      {
        test: /\.less$/i,
        use: extractLESS.extract([ 'css-loader', 'less-loader' ])
      },
    ]
  },
  plugins: [
    extractCSS,
    extractLESS
  ]
};

clean-webpack-plugin

在编译前,删除之前编译效果目次或文件:

npm install --save-dev clean-webpack-plugin

设置:

plugins: [
    new CleanWebpackPlugin(['dist'])
]

如许当我们在构建的时刻可以自动删除之前编译的代码。

剖析(Resolve)

这些选项能设置模块怎样被剖析。webpack 供应合理的默许值,然则照样可以会修正一些剖析的细节。

resolve: {
  alias: {
    'vue$': 'vue/dist/vue.esm.js',
    '@': path.join(__dirname, 'src')
  },
  extensions: ['.js', '.json', '.vue', '.css']
}

我们运用最多的就是别号(alias)和自动剖析肯定的扩大(extensions),比方上面的@可以替换项目中src的途径,比方:

import tab from '@/components/tab.vue'

我们援用src/components目次下的tab.vue组件,不须要经由历程../之类的盘算文件相对途径。这里的extensions可以让我们在引入模块时不带扩大:

import tab from '@/components/tab'

至此我们已进修了我们项目devDependencies依靠中经常使用的模块:

webpack 
css-loader / style-loader
file-loader / url-loader 
cross-env 
webpack-dev-server 
html-webpack-plugin 
extract-text-webpack-plugin
clean-webpack-plugin

这里我们只申清晰明了css、图片、html模板资本webpack相干的加载器和插件,关于js相干的内容涓滴没有提到,明显这是不合乎道理的。之所以要把js零丁拿出来是因为js相干的内容很主要,自力出来细致去归结一下更适宜。

webpack 中怎样运用 es6 ~ es8?

作为一个前端,置信 es6 几乎是无人不知,很多人也肯定晓得可以运用Babel做语法转换,然则关于Babel有哪一些版本,每一个版本支撑的es6语法有哪一些应当不是一切人都清晰的,这就是这部分内容要写的意义。毕竟假如我们的插件只用到了es6中的没一些新特征,为此将全部包引入就有点不太适宜,别的为了更好的用上新特征,我们最少要邃晓有哪一些新特征吧。

ECMAScript 范例竖立的历程

ECMAScript 和 JavaScript 的关联在此不再赘述,发起浏览一下阮一峰先生的《ECMAScript 6简介》,我们须要相识的是从ECMAScript 2016最先,ECMAScript将进入每一年宣布一次新范例的阶段。制订ECMAScript 范例的构造是ECMAScript TC39TC39(ECMA手艺委员为39)是推进JavaScript生长的委员会。 它的成员是都是企业(主如果浏览器厂商)。TC39会按期的开会, 集会的主要成员时是成员公司的代表,以及受约请的专家。

一种新的语法从提案到变成正式范例,须要阅历五个阶段。每一个阶段的变动都须要由 TC39 委员会同意。

  • Stage 0 – Strawman(展现阶段)

  • Stage 1 – Proposal(征求意见阶段)

  • Stage 2 – Draft(草案阶段)

  • Stage 3 – Candidate(候选人阶段)

  • Stage 4 – Finished(定案阶段)

发起看一下alinode 团队的图说ECMAScript新范例(一)就可以大抵相识全部历程。

装置 Babel

Babel 如今的官网供应了一个可以依据你的东西提醒下载适宜的包,详细见这里:Using Babel

假如你想要在敕令行运用Babel,你可以装置babel-cli,然则全局的装置babel-cli不是一个好的挑选,因为如许限制了你Babel的版本;假如你须要在一个Node项目中运用Babel,你可以运用babel-core。

我们这里天然挑选webpack构建我们的工程,下载计划以下:

npm install --save-dev babel-loader babel-core

然后我们须要在项目根目次下竖立.babelrc文件:

{
  "presets": [],
  "plugins": []
}

注:在window下没法经由历程 右键=>新建 敕令来竖立以点开首的文件和文件夹,我们可以经由历程下面的敕令天生.babelrc文件:

type NUL > .babelrc

Linux和Mac下可以经由历程touch敕令天生:

touch .babelrc

Babel 预设(presets)

Babel是一个编译器。 在高层次上,它有3个阶段,它运转代码:剖析,转换和天生(像很多其他编译器)。默许情况下,Babel 6并没有照顾任何转换器,因而假如对你的代码运用Babel的话,它将会原文输出你的代码,不会有任何的转变。因而你须要依据你须要完成的使命来零丁装置相应的插件。

你可以经由历程装置插件(plugins)或预设(presets,也就是一组插件)来指导 Babel 去做什么事情。Babel 供应了多个版本的官方预设:

babel-preset-env

babel-preset-env可以依据你设置的选项,自动增加一些其他的转换器,来满足你当前的装换需求。.babelrc文件新增了options选项:

{
  "presets": ["env", options]
}

详细的设置内容:

  • targets.node 支撑到哪一个版本的 node

  • targets.browsers 支撑到哪一个版本的浏览器

  • loose 启动宽松形式,合营 webpack 的 loader 运用

  • modules 运用何种模块加载机制

  • debug 开启调试形式

  • include 包括哪些文件

  • exclude 消除哪些文件

  • useBuiltIns 是不是对 babel-polyfill 举行剖析,只引入所需的部分

babel-preset-es2015

es2015(ES6)相干要领转译运用的插件,详细见文档

  • check-es2015-constants // 磨练const常量是不是被从新赋值

  • transform-es2015-arrow-functions // 编译箭头函数

  • transform-es2015-block-scoped-functions // 函数声明在作用域内

  • transform-es2015-block-scoping // 编译const和let

  • transform-es2015-classes // 编译class

  • transform-es2015-computed-properties // 编译盘算对象属性

  • transform-es2015-destructuring // 编译解构赋值

  • transform-es2015-duplicate-keys // 编译对象中反复的key,现实上是转换成盘算对象属性

  • transform-es2015-for-of // 编译for…of

  • transform-es2015-function-name // 将function.name语义运用于一切的function

  • transform-es2015-literals // 编译整数(8进制/16进制)和unicode

  • transform-es2015-modules-commonjs // 将modules编译成commonjs

  • transform-es2015-object-super // 编译super

  • transform-es2015-parameters // 编译参数,包括默许参数,不定参数和解构参数

  • transform-es2015-shorthand-properties // 编译属性缩写

  • transform-es2015-spread // 编译睁开运算符

  • transform-es2015-sticky-regex // 正则增加sticky属性

  • transform-es2015-template-literals // 编译模版字符串

  • transform-es2015-typeof-symbol // 编译Symbol范例

  • transform-es2015-unicode-regex // 正则增加unicode形式

  • transform-regenerator // 编译generator函数

babel-preset-es2016

es2016(ES7)相干要领转译运用的插件,详细见文档

  • transform-exponentiation-operator // 编译幂运算符

babel-preset-es2017

es2017(ES8)相干要领转译运用的插件,详细见文档

  • syntax-trailing-function-commas // function末了一个参数许可运用逗号

  • transform-async-to-generator // 把async函数转化成generator函数

babel-preset-latest

latest是一个特别的presets,包括了es2015,es2016,es2017的插件,不过已烧毁,运用babel-preset-env替换,详细见文档

stage-x(stage-0/1/2/3/4)

stage-x预设中的任何转换都是尚未被同意为宣布Javascript的言语(如ES6 / ES2015)的变动。

stage-x和上面的es2015等有些相似,然则它是依据JavaScript的提案阶段辨别的,一共有5个阶段。而数字越小,阶段越靠后,存在依靠关联。也就是说stage-0是包括stage-1的,以此类推。

babel-preset-stage-4:

stage-4的插件:

babel-preset-stage-3:

除了stage-4的内容,还包括以下插件:

babel-preset-stage-2:

除了stage-3的内容,还包括以下插件:

babel-preset-stage-1:

除了stage-2的内容,还包括以下插件:

babel-preset-stage-0:

除了stage-1的内容,还包括以下插件:

为了轻易,我们临时援用 babel-preset-envbabel-preset-stage-2这两个预设。为了启用预设,必需在.babelrc文件中定义预设的相干设置,这里参考vue-cli 模板中的设置
装置:

npminstall --save-dev babel-preset-env babel-preset-stage-2

.babelrc设置申明:

{
  "presets": [
    ["env", { 
      "modules": false 
    }],
    "stage-2"
  ]
}

Babel 插件(plugins)

我们看一下预设的构造诣晓得,实在就是plugins的组合。假如你不采纳presets,完整可以零丁引入某个功用,比方以下的设置就会引入编译箭头函数的功用,在.babelrc文件中举行设置:

{
  "plugins": ["transform-es2015-arrow-functions"]
}

babel-polyfill 与 babel-runtime

Babel默许只转换新的JavaScript句法(syntax),而不转换新的API,比方Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的要领(比方 Object.assign)都不会转码。

举例来讲,ES6在 Array 对象上新增了 Array.from 要领。Babel就不会转码这个要领。假如想让这个要领运转,必需运用 babel-polyfill ,为当前环境供应一个垫片。babel-polyfill 是对浏览器缺失API的支撑。

babel-runtime 是为了削减反复代码而生的。 babel天生的代码,可以会用到一些_extend(), classCallCheck() 之类的东西函数,默许情况下,这些东西函数的代码会包括在编译后的文件中。假如存在多个文件,那每一个文件都有可以含有一份反复的代码。babel-runtime插件可以将这些东西函数的代码转换成require语句,指向为对babel-runtime的援用,如require('babel-runtime/helpers/classCallCheck'). 如许, classCallCheck的代码就不须要在每一个文件中都存在了。

启用插件 babel-plugin-transform-runtime 后,Babel 就会运用 babel-runtime 下的东西函数。除此之外,babel 还为源代码的非实例要领(Object.assign,实例要领是相似如许的 “foobar”.includes(“foo”))和 babel-runtime/helps 下的东西函数自动援用了 polyfill。如许可以防止污染全局定名空间,异常适合于 JavaScript 库和东西包的完成。

总结:

  • 详细项目照样须要运用 babel-polyfill,只运用 babel-runtime 的话,实例要领不能一般事情(比方 “foobar”.includes(“foo”));

  • JavaScript 库和东西可以运用 babel-runtime,在现实项目中运用这些库和东西,须要该项目自身供应 polyfill。

  • transform-runtime只会对es6的语法举行转换,而不会对新api举行转换。假如须要转换新api,就要引入babel-polyfill。

装置插件

npm install --save-dev babel-plugin-transform-runtime

.babelrc 设置:

{
  "plugins": ["transform-runtime", options]
}

options主要有以下设置项:

  • helpers: boolean,默许true,运用babel的helper函数;

  • polyfill: boolean,默许true,运用babel的polyfill,然则不能完整庖代babel-polyfill;

  • regenerator: boolean,默许true,运用babel的regenerator;

  • moduleName: string,默许babel-runtime,运用对应module处置惩罚。

注:默许moduleName为babel-runtime,这里我们可以没必要显式的下载babel-runtime,因为babel-plugin-transform-runtime依靠于babel-runtime。

babel-register

babel-register 模块改写 require 敕令,为它加上一个钩子。今后,每当运用 require 加载 .js 、 .jsx 、 .es 和 .es6 后缀名的文件,就会先用Babel举行转码。引入babel-register,如许背面的文件就可以用 import 替换require,import的长处在于可以引入所需要领或许变量,而不须要加载全部模块,提高了机能。

装置:

npm install --save-dev babel-register

这部分我们又引见了下面几个模块的装置:

babel-loader
babel-core
babel-preset-env 
babel-preset-stage-2 
babel-plugin-transform-runtime
babel-register

webpack 中怎样运用 vue?

既然本文的目标是vue的自定义模板工程,那末天然这里须要零丁引见一下webpack中vue相干的插件。

Vue2文件比较

npm 装置:

npm install --save vue

vue2 经由 2.2 版本晋级后, 文件变成 8 个:

UMDCommonJSES Module
自力构建vue.jsvue.common.jsvue.esm.js
运转构建vue.runtime.jsvue.runtime.common.jsvue.runtime.esm.js

vue.min.js 和 vue.runtime.min.js 都是对应的紧缩版。

  • AMD:异步模块范例

  1. 没有零丁供应 AMD 模块的版本,然则UMD版本中举行了包装,可以直接用作 AMD 模块,运用要领以下:

define(["Vue"],function(Vue) {
    function myFn() {
        ...
    }
    return myFn;
});
  • CommonJS:
    node中经常使用的模块范例,经由历程require引入模块,module.exports导出模块。

...
function Vue$3() {
   ...
}
...
module.exports = Vue$3;
  • UMD: 通用模块范例
    兼容了AMD和CommonJS,同时还支撑老式的“全局”变量范例:

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global.Vue = factory());
}(this, (function () { 'use strict';
    ...
    function Vue$3() {
        ...
    }
    ...
    return Vue$3;
})));
  • ES Module
    ES6在言语范例的层面上,完成的模块功用。模块功用主要由两个敕令组成:export和import。export敕令用于划定模块的对外接口,import敕令用于输入其他模块供应的功用。

...
function Vue$3() {
   ...
}
export default Vue$3;

总结:

  • vue.js 和 vue.runtime.js 可以用于直接 CDN 援用;

  • vue.common.js和vue.runtime.common.js可以运用Webpack1 / Browserify 打包构建;

  • vue.esm.js和vue.runtime.esm.js可以运用Webpack2 / rollup 打包构建。

vue有两种构建体式格局,自力构建和运转时构建。它们的区分自力构建前者包括模板编译器而运转构建不包括。模板编译器的职责是将模板字符串编译为纯 JavaScript 的衬着函数。假如你想要在组件中运用 template 选项,你就须要编译器。

  • 自力构建包括模板编译器并支撑 template 选项。 它也依靠于浏览器的接口的存在,所以你不能运用它来为效劳器端衬着。

  • 运转时构建不包括模板编译器,因而不支撑 template 选项,只能用 render 选项,但纵然运用运转时构建,在单文件组件中也依旧可以写模板,因为单文件组件的模板会在构建时预编译为 render 函数。运转时构建比自力构建要轻量30%,只要 17.14 Kb min+gzip大小。

自力构建体式格局可以如许运用template选项:

import Vue from 'vue'
new Vue({
  template: `
    <div id="app">
      <h1>Basic</h1>
    </div>
  `
}).$mount('#app')

这里我们运用ES Module范例,默许 NPM 包导出的是运转时构建。为了运用自力构建,在 webpack 设置中增加下面的别号:

resolve: {
  alias: {
    'vue$': 'vue/dist/vue.esm.js'
  }
}

vue-loader

装置:

npm install --save-dev vue-loader vue-template-compiler

vue-loader 依靠于 vue-template-compiler。

vue-loader 是一个 Webpack 的 loader,可以将用下面这个花样编写的 Vue 组件转换为 JavaScript 模块。这里有一些 vue-loader 供应的很酷的特征:

  • ES2015 默许支撑;

  • 许可对 Vue 组件的组成部分运用别的 Webpack loaders,比方对 <style> 运用 SASS 和对 <template> 运用 Jade;

  • .vue 文件中许可自定义节点,然后运用自定义的 loader 处置惩罚他们;

  • <style> <template> 中的静态资本看成模块来看待,并运用 Webpack loaders 举行处置惩罚;

  • 对每一个组件模拟出 CSS 作用域;

  • 支撑开辟期组件的热重载。

简而言之,编写 Vue.js 运用顺序时,组合运用 Webpack 和 vue-loader 能带来一个当代,天真而且异常壮大的前端事情流程。

在 Webpack 中,一切的预处置惩罚器须要婚配对应的 loader。 vue-loader 许可你运用别的 Webpack loaders 处置惩罚 Vue 组件的某一部分。它会依据 lang 属性自动推断出要运用的 loaders。

上述我们提到extract-text-webpack-plugin插件提取css,这里申明一下.vue中style标签之间的款式提取的方法:

var ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            css: ExtractTextPlugin.extract({
              use: 'css-loader',
              fallback: 'vue-style-loader' // <- 这是vue-loader的依靠,所以假如运用npm3,则不须要显式装置
            })
          }
        }
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("app.css")
  ]
}

pug 模板

用过模板的都晓得,熟习了模板写起来快多了,赫赫有名的jade生怕无人不知吧。pug是什么鬼?第一次听到的时刻我也猎奇了,然后查了一下才晓得,Pug原名不叫Pug,本来是赫赫有名的jade,厥后因为商标的缘由,改成Pug,哈巴狗。以下是官方诠释:

it has been revealed to us that “Jade” is a registered trademark, and as a result a rename is needed. After some discussion among the maintainers, “Pug” has been chosen as the new name for this project.

简朴看了看照样本来jade熟习的语法划定规矩,坚决在这个模板工程内里用上。

vue-loader内里关于模版的处置惩罚体式格局略有差别,因为大多半 Webpack 模版处置惩罚器(比方 pug-loader)会返回模版处置惩罚函数,而不是编译的 HTML 字符串,我们运用原始的 pug 替换 pug-loader:

npm install pug --save-dev

运用:

<template lang="pug">
div
  h1 Hello world!
</template>

主要: 假如你运用 vue-loader@<8.2.0, 你还须要装置 template-html-loader

PostCSS

装置vue-loader的时刻默许装置了postcss,由vue-loader处置惩罚的 CSS 输出,都是经由历程PostCSS举行作用域重写,你还可认为 PostCSS 增加自定义插件,比方autoprefixer或许CSSNext

在 webpack 工程中运用 postcss,我们须要下载 postcss-loader:

npm install --save-dev postcss-loader

cssnext

cssnext 是一个 CSS transpiler,许可你运用最新的 CSS 语法。cssnext 把 新 CSS 范例转换成兼容性更强的 CSS,所以不须要守候种种浏览器支撑。

装置:

npm install --save-dev postcss-cssnext

postcss.config.js:

module.exports = {
    plugins: [
        require('postcss-cssnext')
    ]
}

webpack.config.js:

module.exports = {
    module: {
        loaders: [
            {
                test:   /\.css$/,
                use: ['style-loader', 'css-loader', 'postcss-loader']
            }
        ]
    }
}

cssnext 依靠了autoprefixer,所以我们无需显式下载autoprefixer。更多关于postcss的插件可以看这里:postcss plugins

这一部分我们进修了这些依靠:

vue
vue-loader 
vue-template-compiler
pug
postcss-loader
postcss-cssnext

webpack2 开启 eslint 校验

范例自身的代码从ESlint最先。ESlint和webpack集成,在babel编译代码最先前,举行代码范例检测。这里我们运用javascript-style-standard作风的校验。

主要依靠的几个包:

eslint —— 基本包
eslint-loader —— webpack loader
babel-eslint —— 校验babel
eslint-plugin-html —— 提取并磨练你的 .vue 文件中的 JavaScript
eslint-friendly-formatter —— 天生美化的报告花样

# javascript-style-standard 依靠的包
eslint-config-standard
eslint-plugin-import
eslint-plugin-node
eslint-plugin-promise
eslint-plugin-standard

装置:

npm install --save-dev eslint eslint-loader babel-eslint eslint-plugin-html eslint-friendly-formatter eslint-config-standard eslint-plugin-import eslint-plugin-node eslint-plugin-node eslint-plugin-promise eslint-plugin-standard

关于eslint的设置体式格局,比较多元化,详细可以看设置文档

  • js解释

  • .eslintrc.*文件

  • package.json内里设置eslintConfig字段

装置eslint-loader以后,我们可以在webpack设置中运用eslint加载器。webpack.config.js

...
module: {
  loaders: [
    {
         test: /\.vue|js$/,
         enforce: 'pre',
         include: path.resolve(__dirname, 'src'),
         exclude: /node_modules/,
         use: [{
             loader: 'eslint-loader',
             options: {
                 formatter: require('eslint-friendly-formatter')
             }
         }]
    }
  ]
},
...

别的,我们既可以在webpack设置文件中指定检测划定规矩,也可以遵照最好实践在一个特地的文件中指定检测划定规矩,我们就采纳背面的体式格局。
在根目次下:

touch .eslintrc.js

.eslintrc.js:

module.exports = {
  root: true,
  parser: 'babel-eslint',
  parserOptions: {
    sourceType: 'module'
  },
  env: {
    browser: true
  },
  extends: 'standard',
  // required to lint *.vue files
  plugins: [
    'html'
  ],
  // add your custom rules here
  rules: {
    // allow paren-less arrow functions
    'arrow-parens': 0,
    // allow async-await
    'generator-star-spacing': 0,
    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
  }
}

这部分我们主要进修了一下eslint相干插件的寄义和设置要领。

竖立属于你的模板

假如你对官方的模板不感兴趣,你可以自身fork下来然后举行修正(或许从新写一个),然后用 vue-cli 来挪用。因为 vue-cli 可以直接拉取 git源:

vue init username/repo my-project

这里我们参考vue-cli的模板工程自身写一个模板工程,主如果须要经由历程meta.*(js,json)举行设置:

module.exports = {
  "helpers": {
    "if_or": function (v1, v2, options) {
      if (v1 || v2) {
        return options.fn(this);
      }

      return options.inverse(this);
    }
  },
  "prompts": {
    "name": {
      "type": "string",
      "required": true,
      "message": "Project name"
    },
    "version": {
      "type": "string",
      "required": false,
      "message": "Project version",
      "default": "1.0.0"
    },
    "description": {
      "type": "string",
      "required": false,
      "message": "Project description",
      "default": "A Vue.js project"
    },
    "author": {
      "type": "string",
      "message": "Author"
    },
    "router": {
      "type": "confirm",
      "message": "Install vue-router?"
    },
    "vuex": {
      "type": "confirm",
      "message": "Install vuex?"
    }
  },
  "completeMessage": "To get started:\n\n  {{^inPlace}}cd {{destDirName}}\n  {{/inPlace}}npm install\n  npm run dev\n\nDocumentation can be found at https://github.com/zhaomenghuan/vue-webpack-template"
};

这里我们就是采纳最简朴的体式格局,关于vue-router、vuex的设置每一个人习气不一样,所以不写在模板工程内里。

然后运用vue-cli运用这个模板竖立工程,没有装置vue-cli的实行:

npm install --global vue-cli

然后竖立工程:

# 竖立一个基于 webpack 模板的新项目
vue init zhaomenghuan/vue-webpack-template my-project
# 装置依靠,走你
cd my-project
npm install
npm run dev

这里依据国际惯例安利一下本文的模板工程:vue-webpack-template

参考

webpack官方文档
babel官方文档
vue-loader中文文档
JavaScript books by Dr. Axel Rauschmayer
ES7新特征及ECMAScript范例的制订流程
怎样写好.babelrc?Babel的presets和plugins设置剖析
babel的polyfill和runtime的区分
webpack2集成eslint

《从0到1搭建webpack2+vue2自定义模板细致教程》

近期在segmentfault课堂开设了一场关于html5+ App开辟工程化实践之路的讲座,迎接前来围观:https://segmentfault.com/l/15…

    原文作者:匠心
    原文地址: https://segmentfault.com/a/1190000009454172
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞