前言

高达一致意在由零构建了一个基础版的vue-cli项目,主要介绍了loader的设置以及组成部分布局起的用法,还被项目上加了less预处理器

齐同一梦想的链接-于搭建vue-脚手架到控制webpack配置(一.基础部署)

本期起引入常用的插件实现支付环境和转环境会就此到的有效果,比如热插拔、css样式提取、公共模块提、取代码压缩等等

区分出和生环境

多插件功能是在支付条件(development)用到之而于s生产环境(production)用非顶的,反之亦然。比如

-development用到的
  • 热插拔调试
  • 生成html模板
-production用到的
  • 生成html模板
  • css样式提取
  • 公模块提取
  • JavaScript压缩
  • ……

引用合法的传教
,区分生产及付出环境有零星种植方式,如下图

image

第二种植艺术涉及到第二破封装,就如官vue-cli构建的色一律,分成了三只布局文件,对当前之我们吧比较复杂,我们应用第一栽方式,设置环境变量来分部署环境。

参考vue-cli生成的简约版工程(webpack-simple),我们发现npm
script写得有些意想不到

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

每当运转webpack命令之前运行了
cross-env NODE_ENV=develpomentproduction,这虽是被环境变量赋值的经过,但是仅仅这样形容是心有余而力不足实施之,我们需要装一个插件——cross-env

npm install --save cross-env

这样我们便足以当后来运行于node环境的js
文件中做客到这些环境变量,通过process.env目标还能拿到package.json里面的布信息,这就事关到node的知了,不多说。

const env = process.env.NODE_ENV
//获取工程的版本号
const version = process.env.npm_package_version

简简单单点写,把环境变量的判断直接坐webpack.config.js文件之极致下面

const path = require('path')
const webpack = require('webpack')

module.exports = {
    entry:{
        app:'./src/main.js'
    },
    //...
}
/**
 * 生成生产代码的时候才触发
 */
if (process.env.NODE_ENV === 'production') {
    // http://vue-loader.vuejs.org/en/workflow/production.html
    module.exports.plugins = (module.exports.plugins || []).concat([
        new webpack.DefinePlugin({
            'process.env': {
            NODE_ENV: '"production"'
            }
        }),
    ])
  }

一经后额外的安排起更加多以来,像面这样勾画是匪顶好统一配置起之,到最后要要抽离出别样一个js文件装载新增或更写的配备起,用webpack-merge中间件合并配置对象。

webpack.DefinePlugin插件是安全局常量的插件,要切记!赋值的上记得写成'"production"',
官方对DefinePlugin插件
是这样说之

在意,因为是插件直接实施文书替换,给一定的价值必须带有字符串本身内之实在引号。通常,有些许栽艺术来齐这功效,使用
‘”production”‘, 或者下 JSON.stringify(‘production’)。

生成html模板

前面根本目录下index.html要我们协调引入js资源地址,有新的资源还要手动引入,很烦,这时候就会见为此到HtmlWebpackPlugin
插件,按照index.html作为模板在dist目录下生成带达装有资源的html 文件。

npm install --save-dev html-webpack-plugin

先期经require引入插件,然后在出口对象中加加plugins属性,数据值类型是数组,数组成员new [插件]()增长插件就是实行。每个插件都起和好之配备起与规范,可以查
npmjs 或者
他们之法定文档

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

module.exports = {
    entry:{
        app:'./src/main.js'
    },
    output:{
        path:path.resolve(__dirname,'./dist'),
        filename:"js/[name].js",
    },
    module:{
        rules:[
        //...
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            filename:'index.html',
            title:'vue demo',
            template:'./index.html',
        })
    ],
    externals:{
        'jquery':'window.jQuery'
    }
}
说明
  • filename 生成的html的文本称,不填就默认是本来文件称
  • title title标签的情节
  • template html模板地址,这里我们之所以本人及一样期待建在跟目录的index.html

此处出长辈对HtmlWebpackPlugin的详见说明文章

index.html的内容如果改一转移了,因为webpack打包了后自动抬高资源地址及html文件里,所以我们只要删掉原本写上去的script标签

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue demo</title>
</head>
<body>
    <div id="app">

    </div>
    <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js"></script>
</body>
</html>

有人也许会见意外,这里怎么加了一个cdn的jQuery,因为自己而于此带了一个知识点:有时候我们见面发出因此到cdn加速的堆栈资源,但是非知情怎么在工程被动用。

好简短我们当html模板被一直引入,然后以webpack.config.js配置中加以相同件“外部引入”(externals)

// webpack.config.js
externals:{
    'jquery':'window.jQuery'
}
//app.vue中引入
import $ from 'jquery'

热替换

web服务器

使用热替换之前当然如果先行出一个web服务器环境啦,安装webpack-dev-server

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

webpack-dev-server其实是一个独门的插件,但是webpack内置了其的配备起,属性devServer对应之就是它的安排起。

module.exports = {
    entry:{
        app:'./src/main.js'
    },
    output:{
        path:path.resolve(__dirname,'./dist'),
        filename:"js/[name].js",
    },
    devServer:{
        contentBase:"./dist"
    }
}

端口地址什么的都默认
http://localhost:8080/
,就设置了与资源目录地址contentBase。
相思再度深刻的去安排可以扣押官方文档
dev-server。我还确确实实没当真看了,嘻嘻。

热替换插件

热替换就是出之长河中改文件内容后并非反复刷新页面,修改会自动同步到浏览器被,webpack内部就发出立卖插件了,不用装直接还因此就可。在plugins添加同码
new webpack.HotModuleReplacementPlugin()就ok了

plugins:[
        new HtmlWebpackPlugin({
            filename:'index.html',
            title:'vue demo',
            template:'./index.html',
        }),
        new webpack.HotModuleReplacementPlugin()
    ]

改一下npm scripts

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

运行 npm run dev,热部署搞定

以上是开发条件要因此到的插件,下面就是是生成环境从而到之插件了

css文件以及vue内样式提取

如非取css样式,所有的.css文件及vue内的style都见面盖style标签的样式给补加到页面的head里面,不便宜资源的缓存而且下降了页面的加载速度。

哼之,就用extract-text-webpack-plugin插件吧,老规矩安装一下

npm install extract-text-webpack-plugin --save-dev
概括以

于使css相关loader之前先用本插件过滤一合

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

module.exports = {
  // other options...
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            css: ExtractTextPlugin.extract({
              use: 'css-loader',
              fallback: 'vue-style-loader' // <- 这是vue-loader的依赖
            }),
            //用了less或者sass的地方都要用上哦
            'less': ExtractTextPlugin.extract({
                use:[
                    'css-loader',
                    'less-loader'
                ],
                fallback:'vue-style-loader'
            })
          }
        }
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("styles/style.css")
  ]
}

vue内部的style需要事先抽取出来,所以一旦当fallback属性上助长预先的加载器
‘vue-style-loader’,’vue-style-loader’是vue-loader自带的啊,如果运行时报错的言语那便手动install一下他吧。

变动多文本

本人一般的惯是管外部引入的css文件认为是可以复用的,而vue内的style是每个页面还不相同的而另外生成的,所以自己修了两ExtractTextPlugin实例分别抽取样式到一定量个公文里。

const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const ExtractRootCss = new ExtractTextPlugin({filename:'styles/root.css',allChunks:false});
const ExtractVueCss = new ExtractTextPlugin({filename:'styles/[name]/style.css',allChunks:true});

module.exports = {
    //other options...
    module:{
        rules:[
        //...
            {
                test:/\.css$/,
                //这里用的ExtractRootCss
                use:ExtractRootCss.extract({
                    fallback:'style-loader',
                    use:['css-loader']
                })
            },
            {
                test:/\.less$/,
                //这里用的ExtractRootCss
                use:ExtractRootCss.extract({
                    fallback:'style-loader',
                    use:[
                        'css-loader',
                        'less-loader'
                    ]
                })
            },
            {
                test:/\.vue$/,
                loader:'vue-loader',
                options:{
                    loaders:{
                        //这里用的ExtractVueCss
                        'css': ExtractVueCss.extract({
                            use: 'css-loader',
                            fallback: 'vue-style-loader' // <- 这是vue-loader的依赖,所以如果使用npm3,则不需要显式安装
                          }),
                        //这里用的ExtractVueCss
                        'less':
                        ExtractVueCss.extract({
                            use:[
                                'css-loader',
                                'less-loader'
                            ],
                            fallback:'vue-style-loader'
                        })
                    },
                }
            },
        ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            filename:'index.html',
            title:'vue demo',
            template:'./index.html',
        }),
        ExtractRootCss,//填入插件实例,复用的css
        ExtractVueCss,//记得按顺序填入,vue内的css
        new webpack.HotModuleReplacementPlugin(),
    ]
}

眼看就是是ExtractTextPlugin插件生成多独公文的办法。你吧得以自己之惯去安排。

国有代码提取

当差不多页面或者多入口的下(entry设了非但一个),不同之模块(chunks)会反复引入一样的资源模块(module,也便是import引入的js文件),还有vue等库底代码,以上这些复用的代码最好是可独立出来,一方面有利于缓存,一方面减少包的体积。

CommonsChunkPlugin插件就是是化解就同题材之,它由属于webpack.optimize对象所以也是匪用装之。具体采用如下

new webpack.optimize.CommonsChunkPlugin({
    name: 'vender',
    minChunks:2
})

minChunks参数可以是number类型,填2
乃是发生2单chunk以上用到的公物块就会见于由包的vender.js里面。minChunks也得污染一个方,返回值是boolean类型.

(chunk可以省略明了吧entry属性设置的进口而转变的整条关系养,所以到目前为止本档也不过发一个chunk,就是’app’,当然插件生成的vender也是一个chunk。对初学者的话即使这样懂吧,用几近矣自然会来概念)

既然如此只发生一个chunk
那即便先行抽取公用库中之代码吧,如vue包中的代码。把代码放到生产条件判断其中哦~

/*生成生产代码的时候才触发*/
if (process.env.NODE_ENV === 'production') {
    module.exports.plugins = (module.exports.plugins || []).concat([
        new webpack.DefinePlugin({
            'process.env': {
            NODE_ENV: '"production"'
            }
        }),
        //抽取从node_modules引入的模块,如vue
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vender',
            minChunks:function(module,count){
                var sPath = module.resource;
                // console.log(sPath,count);
                //匹配 node_modules文件目录
                return sPath &&
                    /\.js$/.test(sPath) &&
                    sPath.indexOf(
                        path.join(__dirname, 'node_modules')
                    ) === 0
            }
        })
    ])
  }

即时是中文文档上之介绍
commons-chunk-plugin

立即是一个热心人总结的各种配置情况下于包的结果
https://segmentfault.com/a/1190000006808865

另插件

源码映射

为重构和减少后底代码不便利debug,所以我们先行要开启source
map功能,在webpack配置中上加相同件devtool,如下

module.exports = {
    //entry: ...
    devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
    module.exports.devtool = '#source-map'
}

eval-source-map凡是支付条件从而之源码映射,source-map凡转变环境从而的源码映射

官方对
devtool的介绍于此处

阮一峰先生对 source
map
的牵线以此

js代码压缩

css文件在
build(抽取和装)的以就拓展了简便的减,所以下面要是指向js代码的滑坡,也就是常事的UglifyJs(丑化js),webpack自带了UglifyJsPlugin插件,在plugins上启用就实施。

new webpack.optimize.UglifyJsPlugin({
    sourceMap: true,//开启源码映射
    compress: {
        warnings: false//去到警告
    }
}),

而上述之用法是webpack1.0遗留下来的,用的本来本子的UglifyJs,他的运用说明为于wepack1.0底文档里。你可出手动安装uglifyjs-webpack-plugin,引入最新的UglifyJs

/* npm install -save-dev uglifyjs-webpack-plugin */

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

new UglifyJsPlugin({
  uglifyOptions: {
    compress: {
      warnings: false
    }
  },
  sourceMap: true
})

webpack3.0汉语文档对拖欠插件的说明
在这里

法定文档的介绍
在这里

webpack1.0搬迁插件

loader-options-plugin 和外插件不同。它的用是支援人们从 webpack 1
搬迁到 webpack
2。官说明

new webpack.LoaderOptionsPlugin({
    minimize: true
}),

运作构建试一下

哼了至目前为止大部分会用到的插件都引入到了webpack配置中,构建一下碰。

完webpack.config.js的代码在此
https://pan.baidu.com/s/1jKnDSYa

npm run dev

dev

npm run build

image

发现uglifyJs报错,是为咱们从未安排babel的翻译器和编译规则,篇幅有限babel的配置说明放到下同样冀。

化解方式:在绝望目录下创造文件.babelrc,内容如下

{
  "presets": [
    ["env", {
       "modules": false 
    }]
  ]
}

安装babel-preset-env,npm install --save-dev babel-preset-env

下一场再build,没问题了

image

包裹后底目录结构如下

image

磨牙几句

怀念要深切摸底每个插件的现实性用法,定制自己之需求必然要是多触及去参考文档和资料。为了便利大家自己就当科目被列一个插件的脚给了汪洋的链接,可以说省去了豪门百度的日子,突然感觉到自己吓密切。

合法文档也不需要总体且看,用到啊看什么,要什么效果布局就至关重要看那片就好,等到有工夫另行简单的了同样不折不扣文档。

下期预告

交目前为止,整个工程得以说完全可用了。样式抽离,公共提取,压缩都为此到了,对比一下vue init webpack-simple project-name构建的简便工程,会发现我们比较其的意义还完好,有没发出一些成就感吧?

万分惋惜,没悟出讲插件用了这般长之篇幅,还是无涉及postcss和babel的布局,下一样盼望起简要提一下这些,然后我们后续优化构建过程,让他可以适应多入口多页面的开支。想要了解下的情节可以关心哦~~

!!!文章首发地址

参考

  • 详解webpack
    多页面/入口支持&公共组件单独包装

  • 详解webpack
    如何拼第三方js库

  • http://www.css88.com/doc/webpack2/plugins/commons-chunk-plugin/

  • https://segmentfault.com/a/1190000006808865

  • https://segmentfault.com/a/1190000007294861

相关文章

网站地图xml地图