Webpack、sass-loader(或 css-loader)在 node_modules 中嵌套文件导入。文件未找到

Posted

技术标签:

【中文标题】Webpack、sass-loader(或 css-loader)在 node_modules 中嵌套文件导入。文件未找到【英文标题】:Webpack, sass-loader (or css-loader) nested file imports inside node_modules. File not found 【发布时间】:2018-02-12 03:07:47 【问题描述】:

我想使用primercss 框架作为sass。我正在使用 webpack 来构建我的应用程序。我已经下载了 npm 包并使用:@import "~primer-css/index.scss"; 将其导入。问题是构建失败并出现以下错误:File to import not found or unreadable: primer-core/index.scss,这是primer-css/index.scss 文件中的子导入。我认为是webpack sass-loader或者css-loader相关的问题,全栈trace如下:

ERROR in ./node_modules/css-loader?"modules":true,"minimize":true,"sourceMap":true,"importLoaders":2,"localIdentName":"[name]__[local]"!./node_modules/postcss-loader/lib?"config":"path":"/Users/vicaba/Projects/medself/medself-client/development/webpack/postcss.config.js","sourceMap":true!./node_modules/sass-loader/lib/loader.js?"outputStyle":"expanded","sourceMap":true,"sourceMapContents":true!./src/theme/theme.scss
Module build failed:
@import "primer-core/index.scss";
^
      File to import not found or unreadable: primer-core/index.scss.
Parent style sheet: /Users/vicaba/Projects/medself/medself-client/development/node_modules/primer-css/index.scss
      in /Users/vicaba/Projects/medself/medself-client/development/node_modules/primer-css/index.scss (line 14, column 1)
Error:
@import "primer-core/index.scss";
^
      File to import not found or unreadable: primer-core/index.scss.
Parent style sheet: /Users/vicaba/Projects/medself/medself-client/development/node_modules/primer-css/index.scss
      in /Users/vicaba/Projects/medself/medself-client/development/node_modules/primer-css/index.scss (line 14, column 1)
    at options.error (/Users/vicaba/Projects/medself/medself-client/development/node_modules/node-sass/lib/index.js:291:26)
 @ ./src/theme/theme.scss 4:14-200
 @ ./src/bootstrap.js
 @ multi ./src/bootstrap.js

ERROR in ./src/theme/theme.scss
Module build failed: ModuleBuildError: Module build failed:
@import "primer-core/index.scss";
^
      File to import not found or unreadable: primer-core/index.scss.
Parent style sheet: /Users/vicaba/Projects/medself/medself-client/development/node_modules/primer-css/index.scss
      in /Users/vicaba/Projects/medself/medself-client/development/node_modules/primer-css/index.scss (line 14, column 1)
    at runLoaders (/Users/vicaba/Projects/medself/medself-client/development/node_modules/webpack/lib/NormalModule.js:194:19)
    at /Users/vicaba/Projects/medself/medself-client/development/node_modules/loader-runner/lib/LoaderRunner.js:364:11
    at /Users/vicaba/Projects/medself/medself-client/development/node_modules/loader-runner/lib/LoaderRunner.js:230:18
    at context.callback (/Users/vicaba/Projects/medself/medself-client/development/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
    at Object.asyncSassJobQueue.push [as callback] (/Users/vicaba/Projects/medself/medself-client/development/node_modules/sass-loader/lib/loader.js:55:13)
    at Object.<anonymous> (/Users/vicaba/Projects/medself/medself-client/development/node_modules/async/dist/async.js:2244:31)
    at Object.callback (/Users/vicaba/Projects/medself/medself-client/development/node_modules/async/dist/async.js:906:16)
    at options.error (/Users/vicaba/Projects/medself/medself-client/development/node_modules/node-sass/lib/index.js:294:32)

loaders配置如下:


  test: /\.scss$/,
  use: ExtractTextPlugin.extract(
    fallback: 'style-loader',
    use: [
      
        loader: 'css-loader',
        options: 
          modules: true,
          minimize: true,
          sourceMap: true,
          importLoaders: 2,
          localIdentName: '[name]__[local]'
        
      ,
      
        loader: 'postcss-loader',
        options: 
          config: 
            path: path.resolve(__dirname, 'postcss.config.js')
          ,
          sourceMap: true
        
      ,
      
        loader: 'sass-loader',
        options: 
          outputStyle: 'expanded',
          sourceMap: true,
          sourceMapContents: true
        
      
    ]
  )

谁能帮帮我?或者对问题有所了解?

【问题讨论】:

【参考方案1】:

所以我想我应该说这个问题似乎非常没有解决,甚至不清楚是否会解决,因为 sass-loader 官方说没有问题,因为这node-sass 应该如何工作。

如果人们有兴趣阅读官方问题线程,它仍然在 github 上的here 上打开。线程中描述了一些快速的技巧,但没有一个对我有用,尽管它们基本上都做同样的事情,包括 sass-imports 中的 node_modules 文件夹。

他们这样做的原因是因为正如您所描述的,当您有一个看起来像这样的简单文件时:

 @import "~primer-css/index.scss";

这确实依赖于 node_modules 文件夹中的子导入或外部 SASS 文件。具体来说,这些:

/*!
 * Primer
 * http://primer.github.io
 *
 * Released under MIT license. Copyright (c) 2017 GitHub Inc.
 */

// Primer master file
//
// Imports all Primer files in their intended order for easy mass-inclusion.
// Should you need specific files, you can easily use separate `@import`s.

// Global requirements
@import "primer-core/index.scss";
@import "primer-product/index.scss";
@import "primer-marketing/index.scss";

因为这些子导入中没有一个前面有 ~,所以它们没有被解析。

事实上,如果你只是尝试编译primer-support/index.scss,它实际上会开箱即用,因为它的所有导入只依赖于它自己的模块,因此它可以解析:

// variables
@import "./lib/variables/typography.scss";
@import "./lib/variables/colors.scss";
@import "./lib/variables/layout.scss";
@import "./lib/variables/misc.scss";

// mixins
@import "./lib/mixins/typography.scss";
@import "./lib/mixins/layout.scss";
@import "./lib/mixins/buttons.scss";
@import "./lib/mixins/misc.scss";

尽管如此,经过比应该花费更长的时间之后,似乎确实有办法解决这个问题,如commented in this post

   
    test: /\.s?css$/,
    loaders: [
      'css',
      'sass?includePaths[]='+ path.resolve(__dirname, 'node_modules') +
        '&includePaths[]='+ path.resolve(__dirname, 'bower_components')
        // tells sass-loader to look in these dirs when resolving files
    ]
  

我改成了:

        
            test: /\.scss$/,
            use: ExtractTextPlugin.extract(
                fallback: "style-loader",
                use: "css-loader?importLoaders=1!postcss-loader!sass-loader?includePaths[]=" + resolve(__dirname, 'node_modules')
            )
        

因为我只希望它检查 SCSS,而且我希望将我的 CSS 和 SCSS 捆绑并缩小在一起。

但是,这可能对大多数人不起作用,所以我想修复您的代码示例,它看起来像:

     
        loader: 'sass-loader',
        options: 
          config: 
            path: path.resolve(__dirname, 'node_modules')
          ,
          outputStyle: 'expanded',
          sourceMap: true,
          sourceMapContents: true
        
      

但我发现config 相当棘手,所以最终我认为包含它的最简单方法是将加载程序use 修改为:

sass-loader?includePaths[]=" + resolve(__dirname, 'node_modules')

【讨论】:

以上是关于Webpack、sass-loader(或 css-loader)在 node_modules 中嵌套文件导入。文件未找到的主要内容,如果未能解决你的问题,请参考以下文章

css-loader,sass-loader 不工作 webpack 2

Webpack:在 sass-loader、css-loader 上重复导入(模块:true)

webpack sass-loader 未生成 css 文件

Webpack sass-loader 无效的 CSS

Webpack Sass-loader 和 Css-loader 'sourceMap' 选项导致失败

带有 sass-loader、MiniCssExtractPlugin 和 uikit 的 Webpack4