Search code examples
javascriptwebpackcss-loadermini-css-extract-plugin

Create link tag for webpack mini-css-extract-plugin extracted file without HTML


I would like to package a javascript project with webpack 4 and I'm struggling with the CSS file. My bundled JS file will be used by other website using a script tag with an absolute URI. So I want my bundle to inject the link tag for the stylesheet in order to manage the hash in the filename.

My style source is a scss file. It works well when I use the style-loader but I would like to extract the CSS in an other file.

I tried the following webpack.config.js :

const miniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    miniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader']
            }
        ]
    },
    plugins: [
        new miniCssExtractPlugin({
            filename: '[name].[hash].css',
        }),
    ]
};

It creates my CSS file in the output dir, but the loader doesn't inject it in the DOM like the style-loader does. And I can't use style-loader after the mini-css-extract-plugin.

I can't use html-webpack-plugin because there is no HTML output file. Is there a way to do what I want with existing loaders ? Is there a way to get the extracted file url in the JS to create the link tag by myself ?

My devDependencies :

{
  // ...
  "devDependencies": {
    "css-loader": "^3.3.2",
    "mini-css-extract-plugin": "^0.8.0",
    "node-sass": "^4.13.0",
    "sass-loader": "^8.0.0",
    "webpack": "^4.41.3",
    "webpack-cli": "^3.3.10"
  }
}

Thank you.


Solution

  • In fact I was in the wrong direction trying to use mini-css-extract-plugin. It can be achieved simply with this rule :

    {
        test: /\.scss$/,
        use: [
            {
                loader: 'style-loader',
                options: {
                    injectType: 'linkTag'
                }
            },
            {
                loader: 'file-loader',
                options: {
                    name: "css/[name].[hash].css",
                    publicPath: "dist/" // depends on your project architecture
                }
            },
            'sass-loader'
        ]
    }
    

    I will have to add another loader in order to minify I think.