如何在sass加载器中从node_modules导入样式表而不使用“~”

11

我正在设置我的Storybook实例,以从我的Rails应用程序中加载样式,但它无法加载我main.scss文件中的导入项,两者都是来自node_modules的样式表:

@import 'react-table/react-table.css';
@import 'animate.css';

当我尝试运行storybook实例时,出现了错误:

ERROR in ./app/javascript/stylesheets/main.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--9-2!./app/javascript/stylesheets/main.scss)
Module not found: Error: Can't resolve './animate.css' in '<my_project>/app/javascript/stylesheets'
 @ ./app/javascript/stylesheets/main.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--9-2!./app/javascript/stylesheets/main.scss) 4:40-111
 @ ./app/javascript/stylesheets/main.scss
 @ ./stories/1-Table.stories.js
 @ ./stories sync ^\.\/(?:(?:(?!\.)(?:(?:(?!(?:|\/)\.).)*?)\/)?(?!\.)(?=.)[^\/]*?\.stories\.js\/?)$
 @ ./.storybook/generated-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/generated-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=true

ERROR in ./app/javascript/stylesheets/main.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--9-2!./app/javascript/stylesheets/main.scss)
Module not found: Error: Can't resolve './react-table/react-table.css' in '<my_project>/app/javascript/stylesheets'
 @ ./app/javascript/stylesheets/main.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--9-2!./app/javascript/stylesheets/main.scss) 3:40-127
 @ ./app/javascript/stylesheets/main.scss
 @ ./stories/1-Table.stories.js
 @ ./stories sync ^\.\/(?:(?:(?!\.)(?:(?:(?!(?:|\/)\.).)*?)\/)?(?!\.)(?=.)[^\/]*?\.stories\.js\/?)$
 @ ./.storybook/generated-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/generated-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=true

这是我工作项目的部分目录:

.
├── .storybook
│   ├── main.js
│   └── preview-head.html
├── app
│   ├── assets
│   │   └── stylesheets
│   │       ├── _base.scss
│   └── javascript
│       ├── packs
│       │   ├── application.js
│       │   └── server_rendering.js
│       └── stylesheets
│           ├── _variables.scss
│           └── main.scss
├── babel.config.js
├── postcss.config.js
├── stories
│   ├── 0-Welcome.stories.js
│   └── 1-Table.stories.js
├── yarn-error.log
└── yarn.lock

以下是我在Storybook的main.js中尝试让sass-loader知道我想要导入文件,而不需要在文件前加上"~"符号,因为Web应用程序无法正确加载样式,所以无法更改我的项目的webpack配置。

const path = require('path')

module.exports = {
  stories: ['../stories/**/*.stories.js'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
  webpackFinal: async config => {
    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader',
        'css-loader',
        {
          loader: 'sass-loader',
          options: {
            includePaths: [
              '../node_modules/animate',
              '../node_modules/react-table'
            ]
          }
        }
      ],
      include: [
        path.resolve(__dirname, '../node_modules'),
        path.resolve(__dirname, '../app/javascript/stylesheets'),
        path.resolve(__dirname, '../app/assets/stylesheets')
      ]
    })
    return config
  }
}

我做错了吗?

2个回答

6
如果您使用的是Webpack 4.x,则只需在Webpack配置文件中添加几个别名,就像这样:
// Your Webpack config file
...

webpackFinal: async config => {
  config.module.resolve.alias = {
    'animate-css': path.resolve(__dirname, '../../../node_modules/animate.css'),
    'react-table': path.resolve(__dirname, '../../../node_modules/react-table-v6/react-table.css'),
  }

  ...
}

然后你可以在你的 main.scss 中导入这些别名:

@import 'animate-css';
@import 'react-table';

你还需要从sass-loader中删除选项。我指定了路径到node_modules,假设它与你的应用程序目录在同一级别上,此外,react-table包不包含CSS文件,所以我指定了v6。


2
类型错误:无法设置未定义的“别名”属性 - Rambatino

0

使用includePaths的完整Webpack 5示例

这是一个完整的示例,不确定为什么includePaths对OP无效,或者是否有其他限制,但它对我起作用了,因为我能够直接从main.scss中使用@use "normalize.css/normalize.css"而不需要使用波浪号。

这将生成包含以下内容的dist/main.css

  • 我们的main.scss
  • node_modules中的normalize.css

两者的效果可以在index.html测试文件中看到。

webpack.config.js

const path = require('path');

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const nodeModulesPath = path.resolve(__dirname, 'node_modules');

module.exports = {
  entry: {
    main: ['./main.scss'],
  },
  mode: 'none',
  module: {
    rules: [
      {
        test: /\.(scss|css)$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: "sass-loader",
            options: {
              sassOptions: {
                includePaths: [nodeModulesPath],
              },
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
  ],
  optimization: {
    minimizer: [
      new CssMinimizerPlugin(),
    ],
    minimize: true,
  }
};

main.scss

@use "normalize.css/normalize.css";

body {
  background-color: red;
}

index.html

<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<title>Sass import</title>
<link rel="stylesheet" href="dist/main.css">
</head>
<body>
<p>Hello</p>
</body>
</html>

package.json

{
  "name": "webpack-cheat",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "build": "webpack",
    "sass": "rm -f dist/main.css && sass main.scss dist/main.css"
  },
  "author": "Ciro Santilli",
  "license": "MIT",
  "devDependencies": {
    "css-loader": "5.2.4",
    "css-minimizer-webpack-plugin": "3.0.2",
    "mini-css-extract-plugin": "2.1.0",
    "normalize.css": "8.0.1",
    "sass": "1.32.11",
    "sass-loader": "11.0.1",
    "style-loader": "2.0.0",
    "webpack": "5.36.1",
    "webpack-cli": "4.6.0",
    "webpack-dev-server": "3.11.2"
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接