优化
JS 压缩大师
terse 就是简洁的意思,顾名思义,Terser 的作用就是将代码变得更加简洁,从而使得代码更适合放在浏览器(互联网)中展示(另外一个打包库,browserify 名字就来源于此)。
Terser 用于压缩代码体积,通常用于生产(也只有生产有这个需求)。
测试下来,mode 为 production 的时候,使用 Terser 时打包产物体积为 352 字节,不使用时体积为 423 字节。
虽然看起来产物的字符都一样,但 Terser 能够对一些不可见的空白字符、换行符、评论、组织分隔符进行删减。从而减小产物体积。
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
entry: "./index.js",
mode: "production",
output: {
filename: "output.js",
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
mangle: {
// Find work around for Safari 10+
safari10: true,
},
},
// Use multi-process parallel running to improve the build speed
parallel: true,
}),
],
},
};
CSS 压缩大师
CSS 文件保存了各种样式,而 CssMinimizer 这个插件的作用就是能够将 CSS 按内容进行合并同类项,把产物体积缩到最小。
module.exports = {
/* ... */
optimization: {
minimize: true,
minimizer: [
new CssMinimizerPlugin(),
]
}
/* ... */
}
副作用插件
这里包含一些能助你如虎添翼的插件,方便开发、生产的流程。
创建 HTML 不再麻烦
网页通常都使用 HTML 作为骨架,但是现今各种前端框架盛行,我们可以方便地编写模板代码,最后才将这些结构体转为真正的 DOM 注入到这个 HTML 文件中。
实际上我们直接使用到 HTML 的场景已经大幅减少,而为了提供网页入口,我们每次都需要在 dist/中手动新建一个 index.html 文件,很繁琐。
而 HtmlWebpackPlugin 能够每次打包都在输出目录 dist/ 创建一个 HTML 文件,并且会包含一个引入输出打包产物的 <script>标签,打包产物的 hash 也会自动更新。
module.exports = {
/* ... */
plugins: [new HtmlWebpackPlugin()],
/* ... */
}
使用环境变量不再麻烦
只需要在 webpack.config.js中提前定义好一些变量,即可以在应用中所有 JS 文件中使用这些全局变量。
其实就是在编译时进行字符串的替换。
module.exports = {
/* ... */
plugins: [new webpack.DefinePlugin({
NODE_ENV: process.env.NODE_ENV || 'development',
PUBLIC_URL: 'path/to/public/dir'
)],
/* ... */
}
为每一个 JS 文件生成一个 CSS
在写 React 应用的时候,通常都会将组件放在同一个文件夹内管理。但是打包后,所有组件的样式文件都放到同一个地方,可能会造成重名困扰。
而使用了 MiniCssExtractPlugin 插件能够很好地解决这个问题,将样式保持出现在它应该出现的组件内。
此外还支持异步加载(渲染了才加载)、没有重复的编译(性能)、更容易使用(组件开发)。
module.exports = {
/* ... */
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
/* ... */
}
注意:MiniCssExtractPlugin 需要同时在 plugin 和 loader 中出现
模块
紧急尝鲜
通常一些比较新的 JS 语法(如 ES2015 的 结构赋值、模板字符串、spread 语法)未必支持在浏览器中运行,需要进行 polyfill (垫片)转换。而 babel 就是 polyfill 的专业团队,他们家出品了一个 babel-loader 专门用来方便我们这些想要尝新的弄潮儿。
原理就是先解析代码,转成 AST, 然后生成 ES5 的代码。
module.exports = {
/* ... */
rules: [
{
test: /.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
include: 'path/to/src/file',
loader: 'babel-loader',
}
]
};
还想尝尝 React
又想用新语法,又想玩 React,不用对打包工具操心,还不赶紧用 CRA 快速上手。
如果你不想使用 CRA,但是又想获得同样的体验,可以使用 babel-preset-react-app 这个预设。CRA 的专业团队的出品,必属精品。
你只要在 babel-loader 的基础上可选配置上如下设置,即可解锁和使用 CRA 一样的体验。
{
test: /.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
include: 'path/to/src/file',
loader: 'babel-loader',
options: {
presets: [
// Preset includes JSX, TypeScript, and some ESnext features
require.resolve('babel-preset-react-app'),
]
}
}
分析
比分看板
GitHub - FormidableLabs/webpack-dashboard: A CLI dashboard for webpack dev server
webpack 构建默认的打印输出的 log 有点丑,想要酷炫的终端数据看板,可以如下安装 webpack 看板:
yarn add -D webpack-dashboard
用的时候就像正常插件一样:
module.exports = {
/* ... */
plugins: [new webpackDashboard()],
/* ... */
}
有图有真相
当我们想要分析打包产物中各个库所占体积的大小,可以使用 Webpack-bundle-analyzer 进行分析,会很直观地看到各个模块在打包产物中的所占体积。
用法也很简单:
module.exports = {
/* ... */
plugins: [new BundleAnalyzerPlugin()]
/* ... */
}