how to make webpack recompile on dev mode with cache on?
robotsmeagol opened this issue · 11 comments
trying to write a plugin based on HtmlWebpackPlugin to change the output of html.
dev mode with cache on, if index.html is not changed, how to make webpack recompile and generate html
class MyPlugin {
apply(compiler) {
compiler.hooks.compilation.tap("MyPlugin", (compilation) => {
HtmlWebpackPlugin.getCompilationHooks(compilation).beforeEmit.tapAsync(
"MyPlugin",
(data, cb) => {
data.html += Date.now();
cb(null, data);
},
);
});
setInterval(() => {
compiler.compile()
}, 60000)
}
}
dev mode with cache on, compiler.compile() won't regenerate html.
You should not run:
setInterval(() => {
compiler.compile()
}, 60000)
it is bad for perf
Sorry I don't undestand what do you try to do
i'm trying to get data from server and inject into html, like this
const res = await axios.get('xxx.com/xxxxx')
data.html += res.data
on dev mode, i want to use timer to check whether data from server changed and regenerate html if changed
Please use HtmlWebpackPlugin.getHooks(compilation).beforeEmit
right now (getCompilationHooks
is not released), I don't recommend to run compiler.compile
using times, you can send a HEAD
request and check it is 304
code or not, and only when somethings changed re-run compilation
how to re-run compilation, do u mean npm run dev
again?
@robotsmeagol to rerun compilation I recommend to make compiler.watching.invalidate()
, note compiler.watching
is not undefined only when you watch
i tried compiler.watching.invalidate()
, but only first time this would works, after that html won't regenerate
What do you mean won't regenerate?
U can check on this demo
in config/Myplugin.js, i inject customData to html
customData is always 100 and never changed
Solution:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
class MyPlugin {
constructor() {
this.pathToData = path.resolve(__dirname, "./my-data.json");
}
apply(compiler) {
compiler.hooks.thisCompilation.tap("MyPlugin", (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
"MyPlugin",
(data, cb) => {
let content;
try {
content = compilation.inputFileSystem.readFileSync(this.pathToData, "utf8");
} catch (error) {
cb(error);
return;
}
content = JSON.parse(content);
compilation.fileDependencies.add(this.pathToData);
data.html = data.html.replace(
"</head>",
`<script>window.customData=${JSON.stringify(content.value)}</script></head>`,
);
cb(null, data);
},
);
});
}
}
module.exports = MyPlugin;
File:
my-data.json
{
"value": "11244123"
}
Add:
{
watchFiles: [require("path").resolve(__dirname, "my-data.json")],
// Other options
}
to config/webpackDevServer.config.js
And disable cache for HtmlWebpackPlugin
new HtmlWebpackPlugin(
Object.assign(
{},
{
cache: false,
inject: true,
template: paths.appHtml,
},
isEnvProduction
? {
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}
: undefined,
),
),
i.e. cache: false
, so webpack will automatically reload page and apply new data
There is a bug in cache
for html-webpack-plugin, that is why we disable it, I am working on the new major release without this bug, cache will work without extra setup in future and without bugs