4

Lets say I'd like to import some stylesheets from a node module in my main app.scss:

@import '~bootstrap/scss/bootstrap';

This will be correctly resolved by PhpStorm, and built by Nuxt.js as well, all good.

Now if I want to do the same for a scoped node module (a node module with a name in the format of @scope/module) Nuxt.js and PhpStorm diverges:

  • @import '@fortawesome/fontawesome-svg-core/styles.css';

    This works fine in Nuxt.js, build goes on without issues, but PhpStorm underlines the whole thing saying Cannot resolve directory '@fortawesome'

  • @import '~@fortawesome/fontawesome-svg-core/styles.css';

    This is understood by PhpStorm and can be resolved just fine, however causes Nuxt.js build to fail with:

ERROR in ./client/assets/sass/app.scss
Module build failed (from ./node_modules/extract-css-chunks-webpack-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/src/index.js):
Error: Can't resolve '~@fortawesome/fontawesome-svg-core/styles.css'

So my question is: Which syntax would be considered correct, and is it possible to make both PhpStorm and Nuxt.js happy at the same time?

For me the ~@ seems to make more sense, as ~ resolves to the path of my node_modules and the actual folder name in there starts with a @. Using only @ kind of breaks the pattern compared to non-scoped node modules, for which ~ prefix is needed according to both PhpStorm and Nuxt.js.

Bence Szalai
  • 768
  • 8
  • 20

2 Answers2

4

Turns out, the issue is caused by the .css extension.

This works fine for both PhpStorm and Nuxt.js: @import '~@fortawesome/fontawesome-svg-core/styles';

Apparently (according to this answer and/or this issue) when the .css extension is used for the @import statement, sass-loader would not really import the given file, but rather translate it into @import url('~@fortawesome/fontawesome-svg-core/styles.css') statement, which is indeed wrong, as url() cannot resolve the ~ properly.

So after all there is significant difference between these two subtly different SASS lines:

  • @import '@fortawesome/fontawesome-svg-core/styles.css';

    This results in @import url('@fortawesome/fontawesome-svg-core/styles.css'), which is up to webpack to resolve later in the build process. Or if not resolved by webpack, it may be sent to the browser where it would fail for sure.

  • @import '~@fortawesome/fontawesome-svg-core/styles';

    This is resolved by sass-loader and node_modules/@fortawesome/fontawesome-svg-core/styles.css is imported into the main style file leaving nothing to be resolved later in the build process (or in the browser for that matter).


PS: also I've realised it has nothing to do with the given node modules being scoped or not. It all comes down to importing .scss vs .css.

Bence Szalai
  • 768
  • 8
  • 20
  • 1
    Apparently Nuxt.js includes the given `styles.css` file as inline in the final `app.*.css` file in both cases. My assumption is that in the first case `@import '@fortawesome/fontawesome-svg-core/styles.css';` results in `@import url('@fortawesome/fontawesome-svg-core/styles.css')` which in turn inlined by webpack at some point, so both works from the build perspective, but it seems to be more like another loader or mechanism after `sass-loader` fixes the messed up `@import url()` part, so the 2nd one still seems to be cleaner solution. But these are just assumptions. Correct me, if I'm wrong! – Bence Szalai Aug 20 '20 at 12:03
0

It's also possible to click right button and Mark directory as → Source root

enter image description here

Londeren
  • 3,202
  • 25
  • 26