最近,我开始学习如何构建Webpack插件。我正在尝试构建一个插件来更新我的源代码。
规则很简单:
a
,我必须将块中所有模块中的所有变量haha
重命名为hehe
所述进入点的位置。a
,我必须将块中所有模块的所有变量haha
重命名为hoho
所述进入点的位置。这是我的代码:
a.js
const haha = 'hello';
// will be "const hehe = 'hello';" in the bundle of "aa" entry point
// will be "const hoho = 'hello';" in the bundle of "aaaa" entry point
console.log(haha);
// will be "console.log(hehe);" in the bundle of "aa" entry point
// will be "console.log(hoho);" in the bundle of "aaaa" entry point
export default haha;
// will be "export default hehe;" in the bundle of "aa" entry point
// will be "export default hoho;" in the bundle of "aaaa" entry point
few.js
import haha from 'a'; // will be "import hehe from 'a';" in the bundle
console.log(haha); // will be "console.log(hehe);" in the bundle
lots.js
import haha from 'a'; // will be "import hoho from 'a';" in the bundle
console.log(haha); // will be "console.log(hoho);" in the bundle
webpack.config.js
module.exports = {
mode: 'development',
entry: {
aa: 'few.js',
aaaa: 'lots.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
}
};
我不知道该怎么做。
在一开始,我认为我的插件必须注册到解析器的特定挂钩,检查当前入口点的名称并替换AST节点的名称。问题是模块a.js
仅解析一次。
我尝试的第二种方法是注册到render
的{{1}}钩子并通过简单的正则表达式重命名变量。我不喜欢这种方法,因为通过正则表达式替换代码非常困难(IMO)。
您怎么看?正确的方法是什么?
答案 0 :(得分:1)
是的。您无法在模块中获取条目信息。 我认为您可以解决的方法可能是不使用入口点。 由于模块在加载后即被缓存, 我们可以利用内联资源查询
a.js
const haha = 'hello';
console.log(haha);
export default haha;
few.js
import haha from './a?change=e'; // will be "import hehe from 'a';" in the bundle
console.log(haha); // will be "console.log(hehe);" in the bundle
lots.js
import haha from './a?change=o'; // will be "import hehe from 'a';" in the bundle
console.log(haha); // will be "console.log(hoho);" in the bundle
自定义加载程序-> transformer.js
module.exports = function(source) {
let queryval = "";
if (this.resourceQuery && this.resourceQuery.indexOf('change')) {
queryval = this.resourceQuery.substr(this.resourceQuery.indexOf("change"+ 1));
// console.log("queryval: ", queryval);
if (queryval) {
const replacedCode = source.replace(/[a]/g, queryval); // this replace every thing but need own logic even default -> def_ult _ is query val :P
console.log("replacedCode: ", replacedCode);
return replacedCode;
}
}
return source;
}
webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
entry: {
aa: './src/few.js',
aaaa: './src/lots.js'
},
module: {
rules: [
{
test: /\.js$/,
oneOf: [
{
resourceQuery: /change/,
use: [
{
loader: path.resolve('./src/transformer.js'),
options: {
replaceWith: true
}
}
],
},
{
loader: path.resolve('./src/transformer.js'),
}
],
}
]
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
optimization: {
runtimeChunk: "single"
}
};
答案 1 :(得分:0)
我打开了一个issue。 Tobias Koppers的回复:
那不可能。
这些模块独立于原始入口点。模块 图不包含此信息。除了那个模块 可以在两个入口点中使用,但在这种情况下不能进行两次构建。