前言

高达同一可望于零构建了一个基础版的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地图