Webpack迁移Rspack速攻实战教程(前瞻版)
Posted 咲奈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Webpack迁移Rspack速攻实战教程(前瞻版)相关的知识,希望对你有一定的参考价值。
前言
rspack 即将开源,但社区中不乏有已经落地的 case ,比如 rspack-migration-showcase 、 modern.js 等。
基于此,本文将介绍如何迁移一个近似于 CRA( create-react-app ) 的项目到 rspack 。
在阅读本文前,我们认为读者已经熟练掌握了 webpack 配置,本文将略过所有前置知识。
注:由于 rspack 处于 0.0.x
版本,可能会发生较大变化,故本文可能存在过时的部分,请仔细甄别。
正文
启动层
启动层分 实例实现
和 DevServer
实现,他们的区别是:
webpack
// webpack 实例
import webpack from 'webpack'
webpack()
// webpack dev server
import WebpackDevServer from 'webpack-dev-server'
WebpackDevServer()
rspack
// rspack 实例
import * as rspack from '@rspack/core'
rspack.rspack()
// rspack dev server
import * as rspackDevServer from '@rspack/dev-server'
rspackDevServer.RspackDevServer()
// 🔴 不支持合成导入
// import rspack from 'rspack'
// import rspackDevServer from '@rspack/dev-server'
无论是 webpack
还是 rspack
,在启动层几乎一致,通过 实例实现
传入配置得到 compiler
,即可引导启动 DevServer
或进行构建,细节略:
// 获取 compiler
const instanceImpl = rspack.rspack // or `webpack`
const compilerImpl = instanceImpl(webpackConfig)
// 获取 dev server
const devServerImpl = rspackDevServer.RspackDevServer // or `WebpackDevServer`
const devServer = devServerImpl(devServerConfig, compilerImpl)
可以看到两者无明显区别,需要注意的是使用 compiler
的后续 api 可能存在 rspack 未支持的情况。
配置层
配置类型
两者配置类型获取方式:
import type Configuration as WebpackConfig from 'webpack'
import type Configuration as RspConfig from '@rspack/core'
基本一致的配置项
这里指的是直接把 webpack
的配置原模原样拷贝给 rspack
也可以兼容的选项,经作者尝试,常用选项如下:
mode
entry
context
output
devtool
devServer
target
stats
infrastructureLogging
有区别的配置项
webpack
的复杂配置需要进行一些调整才能给予 rspack
使用。
resolve
rspack
的 resolve
配置项要在 webpack
的基础上加一个 tsConfigPath
,表示当前项目 tsconfig.json
的路径:
rspackConfig.resolve =
...webpackConfig.resolve,
tsConfigPath: ...
module - javascript 资源
rspack
的每个 rule
配置必须指明他的 type
,如:
module:
rules: [
test: /\\.tsx$/,
// 🟢
type: 'tsx'
]
这和 webpack
中的 asset type 等相似,但 rspack
不光有自己独有的 type
类型(比如 tsx
、ts
等),也支持 asset type (见下文)。
目前常用的 type
有:
ts
/tsx
js
/jsx
css
/css/module
请各取所需。
module - CSS 资源
由于 webpack
的 css 配置过于繁琐,此处仅介绍重点:
-
无需配置
style-loader
、css-loader
,在rspack
我们用不到。 -
postcss-loader
需要替换成@rspack/postcss-loader
,选项的区别是插件必须传递实例,如:// 获取 postcss options const postcssOptions = plugins: [ require( require.resolve('postcss-flexbugs-fixes') ) // ... ]
在
webpack
的postcss-loader
选项中,插件是可以传递路径的,如仅传递require.resolve('postcss-flexbugs-fixes')
,但传递实例也可以,但rspack
只能传递实例。 -
别忘了设定
css
/css/module
的type
给对应规则。 -
sass-loader
/less-loader
使用、配置方式不变。
module - Asset 静态资源
和 webpack
配置方式一致,可正常使用 asset type 注明静态资源:
test: /\\.(png|jpe?g|gif|webp)(\\?.*)?$/i,
type: 'asset/resource'
注意 svgr
需要额外设定 type: 'tsx'
,表示以 JavaScript 方式承接,否则将得到错误的静态资源,另外,由于 svgr
在内部使用 babel 转译组件,将花费较长时间,可 fork 后修改为 esbuild
转译加速,或一律将 .svg
作为静态资源输出。
plugins - 非内置能力
目前 rspack
对 webpack
插件 hooks api 支持较少,大部分插件无法使用,可用经典插件如下:
clean-webpack-plugin
webpack-bundle-analyzer
对于 html-webpack-plugin
的平替,有两个方式可选:
-
使用
@rspack/plugin-html
替代:目的是用来支持其他需要调用HtmlWebpackPlugin
的后续插件,如有些插件需要在 html 模板中进一步加工,若你有二次使用HtmlWebpackPlugin
的插件,请采用此方案。 -
使用内置能力
builtins.html
,详见下文。
在迁移过程中,作者发现的不可用插件如下:
fork-ts-checker-webpack-plugin
明确了哪些经典插件可以直接使用,哪些不可以后,我们距离完整补全 webpack
插件相同的能力还差一些,这些能力已在 rspack
中内置( builtins
),通过 builtins.xxx
方式配置。
plugins - 内置能力
builtins.define
// rspack config
builtins:
define:
'process.env.SOME': JSON.stringify('value'),
// ...
该能力可以平替 DefinePlugin
插件,传值方式一致。
builtins.copy
该能力可以平替 copy-webpack-plugin
,大部分选项与 webpack
一致,但不完整,不支持 globOptions
,这意味着无法忽略某些文件不被拷贝,从而我们无法做到将 index.html
模板文件放到静态资源目录。
比如我们预期拷贝 public/*
到产物目录,但 index.html
我们无法放到 public/index.html
里,因为不支持配置忽略就会造成多份相同资源 emit 冲突,解决方法是 html 模板只能放到项目根目录。
builtins.react
swc 的 react 开发时配置,如下配置即可:
builtins:
react:
development: isDev,
refresh: isDev,
runtime: 'automatic'
builtins.bar
相当于 webpackbar
的替代,但打印容易错位,同时 rspack
非常快,没有必要展示进度条,不建议配置该选项。
builtins.html
内置的 html 能力,缺点是没有提供 HtmlWebpackPlugin
插件实例,无法和其他插件联动,同时配置项不够完整。
值得庆幸的是 lodash template 语法无论是 builtins.html
还是 @rspack/plugin-html
均支持,如 <%= htmlWebpackPlugin.options.title %>
。
若你需支持类似 CRA 的 %PUBLIC_URL%
变量替换,请使用 react-dev-utils/InterpolateHtmlPlugin
搭配 @rspack/plugin-html
,使用方式见 CRA eject
结果。
plugins - 其他
到这里,如果严格和 webpack
插件相比,我们还缺少一些,比如 MiniCssExtractPlugin
、ReactRefreshWebpackPlugin
、ProvidePlugin
,这些由 rspack
内置支持,我们无需配置。
当你需要更多功能时,请优先寻找平替,他可能是一个 builtins.xxx
内置能力,或是某个选项,或是某个 @rspack/plugin-xxx
包。
optimization
对于 optimization.minimize
两者一致。
对于 optimization.minimizer
,我们无需外部提供压缩能力,已经内置。
对于 optimization.splitChunks
,目前支持的分包选项不够全面,不支持调用函数(如 name()
、test()
等),此处推荐手动使用 webpack
拆包语法分包( () => import()
);可以尝试配置非函数选项,但是否生效未知。
cache
虽然 rspack
有 cache
选项,但截止本文发稿时,只能配置 true
/ false
,并未发现有缓存出现。
由于截止本文发稿时,rspack
暂未开源文档未释出,请后续自行探索。
其他
经作者探索,将某个 JavaScript 对象传递至 webpack
构建流程中,是可以通过引用的方式双向同步数据的,但在 rspack
不可以,推测这与 Rust 不支持有关。
总结
本文介绍了 webpack
迁移至 rspack
的基本流程和相关探索,至此,已经完成了 CRA 所有基本能力的平替,代码详见 xn-sakina / xn 。
在作者尝试开发过程中,热更新仍存在丢失样式等问题,经刷新页面后恢复,请酌情采用(如开发时 rspack
构建时 webpack
)。
关于更多 rspack
能力,请自行探索开源后的文档的选项。
以上。
字节跳动发布自研 Web 构建工具 Rspack
作者 | Rspack Team
Rspack 是由 ByteDance Web Infra 团队孵化的基于 Rust 语言开发的 Web 构建工具,拥有高性能、兼容 Webpack 生态、定制性强等多种优点,解决了我们在业务场景中遇到的非常多的问题,让很多开发者的体验有了质的提升。
仓库地址:https://github.com/web-infra-dev/rspack
Quick Start:https://rspack.dev/guide/quick-start.html
官网:https://rspack.dev
为什么要做 Rspack ?
字节跳动内部存在非常多的大型前端应用,它们有着非常复杂的构建配置,十几分钟甚至半小时的构建耗时,我们尝试了多种方法去优化这些项目的编译速度,但是社区内存在的方案都或多或少存在一些问题,在对这些问题总结后,我们理解到工程师对构建工具的诉求是:
良好的 Dev 启动性能,
npm run dev
是开发者每天需要运行很多次的命令,大型项目每次都需要等待 10 分钟,这对于工程师来说是非常痛苦的,所以优化 dev start 的时间是非常重要的;
良好的 Build 性能,
npm run build
是在 CI/CD 环境中经常运行的指令,他决定了应用生产交付的效率,在生产环境中有些应用经常需要 20 ~ 30 分钟的构建时间,如果能缩短这里的耗时对开发链路也会非常有帮助;
足够灵活的配置,用户工程的配置灵活多变,并没有做到完全的统一,在之前尝试将 Webpack 配置迁移到其他构建工具的过程中我们就遇到了非常多的问题,他们的配置都很难达到 Webpack 的灵活程度;
生产环境的产物优化能力,在启动 Rspack 之前,我们实践了社区内的各种方案,但是他们都面临了生产环境一定程度负优化的情况,例如拆包拆的不够精细等等。所以生产环境产物优化是我们不可舍弃的功能点。
在明确这四点之后,我们调研了社区内的所有技术方案,发现并没有完全满足我们需求的,所以我们决定自研 Rspack。
目前 Rspack 是什么阶段
到今天为止 Rspack 已经开发 11 个月左右的时间了,虽然还处于比较早期的阶段,但是在我们验证中, Rspack 可以给项目带来 5 ~ 10 倍的编译效率提升,并且随着我们内置了越来越多的常见 features,性能也在逐步的提升中。
目前 Rspack 已经完成了 Webpack Loader 架构的支持,你可以在 Rspack 中使用很多你之前见到的 Loader,如 babel-loader、less-loader、svgr 等等。我们长期的目标是完整支持 Loader,未来可以直接在 Rspack 中使用社区内的 vue-loader。
当下 Rspack 对缓存的支持还比较简单,只有内存级别的缓存,未来我们会建设更强的缓存能力,包括可以写入硬盘的缓存,并且我们会把缓存做到可以跨设备共享和迁移,提升大型应用的缓存复用率。
Rspack 作为一个较为底层的基础设施,需要通过和社区内的各种上层框架结合才能在开发中获得发挥作用,目前 Rspack 已经接入了字节内的各种研发框架,外部的合作将逐渐开始,现已与 webpack 建立正式合作关系。
未来计划
完善基础能力
Rspack 虽然目前提供的能力能够满足大多数的项目使用,但是相比 Webpack 提供的丰富能力仍然相差很多,我们在未来会根据社区反馈,丰富 Rspack 的基础能力,满足更多的构建场景需求。
跟社区内的伙伴合作
Rspack 作为一个底层依赖解决了我们自己在工作中遇到的很多问题,相信他也可以解决社区的问题。我们非常愿意给社区内的框架团队一些支持,让大家发挥出来 Rspack 真正的性能优势。
提升插件能力
目前 Rspack 已经基本支持了 Loader API,和较少的 Webpack Plugin API,有很多 API 因为会产生较大的性能问题影响,所以我们暂时没有暴露,我们同时也在探索更高性能的插件通信方案,另外一部分 API 是因为我们精力问题暂时没有完成,欢迎大家 PR。在未来,我们会考虑提供高性能的动态插件方案,这些插件可以在提供自由定制的功能的同时,带给开发者更好的开发体验。
持续提升性能
目前 Rspack 是以性能为核心卖点的项目,所以在未来我们会做很多的事情以保持这个特性,如完善性能观测实验室,做好性能防劣化的工作;在更多的场景中使用并发/多核友好的算法;研发可跨平台共享的缓存体系;优化内存占用等等。
建设质量保障体系
在保障性能的同时,我们也会努力去保障 Rspack 的质量,Webpack 已经积累了非常丰富的测试用例,未来 Rspack 会复用 Webpack 已有的测试用例来完善自己的逻辑。建设更加完善的 CI 体系,和社区项目共建 Ecosystem CI 体系,保障项目升级不对上游的项目造成break,保障项目长期健康,并且在测试覆盖率上保障长期上升。
根据我们过去使用 Webpack 的经验,升级构建工具是一件耗时耗力的操作,我们也要请大家帮助我们贡献更多的测试用例,Rspack 会在迭代中尽量保持兼容。
☞小鹏汽车回应多名核心高管换血;OpenAI 总裁回应马斯克批评:我们犯了一个错误;GPT-4 或将于下周发布|极客头条
☞程序员该如何处理遗留软件?
☞“我们聘请 ChatGPT,让它当了一天 ML 工程师”
以上是关于Webpack迁移Rspack速攻实战教程(前瞻版)的主要内容,如果未能解决你的问题,请参考以下文章
如何迁移开源 Flink 任务到实时计算Flink版?实战手册来帮忙!
Office365混合部署实战系列教程二:制定混合部署的迁移方案