Как обновить исходный код модуля на каждый фрагмент?
Недавно я начал изучать, как создавать плагины webpack. Я пытаюсь создать плагин, который обновит мой исходный код.
Правила просты:
- Если имя точки входа имеет менее 2
a
s, Я должен переименовать все переменныеhaha
вhehe
во всех модулях в куске указанной точки входа . - Если имя точки входа имеет более 2
a
s, Я должен переименовать все переменные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
немного.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
очень много.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
веб-пакет.конфиг.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
крюке mainTemplate
и переименовать переменные с помощью простого регулярного выражения. Мне не нравится этот метод, так как замена кода через регулярное выражение чрезвычайно сложна (IMO).
Что вы думаете? Каков правильный путь к этому?
2 ответа:
Ты прав. Вы не можете получить информацию о входе в модули. Я думаю, что вы можете решить, может быть, по-другому, не используя точку входа. В качестве модулей кэшируются, как только он загружен, мы можем использовать встроенный запрос ресурсов
A. js
const haha = 'hello'; console.log(haha); export default haha;
Немного.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
Очень много.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
Пользовательский загрузчик - > трансформатор.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; }
Веб-пакет.конфиг.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" } };
Я открыл выпуск . Ответ от Тобиаса Копперса :
Это невозможно.
Модули независимы от исходной точки входа. Модуль график не содержит этой информации. В дополнение к этому модули может быть в обеих входных точках, но не строятся дважды в этом случае.