本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
作为一名前端开发,我们通常会用像 Webpack 这样的构建工具来打包我们的代码。Webpack 功能强大,提供了所有必要的特性。但是,如果有一个替代品能够执行类似的工作,但构建时间更快呢?
最近,我花了一些时间阅读 Rspack 的官方文档。它的低设置成本、对 Webpack 用户的用户友好界面以及更快的构建时间都非常吸引我。
利用一个相对空闲的工作期,我将 Rspack 应用到我们公司的项目中,结果相当令人印象深刻。在这篇文章中,我想分享我们项目的前端架构,并比较 Rspack 和 Webpack 之间的构建速度,希望这篇文章对某人有所帮助。
太长不看(TL;DR):如果你正在使用带有自定义配置的 Webpack,你应该尝试用 Rspack 替换它,这会节省你大量的等待时间。
我的工作项目的 Webpack 配置
在我们比较 Rspack 和 Webpack 之间的性能之前,让我先展示一下我们如何配置 Webpack 来构建 CSS 和 JavaScript 文件。
这是我们项目的 webpack.config.js:
const path = require("path");const glob = require("glob");const toObject = require("./scripts/toObject");const { VueLoaderPlugin } = require("vue-loader");const MiniCssExtractPlugin = require("mini-css-extract-plugin");const { CleanWebpackPlugin } = require("clean-webpack-plugin");const FixStyleOnlyEntriesPlugin = require("webpack-fix-style-only-entries");module.exports = (env, options) => { const jsSetting = { mode: "production", entry: { index: path.resolve(__dirname, "src/js/entry/index.js"), }, output: { path: path.resolve(__dirname, "apps/statics/dist/"), filename: "js/[name].js", }, target: ["web", "es5"], module: { rules: [ { test: /.m?js$/, include: path.resolve(__dirname, "src"), exclude: /(node_modules|bower_components)/, use: [ { loader: "babel-loader", options: { plugins: ["@babel/plugin-transform-runtime"], }, }, ], }, { test: /.vue$/, use: ["vue-loader"], }, { test: /.s?css$/i, use: ["vue-style-loader", "css-loader", "sass-loader"], }, { test: /\.(png|jpe?g|gif|svg)$/i, use: [ { loader: "url-loader", options: { name: "[path][name].[ext]", context: "src", fallback: require.resolve("file-loader"), limit: 8192, }, }, ], }, { test: /\.(woff|woff2|eot|ttf|otf|)$/, use: [ { loader: "file-loader", options: { name: "[path][name].[ext]", context: "src", }, }, ], }, ], }, plugins: [ new VueLoaderPlugin(), new MiniCssExtractPlugin({ filename: "style/[name].css", }), new CleanWebpackPlugin({ verbose: true }), ], resolve: { alias: { src: path.resolve(__dirname, "src/"), apps: path.resolve(__dirname, "apps/"), }, }, externals: { vue: "Vue", axios: "axios", jquery: "jQuery", }, }, const cssSetting = { mode: "production", entry: { ...toObject(glob.sync("apps/statics/scss/*/.scss")), }, output: { path: path.resolve(__dirname, ""), }, module: { rules: [ { test: /.s?css$/i, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader", options: { url: false }, }, "postcss-loader", { loader: "sass-loader", options: { implementation: require("sass"), sassOptions: { outputStyle: "expanded", }, }, }, ], }, ], }, plugins: [new FixStyleOnlyEntriesPlugin(), new MiniCssExtractPlugin({})], resolve: { alias: { src: path.resolve(__dirname, "src/"), apps: path.resolve(__dirname, "apps/"), }, }, }, if (options.mode == "development") { jsSetting.devtool = "eval-source-map"; } return [cssSetting, jsSetting];};为了简化内容,我已经移除了大部分的 entry 文件,并仅保留了说明所需的必要部分。
在我们的项目中,我们首先构建 CSS,然后是 JavaScript。对于 css 文件,我们使用了一个名为 glob 的库来检测所有的. scss 文件。toObject 是一个自定义函数,用于生成如下的键值对:
{ "apps/statics/scss/index": "apps/statics/scss/index.scss", // ...}所以基本上,这些就是我们项目所需的内容:
构建 Vue SFC 文件
从 SCSS 文件构建 CSS 文件
构建 JavaScript 文件
让我们看看我们如何配置 Rspack 设置。
我的 Rspack 设置
这是我的 rspack.config.js:
const path = require("path");const glob = require("glob");const toObject = require("./scripts/toObject");const { VueLoaderPlugin } = require("vue-loader");const { CleanWebpackPlugin } = require("clean-webpack-plugin");const PreventOutputJSPlugin = require("./scripts/PreventOutputJSPlugin");module.exports = (env, options) => { const isProd = options.mode === "production"; const cssSetting = { mode: "development", context: __dirname, devtool: false, entry: { ...toObject(glob.sync("apps/statics/scss/**/*.scss")), }, output: { path: path.resolve(__dirname, ""), }, module: { rules: [ { test: /\\.scss$/, use: ["postcss-loader", "sass-loader"], type: "css", }, ], }, plugins: [new PreventOutputJSPlugin()], resolve: { alias: { src: path.resolve(__dirname, "src/"), apps: path.resolve(__dirname, "apps/"), }, }, optimization: { minimize: false, }, }; const jsSetting = { context: __dirname, devtool: false, entry: { index: path.resolve(__dirname, "src/js/entry/index.js"), }, output: { path: path.resolve(__dirname, "apps/statics/dist/"), filename: "js/[name].js", }, target: ["web", "es5"], module: { rules: [ { test: /\\.vue$/, loader: "vue-loader", options: { experimentalInlineMatchResource: true, }, }, { test: /\\.scss$/, use: [ { loader: "style-loader", options: { esModule: false }, }, "css-loader", "postcss-loader", "sass-loader", ], type: "javascript/auto", }, { test: /\\.css$/, use: [ { loader: "style-loader", options: { esModule: false }, }, "css-loader", ], type: "javascript/auto", }, { test: /\\.(png|jpe?g|gif|svg)$/i, type: "asset/inline", }, { test: /\\.(woff|woff2|eot|ttf|otf|)$/, type: "asset/resource", }, ], }, plugins: [new VueLoaderPlugin()], resolve: { alias: { src: path.resolve(__dirname, "src/"), apps: path.resolve(__dirname, "apps/"), node_modules: path.resolve(__dirname, "node_modules/"), }, }, externals: { vue: "Vue", axios: "axios", jquery: "jQuery", }, optimization: { minimize: isProd, }, }; if (isProd) { jsSetting.plugins.push(new CleanWebpackPlugin({ verbose: true })); } return [cssSetting, jsSetting];};对于 CSS 文件,我们不需要 css-loader 或 MiniCssExtractPlugin 来构建. scss。
对于 JavaScript 文件,大多数配置与之前相同。
我们的项目大约有 40 个 JavaScript 文件和 90 个 CSS 文件需要构建,让我们看看构建性能:
Webpack
开始开发服务器:35 秒
生产构建:42 秒
开发服务器热构建时间:约 300 毫秒
Rspack
开始开发服务器:15 秒
生产构建:15 秒
开发服务器热构建时间:约 170 毫秒
如你所见,Rspack 在各种场景下的表现都优于 Webpack。
我是否已经用 Rspack 替换了 Webpack?
我真的很想退役 Webpack 以节省我宝贵的时间。然而,在我们的项目中,我们会配置我们的 css-loader 不解析我们 .scss 文件中的 urls:
{ loader: 'css-loader', options: { url: false }}而当前版本的 Rspack(v0.2.9)还不支持这一点。尽管它的构建速度仍然比 Webpack 快得多,但它也会在我们的终端上留下大量错误信息。在与我的团队成员讨论后,我们决定现在不替换它。我已经将其作为功能请求报告给 Rspack 的 Github 问题,并希望这个功能能尽快实现。
结论
正如我在开头提到的,与 Webpack 相比,Rspack 在构建 CSS 和 JavaScript 文件方面确实做得很好,而且从 Webpack 迁移过来不会花费太多时间。所以,如果你想减少构建时间,不要犹豫,冲它!
我是 ssh,工作 6 年 +,阿里云、字节跳动 Web infra 一线拼杀出来的资深前端工程师 + 面试官,非常熟悉大厂的面试套路,Vue、React 以及前端工程化领域深入浅出的文章帮助无数人进入了大厂。
欢迎
长按图片加 ssh 为好友,我会第一时间和你分享前端行业趋势,学习途径等等。2023 陪你一起度过!
关注公众号,发送消息:
指南,获取高级前端、算法学习路线,是我自己一路走来的实践。
简历,获取大厂简历编写指南,是我看了上百份简历后总结的心血。
面经,获取大厂面试题,集结社区优质面经,助你攀登高峰
因为微信公众号修改规则,如果不标星或点在看,你可能会收不到我公众号文章的推送,请大家将本公众号星标,看完文章后记得点下赞或者在看,谢谢各位!