前面学习了在项目中使用webpack对各种类型的文件进行处理和打包,但是在开发过程中,不停的build并不友好,我们需要区分正式环境和开发环境。使用webpack-dev-server可以提升开发过程中体验和效率。但不同平台下,如mac和windows,对环境变量的处理方式是不同的,所以需要安装使用cross-env。在package.json中进行配置:
'script':{
'build': 'cross-env NODE_ENV=production webpack --config webpack.config.js', //用于正式环境
'dev': 'cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js' //用于开发环境
}
webpack.config.js同时运用于正式环境和开放环境,所以要根据不同的环境进行配置:
const path = require('path');
const HTMLPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const idDev = process.env.NODE_ENV === 'development'; //判断是否为开发环境
const config = {
target: 'web',
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: isDev ? '"development"' : '"production"' //使用vue或react等时需要增加此配置,用于区分不同环境下的打包方式
}
}),
new HTMLPlugin()
],
... //其他配置项在《使用webpack打包你的项目》和《使用webpack处理项目中的资源文件》中写过,此处省略
},
if(isDev) {
config.devtool = '#cheap-module-eval-source-map' //用于映射编译后的代码,帮助在页面中调试代码,因为使用vue开发项目时浏览器中显示的代码是经过编译的,不方便调试
config.devServer = {
port: 8000,
host: '0.0.0.0', //可以通过localhosh和内网ip访问
overlay: {
errors: true, //在编译过程中如果有错误,都显示在网页上
},
open: true, //在运行完npm run dev后,在浏览器中自动打开页面
hot: true, //更改代码后只重新渲染更改的内容,不会重新加载整个页面
}
config.plugins.push(
new webpack.HotModuleReplacementPlugin(); //用于配合hot使用
new webpack.NoEmitOnErrorsPlugin(); //用于去掉不必要的信息展示
)
}
module.exports = config
这样便可以在开发时,根据自己的开发习惯打包项目,大大提升开发体验。但这样的配置打包后还存在一个问题,所有的代码,包括样式代码,同时打包到了一个js文件中,代码非常多,影响效率,也不便于缓存。我们希望能把css单独打包成一个css文件,这时需要使用extract-text-webpack-plugin:
const ExtractPlugin = require('extract-text-webpack-plugin'; //把非js代码打包成单独的静态资源文件
...
if(isDev){
config.module.rules.push({
test: /\.styl/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
}
'stylus-loader'
]
})
...
} else {
config.output.filename = '[name].[chunkhash:8].js'; //在开发环境中使用chunkhash会报错
config.module.rules.push(
{
test: /\.styl/,
use: ExtractPlugin.extract({
fallback: 'style-loader',
use:[
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
}
'stylus-loader'
]
})
},
)
config.plugins.push(
new ExtractPlugin('styles.[contentHash:8].css')
)
}
除了要对css单独打包,我们还希望对类库文件单独打包,因为类库文件非常稳定,不必和业务代码在一起频繁打包。正式环境中设置如下:
config.entry = {
app: path.join(__dirname, 'src/index.js'),
vendor: ['vue', 'vue-router'] //对vue和vue-router单独打包
}
config.plugins.push(
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor' //name名称和entry中设置的key值相同,否则无法识别
)}
new webpack.optimize.CommonsChunkPlugin({
name: 'runtime' //把webpack相关的代码单独打包到一个文件中,目的是增加模块时chunkhash不变,可以实现长缓存。必须放到vendor后面。
})
}