Search code examples
javascriptwebpacksassgatsbyhead

How do i include only one CSS file in the html head when I import multiple .scss files?


My websites have a structure that looks kind of like

src/
    components/
        Footer/
            index.jsx
            style.scss
        Header/
            index.jsx
            style.scss
        Navbar/
            index.jsx
            style.scss
...

In each of my index.jsx files, I have import './style.scss' in it.

In a Gatsby website I developed recently, I can only see one style tag in the head, even though I probably have a couple dozen components containing import ./style.scss.

enter image description here

I am now developing a non-Gatsby, React & Webpack website, using the same method when my components contain import ./style.scss a lot of the time, but it looks like there is a style tag for every imported style file.

enter image description here

I'm wondering what Gatsby does, and how I can include the same sort of functionality in my non-Gatsby website


Solution

  • This work is done by webpack, not by Gatsby. Of course, Gatsby extends from a custom implementation but you can import the same behavior into another project by adding a custom webpack configuration (as you can do in Gatsby as well).

    webpack bundles all JavaScript, JSON, and CSS (by default does not support SCSS, it should be achieved by adding a custom webpack's configuration or via plugins) file using a code-splitting technique. This allows you to divide your code across a few bundles that are loaded as needed or as requested.

    In addition, one thing that may work for you, is to use major files to collect some imports. Given:

    src/
        components/
            Footer/
                index.jsx
                style.scss
            Header/
                index.jsx
                style.scss
            Navbar/
                index.jsx
                style.scss
    

    You can create under /src/styles a file called styles.scss and:

    @import 'components/Footer/style';
    @import 'components/Header/style';
    @import 'components/Navbar/style';
    

    Then import the file in the top-level component that contains the other ones.


    Update:

    The warnings that you are talking about are due to a wrong importation order in styles. There are not important since webpack chunks all those styles but they create a warning. There a property called ignoreOrder (set by default as false). You can fix it by:

    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    module.exports = {
      plugins: [
        new MiniCssExtractPlugin({
          ignoreOrder: true, // here
        }),
      ],
      module: {
        rules: [
          {
            test: /\.css$/i,
            use: [MiniCssExtractPlugin.loader, 'css-loader'],
          },
        ],
      },
    };