- Published on
- 约 693 字
实现一个简单的 webpack5 nodejs polyfill 插件
- Authors
- Name
- 小辉辉
现象
有一次项目开发中需要实现对js代码进行转换,包括提取一个对象中的方法,根据特殊规则对某些字符串进行转换等。第一反应就是可以借助babel这个库来实现,具体的实现逻辑就是现将js字符串转换为AST对象,再遍历这个AST对象,实现相关转换逻辑,利用babel自带的类型功能进行AST相关节点的替换,完成转化后再将AST转换为js字符串。
借助babel官方稳定实现这个功能并不难,但是最终在调试过程中遇到了一些意外情况。对应的开发环境是这样的,webpack5 + babel7.x版本,在项目中引入相关babel库后就出现了相关编译错误,主要错误总结如下:
process未定义,Buffer模块无法找到,path模块无法找到
方案
对于上述错误,大家都知道这些模块只有在nodejs开发环境下才存在,在浏览器环境下因为缺失这些模块肯定会报错。那怎么解决呢?首先是看了webpack的官方文档,里面就提到饿可以使用resolve.fallback
属性来解决,按照文档尝试了一番,发现又有了其它模块提示找不到这些模块的问题。
所以就有了这个webpack5-node-polyfill-plugin
这个插件,我是怎么想的呢?如果后期有些项目也遇到这种错误场景,我们有去配置这些参数相对来说就有些做重复工作了,为何不将这类配置直接封装到一个webpack插件里面呢?后面有需要直接引入这个插件就行了,这个样子就多简单了。除此之外,我们还可以考虑对这个插件将所有nodejs环境下可能存在在浏览器环境中用到的相关模块全部实现了,这样一来,可谓是一劳永逸啊。
最后,这个插件的实现也很简单,主要引入了node-libs-browser
这个插件,完整代码如下
const webpack = require('webpack');
const nodeLibs = require('node-libs-browser');
module.exports = class Webpack5NodePolyfillPlugin {
apply(compiler) {
compiler.options.plugins.push(
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: nodeLibs.process,
}),
);
const extractfallBack = Object.keys(nodeLibs).reduce((memo, key) => {
if (nodeLibs[key]) {
memo[key] = nodeLibs[key];
} else {
memo[key] = false;
}
return memo;
}, {});
compiler.options.resolve.fallback = {
...extractfallBack,
...compiler.options.resolve.fallback,
};
}
}
核心逻辑就是遍历node-libs-browser
模块库,将里面每个暴露的模块添加到webpack的resolve.fallback
对象下,特别要注意的是通过webpack自带的webpack.ProvidePlugin
插件单独处理了process和Buffer两个模块。
现在该插件也同时发布到了npm仓库,有需要直接本地安装即可:
npm i webpack5-node-polyfill-plugin