参考 mini-webpack,使用 Rust 从零实现一个简单的 webpack,深入理解 webpack 的同时,还锻炼了 Rust 的技能,简直赢麻了!
代码地址:https://github.com/ParadeTo/rs-webpack
本文对应 Pull Request
实现一个简单的 webpack,首要关键的任务是 JS 代码的解析问题,从头实现一个 JS 解析器是一个非常浩大的工程,所以我们还是挑选一个现成的工具吧,这里选择了 oxc,毕竟是尤大大背书过的。
虽然,oxc 没有 babel 那么详细的文档,但是使用套路还是类似,首先我们需要使用 oxc_parser 来解析 JS 代码生成 AST:
1 | let name = env::args().nth(1).unwrap_or_else(|| "test.js".to_string()); |
其中 test.js
中的内容如下所示:
1 | const b = require('./b.js') |
解析得到的 AST 如下所示:
1 | { |
熟悉 webpack 的知道,打包时我们需要把 require
替换成 __webpack_require__
,并把相对路径 ./b.js
替换成完整路径,所以我们还需要修改原来的代码,这就需要用到 oxc_traverse 了,它的作用是遍历 AST 中的节点,方便我们对感兴趣的节点进行操作。
从上面的 AST 结果中,可以看到我们感兴趣的节点是 CallExpression
,所以我们可以实现一个 Transform 来修改这个节点,如下所示:
1 | struct MyTransform; |
可以按照如下方式来使用这个 Transform:
1 | // 2 Semantic Analyze |
注意,同 babel 不同的是,这里需要先使用 oxc_semantic 进行语法分析得到 symbols
和 scopes
一并传入 traverse_mut
。
最后,我们使用 oxc_codegen 重新生成代码就大功告成了:
1 | // 4 Generate Code |
1 | const b = __webpack_require__('full_path_of_b') |