9
votes

I have a static site where I am using Vue and Webpack.

I have some global CSS rules in a file called style.css and I am importing them by using import './styles.css' from my index.js file. Additionally, I have some .vue files which generate their own CSS.

To generate the HTML page, I am using html-webpack-plugin.

My CSS rules appear to be applying correctly. However, the <style> tags which contain them are dynamically being added to the <head> of my page via the Javascript that Webpack generates. I would prefer these <style> tags to appear statically in the generated index.html file instead. Is there any way to achieve this?

Additionally, if possible, I would like the CSS to be minified.

This is my webpack configuration file:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
  entry: './index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './index.html',
    }),
    new VueLoaderPlugin()
  ],
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ]
      }
    ]
  },
  mode: 'development'
};
1
I'd say this is an uncommon use case. For development, dynamic style elements are fine. Usually in production, a separate, minified CSS file is used. Why do you need the minified CSS in the HTML file? - Sidney
I was hoping that it would decrease the load time of the website. - Adrian
Optimizing your site is great, but if you haven't actually measured a problem, I would advise you not to prematurely optimize! Dynamically injected styles are fine for most smaller sites anyway. - Sidney
if you care about load time you should use long term caching for most assets, but you never want user to cache index.html. In this approach you want to make index.html as small as possible. - Petr Averyanov

1 Answers

10
votes

Sounds like the exact use case for these html-webpack plugins:

  • html-webpack-inline-source-plugin:

    It allows you to embed javascript and css source inline.

  • style-ext-html-webpack-plugin: an alternative to the previous one.

    If you use HtmlWebpackPlugin and ExtractTextPlugin in your Webpack builds to create HTML <link>s to external stylesheet files, add this plugin to convert the links to `~ elements containing internal (sometimes incorrectly called 'in-line') CSS.

  • html-inline-css-webpack-plugin: an alternative to style-ext-html-webpack-plugin.

    Convert external style sheet(<link rel="stylesheet"/>) to internal style sheet(<style>...<style/>). Require mini-css-extract-plugin and html-webpack-plugin

The last 2 HTML webpack plugins depend on one of the following webpack plugins:

  • Extract Text Plugin:

    Extract text from a bundle, or bundles, into a separate file. [...] It moves all the required *.css modules in entry chunks into a separate CSS file. So your styles are no longer inlined into the JS bundle, but in a separate CSS file (styles.css).

  • mini-css-extract-plugin: same as Extract Text Plugin, but for webpack v4.

    This plugin extracts CSS into separate files.