Webpack:无限监视循环和自动生成的文件
Webpack: Infinite watch loop and auto-generated files
我有一个生成文件的脚本,将其命名为 auto.js
。此文件包含一些动态生成的导入,并在 VueJS 项目中使用。
// auto.js
import { apple, strawberry, orange } from 'delicious-fruits';
import { carrot, cucumber, celery } from 'delicious-vegetables';
在使用 Webpacks dev server 时,如果任何项目文件发生变化,我的目标是让这个脚本重新生成我的 auto.js
文件,然后将其包含在内在重新编译的项目中。
我已经把这个脚本变成了一个 Webpack 插件,我正在监听 watchRun
compiler hook。根据其描述,这似乎是理想的钩子:
Executes a plugin during watch mode after a new compilation is triggered but before the compilation is actually started.
class AutoGenerate {
constructor(options) {
this.options = options;
}
apply(compiler) {
compiler.hooks.watchRun.tap('AutoGenerate', () => {
generateFile()
})
}
}
function generateFile () {
// generate auto.js and write to disk
}
我总是遇到无限循环的情况。我尝试通过使用各种生命周期事件(挂钩)以及忽略自动生成的文件来解决问题。当然,通过忽略它,这些更改不会包含在重新编译的项目中。
const webpack = require('webpack');
const AutoGenerate = require("./auto.plugin");
module.exports = {
configureWebpack: {
plugins: [
new webpack.WatchIgnorePlugin([/.*auto\.js/]),
new AutoGenerate()
]
}
}
我也试过进入合辑,并向合辑添加新资产。虽然该过程没有出错,但生成的资产不是最终编译的一部分。
// auto.plugin.js
class AutoGenerate {
static defaultOptions = {
outputFile: 'auto.js',
};
constructor(options = {}) {
this.options = { ...AutoGenerate.defaultOptions, ...options };
}
apply(compiler) {
compiler.hooks.thisCompilation.tap('AutoGenerate', (compilation) => {
const path = require("path")
const filePath = path.resolve(__dirname, `src/plugins/${this.options.outputFile}`)
const { RawSource } = require('webpack-sources')
const fileContent = new RawSource(generateFile())
compilation.emitAsset(
filePath,
fileContent
)
});
}
}
function generateFile() {
// generate file content & return as string
}
module.exports = { AutoGenerate };
// vue.config.js
const AutoGenerate = require("./auto.plugin");
module.exports = {
configureWebpack: {
plugins: [
new AutoGenerate()
]
}
}
如何触发自动生成此文件的逻辑,同时将此文件作为任何重新编译的一部分包含在内,同时避免无限循环?
我无法确定上述问题的直接解决方案。然而,对于任何阅读者,我发现这可以通过使用一个名为 before-build-webpack
, notably by including the watch-run
trigger.
的包来实现。
// vue.config.js
const WebpackBeforeBuildPlugin = require('before-build-webpack')
module.exports = {
configureWebpack: {
plugins: [
new WebpackBeforeBuildPlugin(function(stats, callback) {
// ...
}, ['run', 'watch-run'])
]
}
}
我有一个生成文件的脚本,将其命名为 auto.js
。此文件包含一些动态生成的导入,并在 VueJS 项目中使用。
// auto.js
import { apple, strawberry, orange } from 'delicious-fruits';
import { carrot, cucumber, celery } from 'delicious-vegetables';
在使用 Webpacks dev server 时,如果任何项目文件发生变化,我的目标是让这个脚本重新生成我的 auto.js
文件,然后将其包含在内在重新编译的项目中。
我已经把这个脚本变成了一个 Webpack 插件,我正在监听 watchRun
compiler hook。根据其描述,这似乎是理想的钩子:
Executes a plugin during watch mode after a new compilation is triggered but before the compilation is actually started.
class AutoGenerate {
constructor(options) {
this.options = options;
}
apply(compiler) {
compiler.hooks.watchRun.tap('AutoGenerate', () => {
generateFile()
})
}
}
function generateFile () {
// generate auto.js and write to disk
}
我总是遇到无限循环的情况。我尝试通过使用各种生命周期事件(挂钩)以及忽略自动生成的文件来解决问题。当然,通过忽略它,这些更改不会包含在重新编译的项目中。
const webpack = require('webpack');
const AutoGenerate = require("./auto.plugin");
module.exports = {
configureWebpack: {
plugins: [
new webpack.WatchIgnorePlugin([/.*auto\.js/]),
new AutoGenerate()
]
}
}
我也试过进入合辑,并向合辑添加新资产。虽然该过程没有出错,但生成的资产不是最终编译的一部分。
// auto.plugin.js
class AutoGenerate {
static defaultOptions = {
outputFile: 'auto.js',
};
constructor(options = {}) {
this.options = { ...AutoGenerate.defaultOptions, ...options };
}
apply(compiler) {
compiler.hooks.thisCompilation.tap('AutoGenerate', (compilation) => {
const path = require("path")
const filePath = path.resolve(__dirname, `src/plugins/${this.options.outputFile}`)
const { RawSource } = require('webpack-sources')
const fileContent = new RawSource(generateFile())
compilation.emitAsset(
filePath,
fileContent
)
});
}
}
function generateFile() {
// generate file content & return as string
}
module.exports = { AutoGenerate };
// vue.config.js
const AutoGenerate = require("./auto.plugin");
module.exports = {
configureWebpack: {
plugins: [
new AutoGenerate()
]
}
}
如何触发自动生成此文件的逻辑,同时将此文件作为任何重新编译的一部分包含在内,同时避免无限循环?
我无法确定上述问题的直接解决方案。然而,对于任何阅读者,我发现这可以通过使用一个名为 before-build-webpack
, notably by including the watch-run
trigger.
// vue.config.js
const WebpackBeforeBuildPlugin = require('before-build-webpack')
module.exports = {
configureWebpack: {
plugins: [
new WebpackBeforeBuildPlugin(function(stats, callback) {
// ...
}, ['run', 'watch-run'])
]
}
}