Я использую веб-пакет с watch=true
для компиляции файлов руля в HTML файлы в папке /dist
.
HandlebarsWebpackPlugin
запускается при изменении файлов .hbs
, но я также хотите, чтобы он запускался при изменении файлов JSON. Файлы JSON содержат данные, которые передаются в шаблоны руля при их компиляции в HTML.
Я добавил плагин под названием webpack-watch-files-plugin
, считая, что он будет смотреть файлы JSON и повторно запускать полную сборку при обнаружении изменений, но это не так.
Может кто-нибудь объяснить, как работает веб-пакет в этом отношении? Как я могу перезапустить все плагины (или, по крайней мере, руль для HTML компиляции), когда я изменяю JSON файл?
webpack.config. js
const webpack = require('webpack');
const glob = require("glob");
const path = require("path");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HandlebarsPlugin = require("handlebars-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const WatchFilesPlugin = require('webpack-watch-files-plugin').default;
const mergeJSON = require("./src/utils/mergeJSON");
const handlebarsHelpers = require("handlebars-helpers");
const lang = process.env.npm_config_lang; // lang variable passed as argument to script
const webpackConfig = {
watch: true,
watchOptions: {
ignored: ['node_modules/**', 'dist']
},
entry: path.join(__dirname, 'src'),
plugins: [
new CleanWebpackPlugin(),
new HandlebarsPlugin({
// path to hbs entry file(s). Also supports nested directories if write path.join(process.cwd(), "app", "src", "**", "*.hbs"),
entry: path.join(__dirname, "src", "emails", "**/*.hbs"),
// output path and filename(s). This should lie within the webpacks output-folder
// if ommited, the input filepath stripped of its extension will be used
output: path.join(__dirname, "dist", "[path]", "[name].html"),
// you can also add a [path] variable, which will emit the files with their relative path, like
// output: path.join(process.cwd(), "build", [path], "[name].html"),
// data passed to main hbs template: `main-template(data)`
data: mergeJSON(path.join(__dirname, 'src/emails/**/*.json')),
// globbed path to partials, where folder/filename is unique
partials: [
path.join(__dirname, "src", "partials", "*.hbs")
],
// register custom helpers. May be either a function or a glob-pattern
helpers: {
projectHelpers: handlebarsHelpers()
},
// hooks
// getTargetFilepath: function (filepath, outputTemplate) {},
// getPartialId: function (filePath) {}
onBeforeSetup: function (Handlebars) {},
onBeforeAddPartials: function (Handlebars, partialsMap) {},
onBeforeCompile: function (Handlebars, templateContent) {},
onBeforeRender: function (Handlebars, data, filePath) {
const mergedData = mergeJSON(path.join(__dirname, 'src/emails/**/*.json'));
const filePathArray = filePath.split('/');
const fileName = filePathArray[filePathArray.length-1].split('.hbs')[0];
if(mergedData[fileName]) {
// only json specific to this file and language will be used as data for this file
return {...mergedData[fileName].config, ...mergedData[fileName][lang]};
} else if(!lang) {
const errorText = `The language code is required to build the emails. Pass it as an argument with this format "--lang=en-US".`;
console.log('\n', '\x1b[41m\x1b[37m', errorText, '\x1b[0m');
throw new Error(errorText);
}
},
onBeforeSave: function (Handlebars, resultHtml, filename) {},
onDone: function (Handlebars, filename) {}
}),
new CopyWebpackPlugin([{
from: path.join(__dirname, "src/emails/**/imgs/*"),
to: "[1]/[2].[ext]", // [1] and [2] are groups matched by the regex below
test: /emails\/([^/]+)\/(.+)\.(jpe?g|png|gif|svg|)$/,
}]),
new ImageminPlugin({test: /\.(jpe?g|png|gif|svg)$/i}),
new WatchFilesPlugin({
files: [
path.join(__dirname, "src", "emails", "**/data/*.json")
],
verbose: true
})
]
};
module.exports = webpackConfig;