Webpack 文档中文版,强烈建议仔细认真阅读三遍!而且是从头到尾!
webpack 的功能和优势就不在累述,本篇文章使用的weboack 3。
背景
作为 React 初级开发者来说,React 全家桶实在是太多了!所以这里感谢dva 框架,让我从数据流里抽离出来,专心处理页面和逻辑问题。同时感谢roadhog 工具,让我只会写 React 组件时,也能顺利搭建项目。而且,顺利完成了人生中第一个 React 项目! roadhog 封装了 webpack,加上其完善的文档,使初学者能逃离 webpack 的折磨。但因一些特殊的需求,比如 dll 使用、减少打包时间、区分 dev 和 prod 的打包等,决定还是回到 webpack。
所以我现在区分三种不同环境:本地开发环境(roadhog),开发环境(webpack.dev.js)、生成环境(webpack.prod.js)。
Webpack
如果看完Webpack 文档中文版没有感觉,那就看看适合初学者的webpack 3 零基础入门教程。
基础篇
建议你再次去阅读webpack 的概念。 webpack 的四个核心概念:入口(entry)、输出(output)、解析器(loader)、插件(plugins)。从 entry 里 webpack 会自动去查找相关依赖,然后经过配置的 loader 规则,最后到 output,同时用 plugins 对前三个不同阶段进行扩展和定制。
体积篇
默认情况下,webpack 打包出来的 js 文件比较大,需要我们自己优化减少体积。如使用 CDN、抽离资源文件、独立第三方库为 DLL 等。
Dev 环境不建议对体积进行优化! 推荐Webpack 打包优化之体积篇。 我使用的是UglifyJsPlugin来压缩代码。
const os = require('os');
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
// ...
plugins: [
// webpack 3新特性,提升js执行速度,减少打包大小
new webpack.optimize.ModuleConcatenationPlugin(),
// 对打包文件进行压缩
new ParallelUglifyPlugin({
cacheDir: `${__dirname}/${distDir}/.cache/prod`,
workerCount: os.cpus().length,
uglifyES: {
output: {
comments: false
},
compress: {
warnings: false
},
},
}),
new BundleAnalyzerPlugin(),
],
复制代码
速度篇
webpack 打包进行优化时速度很慢,推荐Webpack 打包优化之速度篇。常用的方法比如抽离第三方库为 DLL 避免二次打包、减少文件搜索范围、利用下Happypack(即并发打包)。 我一般都是把所有方法都用上,还不晓得哪个效果最好,参考我后面列的 webpack 配置文件。
其他
webpack.prod.js 与 webpack.dev.js
如前面所说,项目标配环境至少是三种,加上 dll 打包和本地调试环境,可能需要配置更多 webpack 环境。如官方提到的环境构建,所以建议对 webpack 的配置,进行复用和分离。 查看我的 webpack.config.js 模板。
CommonsChunkPlugin 与 DllPlugin
CommonsChunkPlugin与DllPlugin,均是 webpack 的两个官方推荐插件,均是优化打包大小和抽离文件的功能,最开始我常常搞混他们的功能。
webpack 分离第三方库(CommonsChunkPlugin 并不是分离第三方库的好办法 DllPlugin 科学利用浏览器缓存)里面解释得比较清楚。CommonsChunkPlugin 是用来多页应用时,把共用的、自己写的库抽离出来,组成 common 组件,每次都会重新打包。DllPlugin 是抽离第三方库组件(即不是自己写的),当然也可能是多页面应用中一个或多个页面用到,不会每次都重新打包。
所以,CommonsChunkPlugin 是针对自己封装的库,DllPlugin 是针对第三方库,他们都是用来提高代码的复用。如果是仅有一个页面应用,用不用 CommonsChunkPlugin 都无所谓,毕竟每次都要重新打包。 其他资料:教你如何玩转 webpack.DllPlugin。
DllPlugin 遇到的问题
1、Reference Error: React is not defined
把 react 放在 dll.js 之后,app.js 找不到 react 了,而代码里import React from 'react';
。原因是 app.js 找不到 React 的定义为空,所以需要在 webpack 里加上ProvidePlugin
new webpack.ProvidePlugin({
"React": "react",
}),
复制代码
2、dll.js 如何被引用到 index.html 里
在教你如何玩转 webpack.DllPlugin里有提到通过add-asset-html-webpack-plugin或html-webpack-include-assets-plugin解决,但是当 dll.js 输出带 hash 值,重新打包 dll.js 之后,又会回到本问题的本身,即要通过 hash 值解决缓存问题。 下面是通过html-webpack-plugin解决,分别是 index.js 和 webpack 配置:
// index.ejs
<script src="<%= htmlWebpackPlugin.options.vendor %>"></script>
复制代码
// webpack配置
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 生成入口html。vendor是自定义变量,可替换index.ejs中预设的宏(功能很强大!)
new HtmlWebpackPlugin({
filename: 'index.html',
template: `${__dirname}/src/index.ejs`,
vendor: `${cdnUrl}/${vendorName}`,
// hash: true,
}),
复制代码
Babel
用 react 和 webpack 必然离不开 babel,它是普及 es6 的中坚力量!当然,推荐babel-preset-env 升级迁移完全指北,写得很完美!
不过我还是遇到不能解析[...array]和[...json]的错误,需要npm i -D babel-preset-stage-0
,再在 presets 添加stage-0
。
后记
我本身是 iOS 开发的,然后跟到打杂用了 2 个月 React 开发一个项目。但是到新公司之后,基本就变成 React 工程师,用了 1 天 1 晚加半天学会 webpack 之后感觉 webpack 真是牛逼!学它的过程,最开始因为觉得官方文档晦涩难懂,就抛弃官方文档而转向其他资料,但是最终又回到官方文档,这过程中走了不少弯路。很多资料都是片面而且内容很浅显的,当然也包括本篇文章,所以你等会还是回去看官方文档吧!
所以这里小记自己,以后学习先找个入门教程,然后看官方文档,不懂的再搜索其他资料!