一步步学Webpack4(2)-- 生产环境配置入门
我们在上一篇一步步学Webpack4(1)-- 开发环境搭建入门中使用Webpack完成了开发环境搭建的入门实战练习,这次我们来学习如何配置生产环境.
本章按照分离配置 - 减少打包体积 - 提供基本调试支持
的步骤进行:
1. 分离配置
1.1 分离配置原因 & 分离方式
当前项目中已经有一个 webpack.config.js
配置文件并且运行良好,但是这个配置只适用于开发环境, 开发环境和生产环境的项目构建目标不一样.
开发环境的构建目标是具备方便问题追溯的source-map & 修改保存代码之后的实时加载或者热模块更新,一切为方便开发服务; 生产环境的构建目标更多是通过生成更小的打包文件、更轻的source map、最优化的资源利用,最终实现加载时间的优化.为了在开发环境与生产环境都达到最优的效果,官方文档建议为环境编写独立的配置.
1.2 执行分离:
虽然说开发环境与生产环境将会被分离,但是他们还是一部分配置可以通用的. 依据DRY原则(Don‘t repeat yourself), 我们将保留一份通用配置,并借助 webpack-merge
在特定环境配置中调用通用配置.
步骤一、安装:webpack-merge
npm install --save-dev webpack-merge
- 步骤二、分离配置:
在项目根目录添加 webpack.commom.js
、webpack.dev.js
、webpack.prod.js
三个文件, 将webpack.config.js
拆解放入三个文件中,文件的完整代码如下所示:
webpack.commom.js
const path = require("path"); const CleanWebpackPlugin = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { app: './src/index.js' }, output: { filename: 'main.js', path: path.resolve(__dirname, 'dist') }, plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ inject: false, template: 'index.html', filename: 'index.html' }) ], module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.(png|svg|jpg|gif)$/, use: [ 'file-loader' ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ 'file-loader' ] }, { test: /\.xml$/, use: [ 'xml-loader' ] } ] } }
webpack.dev.js
const merge = require('webpack-merge'); const common = require('./webpack.common'); const webpack = require('webpack'); module.exports = merge( common, { devtool: 'inline-source-map', devServer: { contentBase: './dist', hot: true }, plugins: [ new webpack.HotModuleReplacementPlugin() ] });
webpack.prod.js
const merge = require('webpack-merge'); const common = require('webpack.common.js'); module.exports = merge(common, { // 暂无配置 });
- 步骤三、修改package.json 配置, 将脚本更新为运行对应环境的配置. 开始开发工作时,使用
npm start
运行webpack-dev-server; 开始打包准备发布时,运行npm build
运行webpack.
{ "name": "webpack-stepbystep", "version": "1.0.0", "description": "", "private": true, "scripts": { "start": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "clean-webpack-plugin": "^0.1.19", "css-loader": "^1.0.0", "csv-loader": "^3.0.2", "file-loader": "^2.0.0", "html-webpack-plugin": "^3.2.0", "style-loader": "^0.23.1", "webpack": "^4.23.0", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.10", "webpack-merge": "^4.1.4", "xml-loader": "^1.2.1" }, "dependencies": { "lodash": "^4.17.11" } }
虽然项目配置架构与脚本已经完成,但是生产环境的配置还是空白的.生产环境配置的需要实现的基本功能有:
- 减少打包文件体积
- 支持生产环境下基本调试功能
2. 生产环境配置--减少打包文件体积
2.1 添加模块
想要知道完成生产配置之后的效果,需要源文件不变,通过对比修改生产配置文件之后的结果来验证. 于是我们先为 print.js
添加一个 ”不被调用“ 的方法模块,看看最终有没有方法可以更好地优化代码.添加模块之后的完整代码如下所示:
print.js
export default function printMe () { console.log('Updating print.js'); } export function printTest () { console.log('Testing'); }
2.2 执行普通模式打包
为了接下来编译的时候代码不被压缩,所以暂时将webpack的配置改为 mode: 'development'
, 完整配置如下所示:
webpack.prod.js
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = merge(common, { mode: 'development' });
在终端输入 npm run build
,根据当前 webpack.prod.js
完成打包,结果如下所示:
虽然代码没有引用 printTest
模块,但是 mode: development
模式下的打包文件还是包含了该模块. 编译完的js打包文件 main.js
大小居然达到了575kb,引用了一个lodash库和一个printMe模块就半M了...
2.3 压缩打包代码
接着读官方文档Tree Shaking, 了解到一个叫做摇树(Tree Shaking)的概念,官方给出的理解方法是:
意思就是把应用当成一棵树,那些真正被调用的源代码和库是长在树上的绿色叶子,那些没有被调用的库和代码就是已经枯死的叶子,你可以通过摇晃这颗树把树上的枯叶摇下来,也就是说应用里没用到的代码和库可以通过“摇树”移除.
回想一下上次打包的结果,统一文件的未被调用模块代码也被打包到打包的js文件中,那么也就意味着loadsh库也是这样被打包的,那么我们现在要做的事情就是实现“摇树“,移除Webpack构建的依赖关系图中无用的代码和库.
官方文档的Tree Shaking和Production说得让人头大 (并且脱发) , 说了挺多摇树和生产环境的东西但是让人无从下手,直到我看到 Miniication
小节的这一句:
然后查了相关资料后我才发现,其实在Webpack4之后的Webpack已经自带压缩和“摇树”了,只要将 webpack.prod.js
的 mode: 'development'
改为 mode: 'production'
,完整代码如下所示:
webpack.prod.js
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = merge(common, { mode: 'production' });
打包完成之后的 main.js
只剩下77kb了,压缩了至少80%吧,并且里面已经移除了没有调用的模块,成功完成减少文件体积的需求:
3. 生产环境配置--基本调试支持
官方建议在生产环境开启source map,理由是对于调试以及应用评分有帮助. 配置起来也是十分简单, 只需要加入一行 devtool: 'source-map'
:
webpack.prod.js
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = merge(common, { mode: 'production', devtool: 'source-map' });
在看看打包结果,发现打包后原来所有文件大小不变,但是多出了一个700kb的map文件,做哦那个应该就是生产环境中映射源代码吧,生产环境对于基本调试的支持也成功实现了:
至此生产环境的基本配置已经全部完成
4. 项目地址
To be continued...
系列文章
- 一步步学Webpack4(0)-- 实战起步
- 一步步学Webpack4(1)-- 开发环境搭建入门