Html-webpack-plugin: Can this works with webpack-dev-server

Created on 21 Oct 2014  路  22Comments  路  Source: jantimon/html-webpack-plugin

I just tried to setup and had no luck. Any ideas?

Most helpful comment

It turns out that webpack-dev-middleware has exported fileSystem already, we can use it to get index.html and send it to the client during development.

Here is my devServer.js

import webpack from 'webpack'
import express from 'express'
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import config from './webpack.config'

const compiler = webpack(config)
const app = express()

const devMiddleware = webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath,
  historyApiFallback: true,
})

app.use(webpackHotMiddleware(compiler))
app.use(devMiddleware)


app.get('*', (req, res) => {
  // Here is it! Get the index.html from the fileSystem
  const htmlBuffer = devMiddleware.fileSystem.readFileSync(`${config.output.path}/index.html`)

  res.send(htmlBuffer.toString())
})

app.listen(8080, 'localhost')

All 22 comments

+1
During dev I'm running webpack-dev-server, so my index.html has a script tag pointing at http://localhost:1234/my-entry-bundle.js
For a production build I'd like to use my index.html file as a template for this plugin, and point the script tag at the generated my-entry-bundle.js on disk.
Currently I keep a copy of my index.html as index.production.html which I'm using as a template for html-webpack-plugin (containing <script src="{%=o.htmlWebpackPlugin.assets.main%}"></script>) but it's not ideal having duplicate index.htmls.
Would be nice if it supported webpack dev server out of the box!

I finally use this trick:

compile with webpack first then start webpack-dev-server like this:

http://git.io/bxtfjg

webpack-dev-server does serve HTML generated by this plugin, see this gist.

There may be some other scenarios that aren't handled properly though, if so can you elaborate on your config setup?

@tomchentw I had a look at your react-toastr project. I was able to make it work with webpack-dev-server by making a couple of changes in client/webpack.config.js:

  • Change output.publicPath from assets/ to /assets/ (note leading slash)
  • Change the HtmlWebpackPlugin filename option from ../index.html to index.html.

Then run webpack-dev-server --config ./client/webpack.config.js and access the app at http://localhost:8080/webpack-dev-server/assets/.

What I think is happening with your original configuration is that webpack-dev-server doesn't know what to do with the "../index.html" output path, and as a result the index.html file kind of gets "lost". I'd have to dig into the dev server code to find out more about what's going on.

@ampedandwired thanks for the reply. I'm struggling getting rid of /webpack-dev-server/ postfix of the url. I check the code and I think it's impossible for us to do that. Is that correct?

Actually, I'm trying to integrate this plugin to generator-rf. However, I think I have to modify the dev script from current to this:

webpack --color --watch & webpack-dev-server --inline --hot --content-base ./build

That is, start webpack with watch mode, so it will continuously generates newest index.html file using HtmlWebpackPlugin.
Then start webpack-dev-server to serve assets files but not index.html on the fly.

This can do the trick for what I want: generating up-to-date index.html during development process.

However, I'm thinking if one should modify webpack-dev-server to let it writes changed files to file system instead of persisting it in memory....

Using emitFile instead of directly assign compiles html to compiler.assets?

I don't think you can change the "/webpack-dev-server" prefix.

You shouldn't have to run both webpack --watch and webpack-dev-server together, because webpack-dev-server actually creates am embedded watching webpack compiler itself which emits all the assets into a memory file system.

Watching the index.html file for changes will hopefully be fixed in #5.

Closing this for now as I believe this plugin does in fact work OK with webpack-dev-server. Feel free to reopen if you feel that's not the case.

I also have the issue where I have an index.html template that I want to generate during development but it is not created (mine is also ../index.html because it cannot be in root of whole project build output rather than same folder as JavaScript)

It turns out that webpack-dev-middleware has exported fileSystem already, we can use it to get index.html and send it to the client during development.

Here is my devServer.js

import webpack from 'webpack'
import express from 'express'
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import config from './webpack.config'

const compiler = webpack(config)
const app = express()

const devMiddleware = webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath,
  historyApiFallback: true,
})

app.use(webpackHotMiddleware(compiler))
app.use(devMiddleware)


app.get('*', (req, res) => {
  // Here is it! Get the index.html from the fileSystem
  const htmlBuffer = devMiddleware.fileSystem.readFileSync(`${config.output.path}/index.html`)

  res.send(htmlBuffer.toString())
})

app.listen(8080, 'localhost')

Okay, I've just read through this comment which basically uses the same approach.

@wuct great! Would love to give it a shot in the future. Thanks for the sharing!

Another solution is to use the html-webpack-harddisk-plugin I guess.

As soon as you now set alwaysWriteToDisk to true the generated output of the HtmlWebpackPlugin will always be written to disk. This is very useful if you want to pick up the output with another middleware.

@radum Yap, that's another solution. However, write-to-hard-disk is much slower than write-to-memory.

@wuct Yeah of course, but this is a way to keep your express webpack free. Also the difference in speed for most use cases won't matter for dev purposes.

@ampedandwired , the output of the HtmlWebpackPlugin isn't seen by dev server 'in memory', and that's the problem! Can this be fixed, so the output is done like all other plugins do? The StaticSiteGenerator plugin does this correctly.

thanks

I recently came across this and my solution was to stop using the middleware and instead run webpack-dev-server directly.

For posterity, my versions:

{
    "html-webpack-plugin": "^2.29.0",
    "webpack": "^2.6.1",
    "webpack-dev-server": "^2.4.5"
}

For anyone who...

  • wants it to work with only webpack-dev-server --hot
  • wants to output the HTML file anywhere other than the project's root (e.g. dist)
  • confused with what to put on paths and publicPaths in the webpack config file
{
  // GOALS:
  //   - output the html file to `/dist`, relative to the project's root
  //   - output the js file to `/dist/js`, relative to the project's root
  //     and `/js` relative to the HTML file's root

  entry: './src/entryPoint.js',

  output: {
    // change this to `bundle.js` if you want it to be outputted to the same folder as HTML
    filename: 'js/bundle.js',

    path: path.resolve(__dirname, 'dist'),
    publicPath: '/',
  },

  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    publicPath: '/',
  },

  plugins: [
    new HtmlWebpackPlugin({
      filename: path.resolve(__dirname, 'dist/index.html'),
      template: path.resolve(__dirname, 'src/my-index-template.html'),
    }),
  ]
}

@chrisregner It worked for me! And this also should be added: devServer.watchContentBase = true

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.

Was this page helpful?
0 / 5 - 0 ratings