Search code examples
webpacksassmaterial-components-web

Material.io web with webpack error "Can't find stylesheet to import"


I tried using matrial.io with webpack, just as described in material.io's getting started with the following configurations:

webpack.config.js --> exactly like example

const autoprefixer = require('autoprefixer');

module.exports = {
    entry: ['./app.scss'],
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: 'bundle.css',
                        },
                    },
                    {loader: 'extract-loader'},
                    {loader: 'css-loader'},
                    {
                        loader: 'postcss-loader',
                        options: {
                            plugins: () => [autoprefixer()]
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sassOptions: {
                                implementation: require('sass'),
                                includePaths: ['./node_modules'],
                            },
                        },
                    }
                ],
            },
        ],
    },
};

app.scss --> exactly like the example

@use "~@material/ripple";

.test {
  @include ripple.surface;
  @include ripple.radius-bounded;
  @include ripple.states;
}

package.json

{
    "private": true,
    "scripts": {
        "build": "webpack --config=webpack.config.js"
    },
    "devDependencies": {
        "autoprefixer": "^9.7.4",
        "css-loader": "^3.4.2",
        "extract-loader": "^5.0.1",
        "file-loader": "^6.0.0",
        "postcss-loader": "^3.0.0",
        "sass": "^1.15.2",
        "sass-loader": "^7.1.0",
        "webpack": "^4.42.0",
        "webpack-cli": "^3.3.11"
    },
    "dependencies": {
        "material-components-web": "^4.0.0"
    }
}

However, when I run npm run build I get the following error:

ERROR in ./app.scss
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):

@use "~@material/ripple";
^
      Can't find stylesheet to import.
  ╷
1 │ @use "~@material/ripple";
  │ ^^^^^^^^^^^^^^^^^^^^^^^^
  ╵
  stdin 1:1  root stylesheet
      in /path-to-file/app.scss (line 1, column 1)
 @ multi ./app.scss main[0]

I also tried gulp but I was getting the same error.

Any idea how I can make it work?

I also created a repo for that. You can clone: https://github.com/nazari-dev/material.io


Solution

  • I'm adding an alternative answer with a different mindset and fewer steps, in this way:

    1. I just update sass and sass-loader and definitely material-components-web to the latest versions. so at the end of this update, your package.json is like below:

      {
        "private": true,
        "scripts": {
          "build": "webpack --config=webpack.config.js"
        },
        "devDependencies": {
          "autoprefixer": "^9.7.4",
          "css-loader": "^3.4.2",
          "extract-loader": "^5.0.1",
          "file-loader": "^6.0.0",
          "postcss-loader": "^3.0.0",
          "sass": "^1.26.3",
          "sass-loader": "^8.0.2",
          "webpack": "^4.42.0",
          "webpack-cli": "^3.3.11"
        },
        "dependencies": {
          "material-components-web": "^5.1.0"
        }
      }
      
    2. Then in the app.scss file use mixins like following:

      @use "~@material/ripple/index";
      
      .test {
        @include index.surface;
        @include index.radius-bounded;
        @include index.states;
      }
      

    Then by the npm run build command you have a successful build, in fact, you missed match the latest versions of sass, sass-loader and material-components-web, then you used the latest docs and they have some conflicts with each other and this causes to your error.

    🤔, In this second solution, I saw a weird thing, when I write the example exactly look like the given link the @use '@material/button'; works well and the parser could see the _index.scss inside the node_modules/@material/button folder. but when I switch to your need, I mean @use "@material/ripple"; exactly like this link, the parser couldn't see the _index.scss inside the node_modules/@material/ripple folder and undoubtedly, it comes from the package.json of the ripple module. because in the package.json of ripple module there is "main": "dist/mdc.ripple.js" and "module": "index.js" which I don't know why the author declares it, we're forced to use @use "~@material/ripple/index"; just for this declarations.

    I leave an issue for this weird thing.