Material-components-web: Error "module build failed" when importing with @angular/cli

Created on 20 Jul 2017  路  12Comments  路  Source: material-components/material-components-web

What MDC-Web Version are you using?

0.3.10

What browser(s) is this bug affecting?

All

What OS are you using?

Linux (Fedora 23), Node v6.11.0, npm v5.2.0

What are the steps to reproduce the bug?

Start an @angular/cli project, install for instance @material/select, and add following to styles.scss.

@import '~@material/select/mdc-select';

Run project with npm start

What is the expected behavior?

It should compile fine.

What is the actual behavior?

The following error is output:

ERROR in ./~/css-loader?{"sourceMap":false,"importLoaders":1}!./~/postcss-loader?{"ident":"postcss"}!./~/@angular/cli/~/sass-loader/lib/loader.js?{"sourceMap":false,"precision":8,"includePaths":[]}!./src/styles.scss
Module build failed: 
@import "@material/animation/functions";
^
      File to import not found or unreadable: @material/animation/functions.
Parent style sheet: /workspace/WISTWFU/wist-wfu-app/frontend/frontend-js/node_modules/@material/select/mdc-select.scss
      in /workspace/WISTWFU/wist-wfu-app/frontend/frontend-js/node_modules/@material/select/mdc-select.scss (line 17, column 1)
 @ ./src/styles.scss 4:14-215
 @ multi ./~/primeng/resources/primeng.min.css ./src/styles.scss
webpack: Failed to compile.

Any other information you believe would be useful?

A simple modification of the mdc-select.scss file makes it possible to import it correctly: Simply adding ~ to the package imports.

@import "~@material/animation/functions";
@import "~@material/typography/mixins";
@import "~@material/theme/mixins";
@import "~@material/rtl/mixins";

However I'm hesitant to submit my own pull request, since it would impact every component package.

Most helpful comment

@yeelan0319 unfortunately this does not solve the problem for me, as I am using Angular CLI :cry: And that is actually what this issue is about.

Regarding the documentation: IMHO it's missing specific information about how to configure Webpack. This seems to be exactly the line I mentioned from material-components' own webpack.config.js file; modified for end-users I guess it would be something like:

includePaths: glob.sync('node_modules/@material/*').map((d) => path.join(__dirname, d))

Why not include that directly in the README, instead of just a vague statement that node_modules needs to be in the Sass include path?

Likewise for people using node-sass directly - IMHO it would be much more helpful to have a concrete code snippet.

All 12 comments

Looks like this is a known issue with sass-loader: https://github.com/webpack-contrib/sass-loader/issues/466

What I don't understand is how the material-component authors expect the packages to be consumed? There are no directions for how to do the imports or configure webpack, other than the demo server, which seems to get around the issue by specifying includePaths: glob.sync('packages/*/node_modules').map((d) => path.join(__dirname, d)) in the sass-loader options in webpack.config.js. Apparently eyeglass is the only tool that supports scoped packages in import statements as-is, as provided by material-components. Is it the recommendation to use eyeglass, or if using webpack to always add the material modules to the sass-loader includePaths (although, it should be kept in mind that @angular/cli users will still be left out in the cold)? This needs at the very least some documentation.

Hi @mischkl ,

To import SCSS files, you need to specify in webpack that node_modules are in the includePaths, as we documented here

Could you verify if this solve you problem? You may also refer to our previous issues regarding this problem. #692 #847

@yeelan0319 unfortunately this does not solve the problem for me, as I am using Angular CLI :cry: And that is actually what this issue is about.

Regarding the documentation: IMHO it's missing specific information about how to configure Webpack. This seems to be exactly the line I mentioned from material-components' own webpack.config.js file; modified for end-users I guess it would be something like:

includePaths: glob.sync('node_modules/@material/*').map((d) => path.join(__dirname, d))

Why not include that directly in the README, instead of just a vague statement that node_modules needs to be in the Sass include path?

Likewise for people using node-sass directly - IMHO it would be much more helpful to have a concrete code snippet.

good point @mischkl. I also think the README should be more precise. Unfortunately your guess doesn't work either. To make it up and running you have to try something like that:

includePaths: glob.sync('node_modules').map((d) => path.join(__dirname, d))

Havret's suggestion is how we use it in our toolchain. Try that and see if it works.

Again as mentioned in the description, I can't try the suggestion using an angular-cli project. Perhaps there is a way but it's not documented. I guess no one seems to care because Angular users by and large will choose angular-material components. But it still doesn't make this issue any more fixed.

It's not that no one cares, it's that it is not _really_ a thing that is broken in MDC Web. I did a quick google search to see if anyone else was running into a similar issue, and the method used in the second to last comment in this thread appears to have worked for that user.

Anything past that I think you'll have better luck on Stack Overflow or asking the folks over at Angular CLI

If you look carefully at that last suggestion it means that every individual package path has to be added to the config, and there's no possibility to use one of the MDC Web group packages since they won't be able to resolve their dependencies. So not only does every component need to be added and versioned individually but also added and maintained individually in the angular-cli config. And as far as I can tell there's no benefit to doing this over using it the ~ syntax for each individual package, other than supposed convenience. The problem of not being able to consume the primary grouped package remains.

I have some trouble accepting the answer that "it's not really an MDC Web problem" because I honestly can't tell what kind of setup you're expecting people to use that actually works? Node-sass or original ruby sass plus some dependency resolving plugin? eyeglass? Or are you attempting to target webpack in a roundabout way? if so I'd say that the problem is the sass-loader plug-in. but without having a "reference build setup" to compare the behavior with I can't say.

Hey @mischkl, our recommendation would be to just use the MDC libraries listed on our README built specifically for Angular, i.e. Angular MDC or Blox Material. MDC Web is a foundational library designed to be extended for use in other JS frameworks, so that developers will use the MDC library specific to their framework.

Thanks for the tip. Looking at the Blox Material getting started guide, it seems the magic solution is simply to add the following to the .angular.cli.jsonfile:

"stylePreprocessorOptions": {
        "includePaths": [
          "../node_modules"
        ]
      }

I'll try testing this and posting the result tomorrow. If it turns out to work it might be nice for you to add that to your documentation, as it would seem the mentioned libraries are completely optional and only add a bit more convenience.

This one worked for me on Angular 7.x:

 "stylePreprocessorOptions": {
        "includePaths": [
         "node_modules"
        ]
     }

You must nclude the same stylePreprocessorOptions on projects.yourProjectName.architect.build.options and projects.YourProjectName.test.options.

Guys, i love that feeling. Day wasted, but solution is found

Was this page helpful?
0 / 5 - 0 ratings

Related issues

abhiomkar picture abhiomkar  路  3Comments

traviskaufman picture traviskaufman  路  3Comments

ghost picture ghost  路  3Comments

cintaccs picture cintaccs  路  3Comments

devshekhawat picture devshekhawat  路  3Comments