1关于out.publicPath和out.path
开发环境:out.path无效,out.publicPath就是在内存中生成的压缩文件在本地服务下的访问目录(包括build.js和静态资源引用)会影响html引用资源的路径,在这里需要区别与devServer.publicPath。
假设:
a代表devServer.publicPath
b代表out.publicPath
二者的关联:
当设置a不为false时,本地服务的访问路径会通过它访问内存中生成的压缩文件,如devServer.publicPath为test,则访问路径就是localhost:port/test。
当设置a为false时,本地服务的访问路径会通过b访问内存中生成的压缩文件。
b同时又是最后在html中引用资源代码时访问资源的前缀。
生产环境:out.publicPath是html静态资源引用的路径前缀(静态资源和html的位置关系在打包的时候会根据out.path和filename/chunkFilename确定)
2关于devServer
devServer.contenbase:指的是硬盘中的一个文件目录,当webpack服务生成的内存资源中找不到对应资源时会去这里找.
模块热加载hot需加载热加载插件如下:
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
3关于devtool
有四种类型,如果设置了会生成.map文件,内容是关联源文件的关系,方便调试。
4关于环境判断process.env.NODE_ENV的理解
package.json中的脚本命令用于webpack.config.js中process.env.NODE_ENV的判断,以下代码则是用于项目中其他模块中的环境判断定义:
if(process.env.NODE_ENV === 'production'){
config.devtool = '';
config.plugins = [
new webpack.optimize.UglifyJsPlugin(),
new webpack.BannerPlugin('xx模块'),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
})
];
}
5在scripts中定义环境变量(webpack4之前)
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open",
"build": "cross-env NODE_ENV=production webpack -w --progress --hide-modules"
},
cross-env用以设置环境变量,可以兼容不同平台,需要先安装模块npm install cross-env --save-dev,process.env.NODE_ENV用以判断环境变量
-w(—watch) 实时监控,-p(—progress)显示打包进度,—hide-modules隐藏模块信息
6关于url-loader和file-loader
超过url-loader的limit参数的文件将被打包到一个新的文件夹里,此时需要file-loader
7new webpack.optimize.UglifyJsPlugin()
压缩文件插件,使用此插件需要配置.babelrc文件,否则打包过程会包无法识别es6的错且无法压缩js文件,.babelrc做如下配置:
{
"presets": [
["env", { "modules": false }]
]
}
8关于.babelrc文件
这里统一配置babel,webpack会自动调用
9 关于CommonsChunkPlugin(适用于webpack4之前)
webpack首先根据入口和出口进行打包,如app.js。
而CommonsChunkPlugin用于提取其中的公共模块的,
首先提取被引用的node_modules中的公共第三方模块(这部分不经常变动,可以利用缓存来加快载入速度),打包后的名称为:[name].[chunkhash].js,如:vendor.08sejlehofod.js。
接下来,最后一个chunk,manifest则是在vendor的基础上,再抽取出要经常变动的部分,比如关于异步加载js模块部分的内容,被注入了webpackJsonp的定义及异步加载相关的定义(webpack调用CommonsChunkPlugin处理后模块管理的核心,因为是核心,所以要第一个进行加载,不然会报错)
。这样每次编译以后,只要不引入新的第三方模块,上面vendor的chunkhash保持不变,从而不改变这部分的缓存。
最后,将app中引入三次以上的组件单独打包成名为:vendor-async的包,是个异步加载的包。
10.关于css-loader和style-loader
webpack只认识模块,css文件不是模块,需要通过css-loader转成模块,style-loader可以将模块转成style标签插入到html只能够
单独抽离css文件
利用ExtractTextPlgin,分两步:1.首先在plugin中使用2.将css-loader用ExtractTextPlgin.extract({option})改造
注意:抽离后原来css中的引用img的url路径会出现问题,可以利用option.publicPath重写。
举个栗子:
假如原来在html中的style标签中的css样式引用路径为./static/img/xx.png,则抽离以后的文件会放到./static/css/下面,这是要应用img就去要使用路径../../static/img/xx.png,因此,假设我们设置的out.PublicPath是./,则option.publicPath就是../../
11《深入浅出webpack》学习笔记:
Loader
1.每一个 Loader 都可以通过 URL querystring 的方式传入参数,例如 css-loader?minimize 中的 minimize 告诉 css-loader 要开启 CSS 压缩。(这种方式会报错)
2.给 Loader 传入属性的方式除了有 querystring 外,还可以通过 Object 传入。
3.除了在 webpack.config.js 配置文件中配置 Loader 外,还可以在源码中指定用什么 Loader 去处理文件。 以加载 CSS 文件为例,修改上面例子中的 main.js 如下:
require('style-loader!css-loader?minimize!./main.css');
Webpack-dev-server
4.DevServer不会理会 webpack.config.js 里配置的 output.path 属性
Plugin
CommonsChunkPlugin
为了把基础运行库从 common 中抽离到 base 中去,还需要做一些处理。
首先需要先配置一个 Chunk,这个 Chunk 中只依赖所有页面都依赖的基础库以及所有页面都使用的样式,为此需要在项目中写一个文件 base.js 来描述 base Chunk 所依赖的模块,里面引入基础模块。
// 所有页面都依赖的基础库
import 'react';
import 'react-dom';
Import 'Vue;
……
// 所有页面都使用的样式
import './base.css';
……
接着再修改 Webpack 配置,在 entry 中加入 base,相关修改如下:
module.exports = {
entry: {
base: './base.js'
},
};
最后以上就完成了对新 Chunk base 的配置。
为了从 common 中提取出 base 也包含的部分,还需要配置一个 CommonsChunkPlugin,相关代码如下:
new CommonsChunkPlugin({
// 从 common 和 base 两个现成的 Chunk 中提取公共的部分
chunks: ['common', 'base'],
// 把公共的部分放到 base 中
name: 'base'
})
由于 common 和 base 公共的部分就是 base 目前已经包含的部分,所以这样配置后 common 将会变小,而 base 将保持不变。
从vue-cli2配置的vendor.js中再次分离体积较大的模块
比如:我想把vue从vendor.js中单独分离出来,做如下配置
下面的配置可以把vue从vendor.js中分离出来,但是包很大,不如script引入vue.min.js
new webpack.optimize.CommonsChunkPlugin({
name: 'vue',
chunks:['vendor'],
minChunks (module) {
return module.resource && module.resource.indexOf('vue.esm.js') !== -1;
}
})