参考 mini-webpack,使用 Rust 从零实现一个简单的 webpack,深入理解 webpack 的同时,还锻炼了 Rust 的技能,简直赢麻了!
代码地址:https://github.com/ParadeTo/rs-webpack
本文对应 Pull Request:https://github.com/ParadeTo/rs-webpack/pull/4
标题似乎与本系列风马牛不相及,用 Rust 实现 webpack 怎么就涉及到了 Node.js 的插件开发了,别急,待我先解释一下。回想一下,我们使用 webpack 进行打包时,是不是经常会执行下面这个命令:
1 | webpack --config webpack.config.js |
同样的,我们的 RS Webpack 也想支持这样的命令,但是 Rust 中怎么去得到 webpack.config.js
中导出的内容呢?我能想到的是需要有个 JS Runtime 去运行 webpack.config.js
,但是感觉这样未免有点太重了,而且还涉及到 JS Runtime 需要能把 webpack.config.js
中的内容在 Rust 中还原出来,找了一圈发现没有什么好用的工具,所以只能另辟蹊径了。
查阅 Rspack 源码发现,它是利用 NAPI-RS 给 Node.js 开发插件来实现的。具体做法是使用 Rust 来编写打包器的核心代码,使用 NAPI-RS 编译成插件供 Node.js 端调用,而 Node.js 端负责配置文件的导入与解析,并作为参数传给 Rust 提供出来的接口。
如何使用 NAPI-RS,可以参考官网,这篇文章主要介绍如何将我们的项目改造成我们需要的结果。
首先,我们把我们的项目结构改成如下这样:
1 | . |
crates
下面放的是 Rust 项目,rswebpack_binding
是由 NAPI 自动生成的,主要用于导出接口,rswebpack_core
是核心库,上一篇文章的相关代码都移动到了这里面packages
下面放的是 JS 项目,rswebpack-cli
最终会发布成命令行工具。
其中,rswebpack_binding
中的代码比较简单,仅仅是在原来的 Compiler
上包装了一下:
1 | // lib.rs |
这里新定义了 RawConfig
用于接收 JS 传入的配置,然后还规定了 RawConfig
如何转换为 Config
,不过目前转换规则非常简单。
而 rswebpack-cli
就更简单了,只需要解析命令行参数,读取配置,然后调用插件导出的接口就行:
1 |
|
别忘了 package.json
中配置好命令的名字:
1 | { |
然后 npm link
一下,之后我们新建一个目录:
1 | . |
其中 rswebpack.config.js
内容如下所示:
1 | const path = require('path') |
之后,执行 rswebpack --config rswebpack.config.js
,如果能正常输出 bundle.js
则说明改造成功。