Every time I change the index.html template, I need to re-run the build task now.
Hmm this should work - could you please try the 2.0 version or provide a demo?
Same problem i met.
When i run webpack-dev-server --inline --hot --colors --content-base=./www, it prints webpack: bundle is now INVALID.
plugin version:
"html-webpack-plugin": "^2.1.0",
"webpack-dev-server": "^1.14.0"
Same
var webpack = require('webpack')
, path = require('path')
, HtmlWebpackPlugin = require('html-webpack-plugin')
, CleanWebpackPlugin = require('clean-webpack-plugin')
, ExtractTextPlugin = require("extract-text-webpack-plugin")
, autoprefixer = require('autoprefixer')
module.exports = {
devServer: {
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
contentBase: './app',
port: 8080,
},
entry: [
path.resolve(__dirname, 'app/src/'),
],
output: {
path: path.resolve(__dirname, 'app/build/'),
filename: './js/bundle?[hash].js'
},
module: {
loaders: [
{
test: /\.jade$/,
loader: 'jade'
},
{
test: /\.js$/,
include: path.resolve(__dirname, 'app/src'),
exclude: /node_modules/,
loader: 'babel'
},
{
test: /\.styl$/,
include: path.resolve(__dirname, 'app/src'),
loader: ExtractTextPlugin.extract("style-loader", "css-loader!postcss-loader!stylus-loader")
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader!postcss-loader")
},
]
},
postcss: [ autoprefixer ],
plugins: [
new ExtractTextPlugin("./css/style?[hash].css"), // separate css
new CleanWebpackPlugin(['app/build'], {
verbose: true,
dry: false
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './app/src/jade/index.jade',
inject: 'body',
}),
new HtmlWebpackPlugin({
filename: 'homepage.html',
template: './app/src/jade/homepage.jade',
inject: 'body',
}),
]
}
webpack-dev-server --devtool eval --progress --hot --colors --host 0.0.0.0 --content-base app
webpack: bundle is now INVALID.
Hash: 020f485713bee7553bdf
Version: webpack 1.12.14
Time: 154ms
Asset Size Chunks Chunk Names
./css/style?020f485713bee7553bdf.css 1.93 kB 0 [emitted] main
index.html 297 bytes [emitted]
chunk {0} ./js/bundle?020f485713bee7553bdf.js, ./css/style?020f485713bee7553bdf.css (main) 213 kB
+ 79 hidden modules
Child html-webpack-plugin for "homepage.html":
chunk {0} homepage.html 6.11 kB
+ 3 hidden modules
Child html-webpack-plugin for "index.html":
chunk {0} index.html 6.1 kB [rendered]
[0] ./~/html-webpack-plugin/lib/loader.js!./app/src/jade/index.jade 394 bytes {0} [built]
+ 2 hidden modules
webpack: bundle is now VALID.
"devDependencies": {
"autoprefixer": "^6.3.3",
"babel-loader": "^6.2.3",
"babel-preset-es2015": "^6.5.0",
"babel-preset-stage-0": "^6.5.0",
"clean-webpack-plugin": "^0.1.8",
"css-loader": "^0.23.1",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
"html-webpack-plugin": "^2.9.0",
"jade": "^1.11.0",
"jade-loader": "^0.8.0",
"jquery": "^2.2.1",
"normalize.css": "^3.0.3",
"postcss-loader": "^0.8.1",
"precss": "^1.4.0",
"style-loader": "^0.13.0",
"stylus-loader": "^1.5.1",
"webpack-dev-server": "^1.14.1"
}
"html-webpack-plugin": "^2.8.1",
"webpack-dev-server": "^1.14.1"
getting the same error
any updates to this issue?
@usergit I am sorry but I really don't get the problem - every thing works as expected.
You change the html file, webpack sets the state to invalid and recompiles everything.
Only hot-module replacement is not possible.
馃槰 unfortunately and this is the things i met.
When i change the html file, webpack does recompiled but page still have no refresh action.
"devDependencies": {
"html-webpack-plugin": "^2.24.1",
"webpack": "^1.13.2",
"webpack-dev-server": "^1.16.2"
}
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'index.html')
})
]
webpack-dev-server --inline --hot
@viko16 there is no auto refresh by now - would be open for pull requests :)
Temporary solutions are always the best 馃槅
Just require template in your entry file (app.js or sth):
import "./index.pug";
And you will have fast bundling time + reload but don't do this on production 馃槈
It seems like Vue has solved this with https://github.com/vuejs-templates/webpack/blob/master/template/build/dev-server.js#L32-L37
@pspeter3 wow that's nice - is there any way we could move this into this plugin?
@jantimon I can try. I'll fork and submit a PR
So I think the issue is that the plugin doesn't have access to the hot middleware plugin. It seems like the Vue dev server is doing the best thing.
@19majkel94 Can you elaborate how you did it? i did import in my entry and did not reload the html.
i came a long way defeating one by one.. .ts, .babel, .scss.... and then i got stuck at .html, no hot reload for this on vanilla html.... nor even auto reload.. any way to get this working some other how ?
It looks like that this is really hard to accomplish on compiler level but could be accomplished on the level of the dev-server. I guess it might also be possible to write a custom html-webpack-hmr-plugin which would introduce a new entry point e.g. using https://github.com/jantimon/extra-entry-webpack-plugin which does the hmr - maybe you want to start working on that?
Running it doesn't generate the /dist folder files. Instead, if i just run webpack --watch and lite-server, it works for me. For some reason webpack-dev-server does kick off html plugin, but for some reason the plugin doesn't write to /dist afterwards.
@windmaomao that's completely unrelated to this thread - it's a performance boost by webpack-dev-server and can be solved by https://github.com/jantimon/html-webpack-harddisk-plugin or by setting the output filesystem - for further information please open a stackoverflow question
In case if needed, here's working setup with hot reload of .js and index.html
For hot reload development:
npm run dev
For production:
npm run build
webpack.config.js
```var path = require('path')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [{
test: /.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV !== 'production') {
module.exports.plugins = (module.exports.plugins || []).concat([
new HtmlWebpackPlugin({
template: './index.html'
})
])
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
})
])
}
package.json
```{
"name": "test1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --inline --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"mithril": "^1.0.0"
},
"devDependencies": {
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-plugin-transform-react-jsx": "^6.22.0",
"babel-preset-es2015": "^6.22.0",
"cross-env": "^3.1.4",
"file-loader": "^0.10.0",
"html-webpack-plugin": "^2.28.0",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.3.0"
}
}
/src/main.js
if (process.env.NODE_ENV !== 'production') {
require('file-loader!../index.html')
}
i think yet a better solution was doing something like this
devServer: {
contentBase: [ PathToTheFolderWhereYourHTMLsLives ],
watchContentBase: true
}
this approach doesnt require any "requiring" inside js files...
My approach is a hot reload and not full page reload.
If you change little piece of .js code you don't need to reload whole page.
Again, I just hate the fact that I need to add 'unnecessary' stuff in my js entries.. And somehow remember to remove that.. Or just leave there... Yet the one I showed still has HMR with js but with the html files will do a full page reload yes. Both ways not ideal.. Would rather study a possibility to create a plugin to inject html webpack plug-in outputs as an webpack entry and somehow get it done automatically...
Using reload-html-webpack-plugin is done !!
When you change the templates, the html-webpack-plugin does recompiling them, but it just not to re-write the new generated html files to the disk. Given this, even if the devServer reloading the pages, the result will not change. If you are in this case, try this plugin:
No need to write to disk or open more sockets: just use the html-webpack-plugin-after-emit event to trigger a content-changed message from the devserver::
let devServer; // set below
module.exports = {
plugins: [reloadHtml],
devServer: {
before(app, server) {
devServer = server;
}
}
}
function reloadHtml() {
this.plugin('compilation',
thing => thing.plugin('html-webpack-plugin-after-emit', trigger));
const cache = {};
function trigger(data, callback) {
const orig = cache[data.outputName];
const html = data.html.source();
// plugin seems to emit on any unrelated change?
if (orig && orig !== html)
devServer.sockWrite(devServer.sockets, 'content-changed');
cache[data.outputName] = html;
callback();
}
}
I'm sure someone can make a nice plugin out of this with more style, but this works for me.
reload-html-webpack-plugin doesn't seem to work with Webpack 4.
Thanks @avdd for the quick work-around, which worked for me (even though I wish this somehow worked out of the box between html-webpack-plugin and webpack-dev-server).
If anyone else runs into Webpack 4's deprecation warning:
DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
You can change reloadHtml to this:
function reloadHtml() {
const cache = {}
const plugin = {name: 'CustomHtmlReloadPlugin'}
this.hooks.compilation.tap(plugin, compilation => {
compilation.hooks.htmlWebpackPluginAfterEmit.tap(plugin, data => {
const orig = cache[data.outputName]
const html = data.html.source()
// plugin seems to emit on any unrelated change?
if (orig && orig !== html) {
devServer.sockWrite(devServer.sockets, 'content-changed')
}
cache[data.outputName] = html
})
})
}
@sebastianseilund not able to get this working compilation.hooks.htmlWebpackPluginAfterEmit.tap(..) produces:
TypeError: Cannot read property 'tap' of undefined
and indeed Object.keys( compilation.hooks ) is:
[ 'buildModule',
'rebuildModule',
'failedModule',
'succeedModule',
'finishModules',
'finishRebuildingModule',
'unseal',
'seal',
'optimizeDependenciesBasic',
'optimizeDependencies',
'optimizeDependenciesAdvanced',
'afterOptimizeDependencies',
'optimize',
'optimizeModulesBasic',
'optimizeModules',
'optimizeModulesAdvanced',
'afterOptimizeModules',
'optimizeChunksBasic',
'optimizeChunks',
'optimizeChunksAdvanced',
'afterOptimizeChunks',
'optimizeTree',
'afterOptimizeTree',
'optimizeChunkModulesBasic',
'optimizeChunkModules',
'optimizeChunkModulesAdvanced',
'afterOptimizeChunkModules',
'shouldRecord',
'reviveModules',
'optimizeModuleOrder',
'advancedOptimizeModuleOrder',
'beforeModuleIds',
'moduleIds',
'optimizeModuleIds',
'afterOptimizeModuleIds',
'reviveChunks',
'optimizeChunkOrder',
'beforeChunkIds',
'optimizeChunkIds',
'afterOptimizeChunkIds',
'recordModules',
'recordChunks',
'beforeHash',
'contentHash',
'afterHash',
'recordHash',
'record',
'beforeModuleAssets',
'shouldGenerateChunkAssets',
'beforeChunkAssets',
'additionalChunkAssets',
'additionalAssets',
'optimizeChunkAssets',
'afterOptimizeChunkAssets',
'optimizeAssets',
'afterOptimizeAssets',
'needAdditionalSeal',
'afterSeal',
'chunkHash',
'moduleAsset',
'chunkAsset',
'assetPath',
'needAdditionalPass',
'childCompiler',
'normalModuleLoader',
'optimizeExtractedChunksBasic',
'optimizeExtractedChunks',
'optimizeExtractedChunksAdvanced',
'afterOptimizeExtractedChunks' ]
webpack 4.8
html-webpack-plugin 3.20
NVM, it was a result of bad ordering in webpack-merge, where our custom reloadHtml plugin was coming before HtmlWebpackPlugin
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
i think yet a better solution was doing something like this
this approach doesnt require any "requiring" inside js files...