Inline JavaScript and CSS with webpack
Asked Answered
S

5

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'
};
Swamp answered 18/9, 2016 at 8:14 Comment(2)
Did you find a solution?Sinistrorse
I'm using grunt-processhtml github.com/dciccale/grunt-processhtml to solve that.Swamp
I
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()
]  
Interrogatory answered 24/7, 2017 at 9:3 Comment(1)
This doesnt work any more, looks like theres some crappy npm package versioning and compatibility going on, surprise surpriseDianadiandra
G
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
        ],
      },
    ],
  },
}
Grade answered 9/1, 2021 at 20:47 Comment(3)
it does not seem like working for me, it does not seem to inline the js files.Syndicate
This worked beautifully, but is there a way to add the inline js in the body:Stereotyped
@JonathanDsouza, I think you just inject: 'body'?Ergonomics
I
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()
]  
Interrogatory answered 24/7, 2017 at 9:3 Comment(1)
This doesnt work any more, looks like theres some crappy npm package versioning and compatibility going on, surprise surpriseDianadiandra
T
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.

Tim answered 12/10, 2022 at 16:29 Comment(0)
J
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>
Jurisprudence answered 14/11, 2022 at 9:42 Comment(0)
A
-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$/],
        })
    ]
}
Ante answered 28/10, 2020 at 14:35 Comment(3)
script-ext-html-webpack-plugin has been deprecated by the author and won't have compatibility with webpack 5.Endbrain
The inline functionally is still working with webpack5.Gathering
Doesn't work with html-webpack-plugin: "5" github.com/numical/script-ext-html-webpack-plugin/blob/master/…Groupie

© 2022 - 2024 — McMap. All rights reserved.