Импорт вложенных файлов Webpack, sass-loader (или css-loader) внутри node_modules. Файл не найден

Я хочу использовать фреймворк Primercss как sass. Я использую webpack для создания своего приложения. Я скачал пакет npm и импортировал его, используя: @import "~primer-css/index.scss";. Проблема в том, что сборка завершается с ошибкой: File to import not found or unreadable: primer-core/index.scss , которая является субимпортом в файле primer-css/index.scss. Я думаю, что это проблема, связанная с sass-loader или css-загрузчиком webpack, трассировка полного стека выглядит следующим образом:

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)

Конфигурация загрузчиков следующая:

{
  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
        }
      }
    ]
  })
}

Может кто-нибудь мне помочь? Или пролить свет на проблему?


person vicaba    schedule 03.09.2017    source источник


Ответы (1)


Поэтому я думаю, что должен сказать, что эта проблема кажется очень нерешенной, и даже не кажется ясным, будет ли она решена, поскольку sass-loader официально заявляет, что проблемы нет, потому что вот как < em>node-sass должен работать.

Если люди заинтересованы в чтении официальной ветки проблемы, она по-прежнему открыта здесь на гитхабе. В ветке описана пара быстрых хаков, но ни один из них не сработал у меня так хорошо, хотя все они в основном делают одно и то же, то есть включают папку node_modules в sass-imports.

Причина, по которой они это делают, заключается в том, что, как вы описали, когда у вас есть простой файл, который выглядит так:

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

Это зависит от вложенного импорта или внешних файлов SASS в папке node_modules. Если быть точным, это:

/*!
 * 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";

Тем не менее, после того, как это заняло гораздо больше времени, чем должно было, похоже, есть способ обойти это, как прокомментировал это сообщение

   {
    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')
person nmu    schedule 29.11.2017