参考 webpack教程、create-react-app(eject后)配置,自定义一个适合的、可维护的webpack配置
1. 自动清理 /dist 文件夹
设置缓存配置后,内容变更后的每次构建都会生成新的文件。但是 webpack 无法追踪到哪些文件是实际在项目中用到的。然后,需要在每次构建前清理 /dist 文件夹。使用插件可以自动完成。
1.1 安装依赖
yarn add clean-webpack-plugin -D
1.2 修改 webpack.prod.js 文件
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.base.js");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = merge(baseConfig, {
mode: "production",
plugins: [new CleanWebpackPlugin(), new OptimizeCssAssetsPlugin()],
});
1.3 重新构建会清空 /dist 目录后,重新生成文件夹
2. 配置 source map
当 webpack 打包源代码时,会很难追踪到错误和警告在源代码中的原始位置。例如,如果将三个源文件(a.js, b.js 和 c.js)打包到一个 bundle(bundle.js)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会简单地指向到 bundle.js。
为了更容易地追踪错误和警告,JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。
development 模式默认开启,production 模式默认关闭。
2.1 development 模式查看效果
2.1.1 编辑 App.jsx 文件 ,添加代码
componentDidMount() {
console1.log("my-webpack-config");
}
2.1.2 保存代码,自动构建,得到报错,可以明确看出错误来源
App.jsx:47
Uncaught ReferenceError: console1 is not defined
at App.componentDidMount (App.jsx:47)
at commitLifeCycles (react-dom.development.js:19814)
at commitLayoutEffects (react-dom.development.js:22803)
at HTMLUnknownElement.callCallback (react-dom.development.js:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
at invokeGuardedCallback (react-dom.development.js:292)
at commitRootImpl (react-dom.development.js:22541)
at unstable_runWithPriority (scheduler.development.js:653)
at runWithPriority$1 (react-dom.development.js:11039)
at commitRoot (react-dom.development.js:22381)
2.1.3 编辑 webpack.dev.js 文件
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.base.js");
module.exports = merge(baseConfig, {
mode: "development",
devtool: "none",
});
2.1.4 保存代码,自动构建,得到报错,无法看出错误来源
main.094c8773.js:38388 Uncaught ReferenceError: console1 is not defined
at App.componentDidMount (main.094c8773.js:38388)
at commitLifeCycles (main.094c8773.js:22273)
at commitLayoutEffects (main.094c8773.js:25262)
at HTMLUnknownElement.callCallback (main.094c8773.js:2647)
at Object.invokeGuardedCallbackDev (main.094c8773.js:2696)
at invokeGuardedCallback (main.094c8773.js:2751)
at commitRootImpl (main.094c8773.js:25000)
at unstable_runWithPriority (main.094c8773.js:30483)
at runWithPriority$1 (main.094c8773.js:13498)
at commitRoot (main.094c8773.js:24840)
2.2 分别配置
2.2.1 webpack.dev.js
devtool: "eval-source-map",
2.2.2 webpack.prod.js
devtool:"source-map",
2.3 重新构建,得到报错,都可以明确看出错误来源
<!-- development -->
App.jsx?1591:6
Uncaught ReferenceError: console1 is not defined
at App.componentDidMount (App.jsx?1591:6)
at commitLifeCycles (react-dom.development.js?61bb:19814)
at commitLayoutEffects (react-dom.development.js?61bb:22803)
at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:237)
at invokeGuardedCallback (react-dom.development.js?61bb:292)
at commitRootImpl (react-dom.development.js?61bb:22541)
at unstable_runWithPriority (scheduler.development.js?3069:653)
at runWithPriority$1 (react-dom.development.js?61bb:11039)
at commitRoot (react-dom.development.js?61bb:22381)
react-dom.development.js?61bb:19527
The above error occurred in the <App> component:
in App
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
react-dom.development.js?61bb:11102
Uncaught ReferenceError: console1 is not defined
at App.componentDidMount (App.jsx?1591:6)
at commitLifeCycles (react-dom.development.js?61bb:19814)
at commitLayoutEffects (react-dom.development.js?61bb:22803)
at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:237)
at invokeGuardedCallback (react-dom.development.js?61bb:292)
at commitRootImpl (react-dom.development.js?61bb:22541)
at unstable_runWithPriority (scheduler.development.js?3069:653)
at runWithPriority$1 (react-dom.development.js?61bb:11039)
at commitRoot (react-dom.development.js?61bb:22381)
react-dom.production.min.js:209
ReferenceError: console1 is not defined
at a.value (App.jsx:6)
at lo (react-dom.production.min.js:212)
at pu (react-dom.production.min.js:255)
at t.unstable_runWithPriority (scheduler.production.min.js:19)
at Wl (react-dom.production.min.js:122)
at du (react-dom.production.min.js:248)
at $o (react-dom.production.min.js:239)
at Uo (react-dom.production.min.js:230)
at Du (react-dom.production.min.js:281)
at react-dom.production.min.js:284
App.jsx:6
Uncaught ReferenceError: console1 is not defined
at a.value (App.jsx:6)
at lo (react-dom.production.min.js:212)
at pu (react-dom.production.min.js:255)
at t.unstable_runWithPriority (scheduler.production.min.js:19)
at Wl (react-dom.production.min.js:122)
at du (react-dom.production.min.js:248)
at $o (react-dom.production.min.js:239)
at Uo (react-dom.production.min.js:230)
at Du (react-dom.production.min.js:281)
at react-dom.production.min.js:284
3. 自动压缩图片
3.1 安装依赖
yarn add imagemin-webpack-plugin -D
3.2 编辑 webpack.prod.js
开发环境不需要压缩
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.base.js");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
module.exports = merge(baseConfig, {
mode: "production",
devtool: "source-map",
plugins: [
new CleanWebpackPlugin(),
new OptimizeCssAssetsPlugin(),
//Make sure that the plugin is after any plugins that add images
new ImageminPlugin({
pngquant: {
quality: "95-100",
},
}),
],
});
3.3 重新构建,查看生成的图片大小
//前
big.png 4.4M
//后
big.efb37eb0.png 3.8M
4. 自动补全 CSS 前缀
4.1 安装依赖
yarn add postcss-loader autoprefixer -D
4.2 编辑 webpack.base.js
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: { publicPath: "../../" },
},
"css-loader",
// Use it after css-loader and style-loader, but before other preprocessor loaders like e.g sass|less|stylus-loader, if you use any.
{
loader: "postcss-loader",
options: {
plugins: [require("autoprefixer")],
},
},
],
},
4.3 添加 .browserslistrc 文件
<!-- 参考 create-react-app -->
# Browsers that we support
> 1%,
last 2 versions
4.4 编辑 index.css 文件
.color {
color: rebeccapurple;
display: flex;
box-sizing: border-box;
}
@font-face {
font-family: myFirstFont;
src: url("./font/font.ttf");
}
.font {
font-family: myFirstFont;
}
4.5 重新构建获取重启 dev-server 可以看到补全的 CSS
<!-- main.ad7a61d4.css 格式化效果 -->
.color {
color: #639;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
@font-face {
font-family: myFirstFont;
src: url(../../static/media/font.d55bf3f0.ttf);
}
.font {
font-family: myFirstFont;
}
5. 统计构建耗时
添加 loader、plugin 之后,build 执行时间变得很长,但是不知道各自耗时。
5.1 安装插件
yarn add -D speed-measure-webpack-plugin
5.2 编辑 webpack.prod.js
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.base.js");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap(
merge(baseConfig, {
mode: "production",
devtool: "source-map",
plugins: [
new CleanWebpackPlugin(),
new OptimizeCssAssetsPlugin(),
//Make sure that the plugin is after any plugins that add images
new ImageminPlugin({
pngquant: {
quality: "95-100",
},
}),
],
})
);
5.3 重新构建
SMP ⏱
General output time took 25.79 secs
SMP ⏱ Plugins
ImageminPlugin took 21.42 secs
OptimizeCssAssetsWebpackPlugin took 0.756 secs
HtmlWebpackPlugin took 0.128 secs
CleanWebpackPlugin took 0.021 secs
MiniCssExtractPlugin took 0 secs
SMP ⏱ Loaders
babel-loader took 1.033 secs
module count = 2
html-webpack-plugin took 0.72 secs
module count = 1
mini-css-extract-plugin, and
css-loader, and
postcss-loader took 0.616 secs
module count = 1
url-loader took 0.565 secs
module count = 2
modules with no loaders took 0.546 secs
module count = 9
css-loader, and
postcss-loader took 0.441 secs
module count = 1
file-loader took 0.012 secs
module count = 1
代码仓库
参考链接