Загрузка определенного компонента из MDL с помощью webpack

#javascript #sass #webpack #material-design-lite #sass-loader

#javascript #sass #webpack #материал-дизайн-облегченный #sass-загрузчик

Вопрос:

Я хочу просто использовать компонент компоновки MDL в своем проекте.

Итак, в моем app.css файле я импортирую это:

@import url('~material-design-lite/src/layout/_layout.scss');

и во время процесса сборки я получаю следующую ошибку:

 ERROR in ./~/css-loader!./~/material-design-lite/src/layout/_layout.scss
Module not found: Error: Cannot resolve 'file' or 'directory' ../variables in /Users/Mitch/Documents/project/web/node_modules/material-design-lite/src/layout
 @ ./~/css-loader!./~/material-design-lite/src/layout/_layout.scss 3:10-66

ERROR in ./~/css-loader!./~/material-design-lite/src/layout/_layout.scss
Module not found: Error: Cannot resolve 'file' or 'directory' ../mixins in /Users/Mitch/Documents/project/web/node_modules/material-design-lite/src/layout
 @ ./~/css-loader!./~/material-design-lite/src/layout/_layout.scss 4:10-63
  

_layout.sccs начинается с этих строк

 @import "../variables";
@import "../mixins";
  

Есть идеи, что я могу делать неправильно?

Соответствующие части моего webpack.config.js :

 const PATHS = {
    node_modules: path.resolve(__dirname, 'node_modules'),
    build: path.join(__dirname, 'public', 'build'),
    js: path.resolve(__dirname, 'public', 'js'),
    css: path.resolve(__dirname, 'public', 'css'),
};

...
resolve: {
    root: [
        path.resolve(__dirname),
        PATHS.node_modules,
        PATHS.js,
        PATHS.css
    ],
    ...
    extensions: ['', '.js', '.jsx', '.json', '.css', '.scss']
},
module: {
    loaders: [
        {
            test: /.css$/,
            loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
        },
        {
            test: /.scss$/,
            loader: ExtractTextPlugin.extract('style', 'css?modules!sass')
        },
        {
            test: /.png$/,
            loader: 'url-loader?limit=100000'
        },
        {
            test: /.jpg$/,
            loader: 'file-loader'
        },
        {
            test: /.gif$/,
            loader: 'file-loader'
        },
        {
            test: /.(woff|woff2)(?v=d .d .d )?$/,
            loader: 'url?limit=10000amp;mimetype=application/font-woff'
        },
        {
            test: /.ttf(?v=d .d .d )?$/,
            loader: 'url?limit=10000amp;mimetype=application/octet-stream'
        },
        {
            test: /.eot(?v=d .d .d )?$/,
            loader: 'file'
        },
        {
            test: /.svg(?v=d .d .d )?$/,
            loader: 'url?limit=10000amp;mimetype=image/svg xml'
        },
        {
            test: /.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
                presets: ['es2015']
            }
        }
    ]
}
...
  

Соответствующие зависимости :

 ...
"devDependencies": {
    "babel-core": "^6.14.0",
    "babel-loader": "^6.2.5",
    "babel-preset-es2015": "^6.14.0",
    "css-loader": "^0.25.0",
    "eslint": "^3.6.1",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.9.0",
    "node-sass": "^3.10.1",
    "sass-loader": "^4.0.2",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "webpack": "^1.13.2",
    "webpack-validator": "^2.2.7"
}
...
  

Обновить

Я попытался @import url('~material-design-lite/src/material-design-lite.scss'); , поскольку это не частичное, после того, как я изменил его, чтобы импортировать только компонент макета.

Теперь я получаю следующие ошибки:

 ERROR in ./~/css-loader!./~/material-design-lite/src/material-design-lite.scss
Module build failed: Unknown word (19:1)

  17 | /* Material Design Lite */
  18 | 
> 19 | // Variables and mixins
     | ^
  20 | @import "variables";
  21 | @import "mixins";
  22 | 

 @ ./~/css-loader!./public/css/app.css 3:10-114
  

В комментариях происходит сбой. Я понятия не имею, как это исправить, я пытался использовать postcss загрузчики postcss-scss и postcss-strip-inline-comments плагин, но безрезультатно; старые ошибки были просто заменены новыми ошибками.

Комментарии:

1. Может ли это быть связано с тем, что файл, который я хочу загрузить, является частичным? Согласно документам: «Частичный — это просто файл Sass с именем с начальным подчеркиванием. Вы можете назвать его чем-то вроде _partial.scss. Подчеркивание позволяет Sass знать, что файл является только частичным файлом и что его не следует создавать в CSS-файл. »

Ответ №1:

Фактическая проблема в вашем примере заключалась в том, что вы импортировали MDL следующим образом

 @import url('~material-design-lite/src/layout/_layout.scss');
  

вместо

 @import '~material-design-lite/src/layout/_layout.scss';
  

Первый игнорируется загрузчиком sass (поскольку у SASS нет импорта url ()) и будет обработан загрузчиком css. Однако css-загрузчик не будет автоматически расширяться .scss variables , например. Вот почему вы получали эти ошибки «Модуль не найден».

Комментарии:

1. Прежде всего: Как, черт возьми, я не подумал об этом, когда мое «решение» делает это и еще кое-что. Как иногда работает мозг.. Спасибо. Однако я кое-что заметил. Учтите, что порядок содержимого в моем app.css файле такой: импорт SASS, импорт CSS, остальная часть CSS, когда я создаю файлы, содержимое моего app.bundle.css файла находится в таком порядке: импорт CSS, импорт SASS, остальная часть CSS. Есть ли какой-либо способ заставить его соблюдать порядок, в котором я импортирую файлы? Потому что с CSS в большинстве случаев важен порядок.

2. Извините, что беспокою вас, но не могли бы вы сказать мне, есть ли способ решить проблему, с которой я сталкиваюсь, когда я следую предложенному вами решению? Y наше решение лучше моего, и я хотел бы его реализовать, за исключением одной вещи

3. Порядок разрешенного импорта должен быть в том же порядке, в котором встречается импорт. Если это не так, может возникнуть другая проблема в вашей настройке. Не могли бы вы привести мне небольшой пример репозитория, который демонстрирует это?

4. Вот так: github.com/mkarajohn/load_order_example . Посмотрите, что читается в первом комментарии внутри app.scss . Когда я его создаю, первый комментарий в моем main.bundle.css начинается с This marks the beginning of other.css rules

5. Эй, Йоханнес, есть ли шанс, что ты можешь проверить репозиторий, который я создал для тебя? Спасибо.

Ответ №2:

Я нашел решение / обходной путь.

Что я сделал, так это то, что я создал custom-mdl.scss файл в своем css/ каталоге, где я просто делаю

@import '~material-design-lite/src/layout/_layout.scss';

и изменил мою точку входа, чтобы она была как

 app : [ 'app.js', 'custom-mdl.scss', 'app.css' ]
  

вместо того, чтобы просто

 app : [ 'app.js', 'app.css' ]
  

Вышеуказанное выполняется нормально, с custom-mdl выводом, предшествующим app.css содержимому в пакете, как и предполагалось.

Обратите внимание, что я также удалил ?modules его из своей ExtractTextPlugin конфигурации, поэтому

ExtractTextPlugin.extract('style', 'css!sass')

вместо

ExtractTextPlugin.extract('style', 'css?modules!sass')

В противном случае имена классов custom-mdl.scss файла будут искажены.