Ответ 1
Недавно я использовал модифицированную версию этого решения в производстве, и у меня не было никаких проблем с ним. (Моя компания настроена с более сложным фильтром, чтобы исключить некоторые модули, но в остальном они одинаковы).
Мы используем конструкцию script для обхода соответствующего каталога (в нашей настройке src
, но в вашем src/snippets
). Для каждого файла, который заканчивается на .js, мы импортируем его и реэкспортируем его в src/index.js
. Если вам нужно что-то более надежное, например, переходить на несколько уровней, вам нужно будет изменить это, чтобы рекурсивно пересечь структуру каталогов.
Когда это будет сделано, мы выведем его в index.js вместе с напоминанием о том, что файл автоматически сгенерирован, чтобы отговорить людей от ручного добавления записей в файл.
const fs = require("fs");
const { EOL } = require("os");
const path = require("path");
let modules = 0;
const buffer = [
"// auto-generated file", "",
];
const emitModule = file => {
const moduleName = file.replace(".js", "");
modules += 1;
buffer.push(`exports.${moduleName} = require("./snippets/${moduleName}");`);
};
const files = fs.readdirSync(__dirname + "/snippets");
files
.filter(fname => fname !== "index.js" && !fname.startsWith("."))
.forEach(f => {
const stats = fs.statSync(path.join(__dirname, "snippets", f));
if (stats.isFile()) {
emitModule(f);
}
});
fs.writeFileSync(path.join(__dirname, "index.js"), buffer.join(EOL)+EOL);
console.info(`Built 'src/index.js' with ${modules} modules`);
Затем, в webpack.config.js, мы устанавливаем для libraryTarget значение umd
следующим образом:
module.exports = {
entry: path.resolve(__dirname, "src/index.js"),
output: {
path: path.resolve(__dirname, "build/"),
filename: "mylib.js",
libraryTarget: "umd"
}
};
Наконец, для удобства в package.json мы используем следующее, чтобы автоматически запускать конструкцию script перед созданием (вы также можете использовать ее перед запуском webpack-dev-сервера или запусками тестов mocha).
Эта настройка выглядит довольно взломанной, но она работает очень хорошо. Единственная проблема, с которой я когда-либо сталкивался, заключается в том, что иногда порядок модулей изменяется (предположительно, из-за различий в среде), а перечисление файлов вызывает ложное срабатывание в git.
Я поставил весь пакет на GitHub здесь: https://github.com/akatechis/webpack-lib-poc
Обновление:
Если вы не хотите вручную вызывать сборку script, добавив ее в свой пакет package.json scripts
, вы всегда можете обернуть ее как плагин webpack. Вы можете прочитать подробности здесь
Короче говоря, плагин - это всего лишь объект с методом apply
, который регистрируется с помощью компилятора webpack. Из документов:
В качестве умного разработчика JavaScript вы можете вспомнить метод
Function.prototype.apply
. Из-за этого метода вы можете передать любую функцию в качестве плагина (this
укажет на компилятор). Вы можете использовать этот стиль для встроенных пользовательских плагинов в своей конфигурации.
Ниже приведены изменения между двумя настройками:
Измените конфигурацию webpack для импорта сборки script и добавьте ее в массив plugins
:
const path = require("path");
const buildPlugin = require("./src/index.build");
module.exports = {
entry: path.resolve(__dirname, "src/index.js"),
output: {
path: path.resolve(__dirname, "build/"),
filename: "mylib.js",
libraryTarget: "umd"
},
plugins: [buildPlugin]
};
Затем измените index.build.js
, чтобы экспортировать функцию, которая регистрирует обратный вызов в компиляторе (получает его как this
). Возьмите содержимое сборки script из ранее, поместите его в функцию build()
и затем экспортируйте функцию плагина следующим образом:
module.exports = function () {
this.plugin('run', function(compiler, callback) {
console.log("Build script starting");
build();
callback();
});
};
Удалите цель build-index
из любых скриптов в package.json
. Webpack теперь будет всегда вызывать вашу конструкцию script перед запуском.