Material.io Web 出现 webpack 错误 "Can't find stylesheet to import"

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

我尝试将 matrial.io 与 webpack 一起使用,正如 material.io's getting started 中所述,配置如下:

webpack.config.js --> 完全像 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 --> 完全像 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"
    }
}

然而,当我 运行 npm run build 我得到以下错误:

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]

我也试过 gulp 但我遇到了同样的错误。

知道如何让它工作吗?

我还为此创建了一个回购协议。你可以克隆: https://github.com/nazari-dev/material.io

其实,你不服从instruction of getting started with material.io, but if you followed you wouldn't be a success. based on the open issue and some other issues the @material有很多问题。特别是 sass-loader 有问题。当然,我建议你不要使用它并寻求找到更好的解决方案。

但是,对于当前的构建错误,请按照以下步骤成功构建:

  1. 构建自定义导入函数并将其放在 webpack 配置文件的顶部:

    function tryResolve_(url, sourceFilename) {
        try {
            return require.resolve(url, {paths: [path.dirname(sourceFilename)]});
        } catch (e) {
            return '';
        }
    }
    
    function tryResolveScss(url, sourceFilename) {
        const normalizedUrl = url.endsWith('.scss') ? url : `${url}.scss`;
        return tryResolve_(normalizedUrl, sourceFilename) ||
            tryResolve_(path.join(path.dirname(normalizedUrl), `_${path.basename(normalizedUrl)}`),
                sourceFilename);
    }
    
    function materialImporter(url, prev) {
        if (url.startsWith('@material')) {
            const resolved = tryResolveScss(url, prev);
            return {file: resolved || url};
        }
        return {file: url};
    }
    
  2. 更改 webpack 配置文件中的 sass-loader 配置,如下所示:

    {
        loader: 'sass-loader',
        options: {
            importer: materialImporter,
        },
    }
    
  3. 使用以下命令更新 sass npm 包,它应该是 "sass": "^1.26.3":

    npm update sass
    
  4. app.scss 文件中删除 ~。因为我们使用了我们的服装导入器功能,所以这个代字号无法通过我们的新导入器功能来解析。然后直接导入 _mixins.scss 部分文件。所以我们有:

    @use "@material/ripple/mixins";
    
  5. 而不是通过 ripple.surface 包含 surface 您应该直接从 mixins 部分文件导入它。我不知道为什么 example write it like @include ripple.surface; and import the ripple from @use "@material/ripple";! because of the _ripple.scssfile doesn't exist and accordingly the surface doesn't exist too. I read the @use doc of sass and understand the @use could be used when the sass file existed, so I think importing like this example is not for a use-case like your re-production.

    @include mixins.mdc-ripple-surface;
    
  6. 最后,您的 app.scss 文件应该如下所示:

    @use "@material/ripple/mixins";
    
    .test {
      @include mixins.mdc-ripple-surface;
      @include mixins.mdc-ripple-radius-bounded;
    }
    

最终,npm run build命令运行成功。

我正在以不同的心态和更少的步骤添加备选答案,这样:

  1. 我只是将 sasssass-loader 以及 material-components-web 更新到最新版本。所以在本次更新结束时,您的 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.26.3",
        "sass-loader": "^8.0.2",
        "webpack": "^4.42.0",
        "webpack-cli": "^3.3.11"
      },
      "dependencies": {
        "material-components-web": "^5.1.0"
      }
    }
    
  2. 然后在 app.scss 文件中使用 mixins,如下所示:

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

然后通过npm run build命令构建成功,事实上,你错过了匹配最新版本的sasssass-loadermaterial-components-web,那么你使用了最新的文档,它们之间存在一些冲突,这会导致你的错误。

,在第二个解决方案中,我看到了一件奇怪的事情,当我写 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 时,解析器 无法 看到里面的 _index.scss node_modules/@material/ripple 文件夹,毫无疑问,它来自 ripple 模块的 package.json 。因为在 ripple 模块的 package.json 里面有 "main": "dist/mdc.ripple.js""module": "index.js" 不知道作者为什么声明它,我们被迫使用 @use "~@material/ripple/index"; 只是为了这个声明。

我离开 an issue 因为这个奇怪的事情。