19

I'm using Webpack for bundling resources. Currently it bundle both the CSS and JS files into a separate file called bundle.js. How can I make both the JS and CSS embedded inline in html file?

import HtmlWebpackPlugin from 'html-webpack-plugin';
import {HotModuleReplacementPlugin} from 'webpack';

export default {
  entry: {app: './test/dev'},
  module: {
    loaders: [
      {test: /\.js/, loader: 'babel-loader', exclude: /node_modules/},
      {test: /\.scss$/, loader: 'style!css!sass'}
    ]
  },
  plugins: [new HotModuleReplacementPlugin(), new HtmlWebpackPlugin()],
  devtool: 'eval-source-map'
};
2
  • Did you find a solution? Commented Jun 6, 2017 at 8:12
  • 1
    I'm using grunt-processhtml github.com/dciccale/grunt-processhtml to solve that. Commented Jun 6, 2017 at 19:22

5 Answers 5

9

Use InlineChunkHtmlPlugin from react-dev-utils

const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');

module.exports = {
  // ...
  output: { filename: 'client-bundle.js' },
  plugins: [
    new HtmlWebpackPlugin(),
    new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/client-bundle/]),
  ],
  // ...
};

*where "/client-bundle/" regex should match output filename

https://github.com/facebook/create-react-app/tree/master/packages/react-dev-utils#new-inlinechunkhtmlpluginhtmlwebpackplugin-htmlwebpackplugin-tests-regex


for inline css you need additional rules object:

module.exports = {
  entry: ['./src/style.css', './src/client.js'],
  // ...
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          'style-loader', // Creates `style` nodes from JS strings
          'css-loader', // Translates CSS into CommonJS
        ],
      },
    ],
  },
}
Sign up to request clarification or add additional context in comments.

3 Comments

it does not seem like working for me, it does not seem to inline the js files.
This worked beautifully, but is there a way to add the inline js in the body:
@JonathanDsouza, I think you just inject: 'body'?
6

use https://github.com/DustinJackson/html-webpack-inline-source-plugin

plugins: [
  new HtmlWebpackPlugin({
    inlineSource: '.(js|css)$' // embed all javascript and css inline
  }),
  new HtmlWebpackInlineSourcePlugin()
]  

1 Comment

This doesnt work any more, looks like theres some crappy npm package versioning and compatibility going on, surprise surprise
6

For Webpack 5:

Neither

  • InlineChunkHtmlPlugin from react-dev-utils (due to some obscure error where something was undefined)

nor

  • html-webpack-inline-source-plugin (due to Webpack 5 incompatibility)

worked for me, so i found a different solution that only uses html-webpack-plugin (which is compatible with Webpack 5) and the modification of the template you supply for HtmlWebpackPlugin.

template.html:


<!doctype html>
<html>
    <head>
        <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
        <div id="root"></div>
        <script defer="defer">
            <% /*
            The following line is a workaround for scripts that insert .js code into the generated .html file.
            Because this is set here, "inject: false" is set in webpack-config.js in plugins.HtmlWebpackPlugin
            */ %>
            <%= compilation.assets[webpackConfig.output.filename].source() %>
        </script> 
    </body>
</html>

webpack-config.js:


// ...
// your other webpack-config code
//...
output: {
    filename: 'bundle.js',
    path: "./myOutPath",
},
plugins: [
    new HtmlWebpackPlugin({
      title: "My Web App",
      template: "template.html",
      // this is a workaround for the injection of the code from the output file into the .html
      // the injection will be handled in the template file
      inject: false,
    })
  ],

In this case, only the content of the one output file set in your Webpack config (here: bundle.js) gets injected into the HTML file. But i guess you get the general point.

Comments

0

Adding to @daddaidudu's answer, my build files had hash values, so adding hash to the key worked for me.

<style type="text/css">
    <%= compilation.assets['default.bundle.css?hash=' + compilation.hash].source() %>
</style>

Comments

-1

html-webpack-inline-source-plugin doesn't work anymore, you can use script-ext-html-webpack-plugin instead.

const HtmlWebpackPlugin = require('html-webpack-plugin')
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');

module.exports = {
    entry: {
        index: './src/index.js'
    },
    output: {
        path: __dirname + '/dist',
    },
    plugins: [
        new HtmlWebpackPlugin({
            cache: false
        }),
        new ScriptExtHtmlWebpackPlugin({
            inline: [/\.js$/],
        })
    ]
}

3 Comments

script-ext-html-webpack-plugin has been deprecated by the author and won't have compatibility with webpack 5.
The inline functionally is still working with webpack5.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.