完整示例
可查看对应的例子,npm start
运行。
执行
npm init -y //快速创建package.json
npm i webpack -g
npm i webpack -D//不装有时会有问题
值得一提的是现在webpack2+支持ES6的module了。
npm install --save-dev css-loader style-loader//用于加载css文件
npm install --save-dev file-loader//用于加载图片与字体文件
//npm install --save-dev csv-loader xml-loader //不太用的上
entry可以引入几个不同的文件,output里的finename的[name],就代表的在entry里定义的文件的名称。输出后会生成不同的打包文件。
安装html-webpack-plugin
插件可以帮助我们自动生成html模板,模板里会自动将生成的多个bundle加入html中。
npm install --save-dev html-webpack-plugin
如果希望每次打包前将dist文件自动清空可以安装这个插件。
npm install clean-webpack-plugin --save-dev
不同的devtool
配置可以开启不同的source maps
便于你查看源代码,有不同的类型。其中eval
是最快的,但是打包时不会根据sourceMapFilename
生成map文件。
每次要编译代码都手动运行显得很麻烦。 Webpack有几个不同的方式更改代码时自动编译代码:
webpack's Watch Mode
webpack-dev-server //相当于一个本地服务+webpack-dev-middleware
//webpack-dev-middleware
在script里加入
"watch": "webpack --watch"
缺点是需要手动刷新浏览器.
相当于启了一个本地服务(socket)在上面热更新,默认http://localhost:8080/
,一般开发时推荐用这个。
npm install --save-dev webpack-dev-server
HMR不适用于生产。随附webpack,通过配置启用hmr。 module.hot只有module.hot.accept监听的相应文件变化了才会触发。 相比webpack-dev-server,他在html模板加载文件的顺序是按照entry的顺序。
// webpack.config.js
const webpack = require('webpack');
module.exports = {
/*...*/
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devServer: {
hot: true ,
contentBase: path.resolve(__dirname, 'dist'),
publicPath: '/'
}
};
直接执行进行生产方式打包。
webpack -p
或等效
webpack --optimize-minimize --define process.env.NODE_ENV="'production'"
--optimize-minimize
相当于开启了UglifyJsPlugin。
UglifyJs是给生产环境用的,他无法直接识别ES6+的语法。
// webpack.config.js
const webpack = require('webpack');
module.exports = {
/*...*/
plugins:[
new webpack.optimize.UglifyJsPlugin({
sourceMap: options.devtool && (options.devtool.indexOf("sourcemap") >= 0 || options.devtool.indexOf("source-map") >= 0)
})
]
};
--define process.env.NODE_ENV="'production'"
相当于开启了DefinePlugin。
plugins:[
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
创建两个webpack.config文件,一个webpack.dev.js
,开发用,一个webpack.prod.js
生产用。
根据env
参数的不同调用不同配置。
"scripts": {
"dev": "webpack-dev-server --env=dev --open",
"prod": "webpack --env=prod --progress --profile --colors",
}
也可以用cross-env
,但是读的是process.env.NODE_ENV
。
"scripts": {
"dev": "cross-env NODE_ENV=dev webpack-dev-server --open",
"prod": "cross-env NODE_ENV=prod webpack --progress --profile --colors"
}
用webpack-merge
合并公共的webpack配置文件,个人感觉webpack-merge
不是必须的,可以按照手动的方式,然后提取公共的思路自己创建一种手动高级方式!(听着就觉得很高级)
一般有三种代码分割的方法:
Entry Points: 使用entry配置手动拆分代码。
Prevent Duplication: 使用CommonsChunkPlugin重复数据删除和拆分块。
Dynamic Imports: 通过模块内部函数调用分割代码。
在前面的代码里我们可以看到,entry不同的文件将会生成不同的bundle。 缺点是不同模块引入的相同模块会被重复打包进bundle里。
为了弥补入口点的问题,使用CommonsChunkPlugin
提取公共模块单独打包。
利用import实现动态加载和懒加载。这里不多介绍。
可以给所有打包出来的budle加上[hash]名,使文件能不被缓存。 但是坏处是一个文件改动会让所有bundle都变化hash名。 可以使用[chunkhash]给每个bundle hash。
html中引入的外部文件,可以通过设置externals,在文件中引入。 在文件目录较深时,可以通过设置alias,在文件中直接引入别名文件。 使用extensions可以设置直接省略的后缀。
安装grunt-webpack可以在grunt中执行webpack。
npm i webpack grunt-webpack --save-dev
安装webpack-stream可以在gulp中执行webpack。
npm i webpack-stream -D
暂时也只能打包js,webpack的plugins也都会报错,css打包也不成功。 没有详细的文档与demo,暂时不愿意踩这个坑,作了解即可。
安装react
npm i react react-dom -S
为了打包react与es6语法,需要安装babel 注意babel-cli的版本同步问题
npm i babel-cli -g
npm i babel-cli -D
npm i babel-loader -D
npm i babel-preset-env babel-preset-react -D
.babelrc文件配置
{
"presets": [
"env",
"react"
]
}