Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import stylesheets from node_modules in sass loader without "~"

I'm setting up my Storybook instance to load the styles from my Rails app but it failed to load the imports within my main.scss file, both are stylesheets from node_modules:

@import 'react-table/react-table.css';
@import 'animate.css';

I received errors when I try to run my storybook instance:

ERROR in ./app/javascript/stylesheets/main.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--9-2!./app/javascript/stylesheets/main.scss)
Module not found: Error: Can't resolve './animate.css' in '<my_project>/app/javascript/stylesheets'
 @ ./app/javascript/stylesheets/main.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--9-2!./app/javascript/stylesheets/main.scss) 4:40-111
 @ ./app/javascript/stylesheets/main.scss
 @ ./stories/1-Table.stories.js
 @ ./stories sync ^\.\/(?:(?:(?!\.)(?:(?:(?!(?:|\/)\.).)*?)\/)?(?!\.)(?=.)[^\/]*?\.stories\.js\/?)$
 @ ./.storybook/generated-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/generated-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=true

ERROR in ./app/javascript/stylesheets/main.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--9-2!./app/javascript/stylesheets/main.scss)
Module not found: Error: Can't resolve './react-table/react-table.css' in '<my_project>/app/javascript/stylesheets'
 @ ./app/javascript/stylesheets/main.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--9-2!./app/javascript/stylesheets/main.scss) 3:40-127
 @ ./app/javascript/stylesheets/main.scss
 @ ./stories/1-Table.stories.js
 @ ./stories sync ^\.\/(?:(?:(?!\.)(?:(?:(?!(?:|\/)\.).)*?)\/)?(?!\.)(?=.)[^\/]*?\.stories\.js\/?)$
 @ ./.storybook/generated-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/generated-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=true

This is the directory of part of my working project:

.
├── .storybook
│   ├── main.js
│   └── preview-head.html
├── app
│   ├── assets
│   │   └── stylesheets
│   │       ├── _base.scss
│   └── javascript
│       ├── packs
│       │   ├── application.js
│       │   └── server_rendering.js
│       └── stylesheets
│           ├── _variables.scss
│           └── main.scss
├── babel.config.js
├── postcss.config.js
├── stories
│   ├── 0-Welcome.stories.js
│   └── 1-Table.stories.js
├── yarn-error.log
└── yarn.lock

And this is my attempt in my Storybook's main.js to let sass-loader know I want to import the files without putting the "~" sign as the web app side will not load the styles correctly so it's not an option to change the webpack config of my project.

const path = require('path')

module.exports = {
  stories: ['../stories/**/*.stories.js'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
  webpackFinal: async config => {
    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader',
        'css-loader',
        {
          loader: 'sass-loader',
          options: {
            includePaths: [
              '../node_modules/animate',
              '../node_modules/react-table'
            ]
          }
        }
      ],
      include: [
        path.resolve(__dirname, '../node_modules'),
        path.resolve(__dirname, '../app/javascript/stylesheets'),
        path.resolve(__dirname, '../app/assets/stylesheets')
      ]
    })
    return config
  }
}

Am I doing it wrongly?

like image 321
nayiaw Avatar asked Feb 28 '20 04:02

nayiaw


People also ask

Is sass loader deprecated?

'node-sass' usage is deprecated and will be removed in a future major version. To opt-out of the deprecated behaviour and start using 'sass' uninstall 'node-sass'.

How do I import a CSS file into a node module?

Use an absolute path to import a CSS file from node_modules in React, e.g. import 'bootstrap/dist/css/bootstrap. min. css' . Make sure you have the specific package installed, omit the node_modules directory and start with the package name.

How do I import a CSS file into SCSS?

It is now possible to import css files directly into your sass file. The following PR in github solves the issue. The syntax is the same as now - @import "your/path/to/the/file" , without an extension after the file name. This will import your file directly.

Does sass loader require node sass?

node. js - Sass-loader requires node-sass >=4 even if that exist - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.


1 Answers

If you are using Webpack 4.x, then all that you need is to add a couple of aliases in your Webpack config file like this:

// Your Webpack config file
...

webpackFinal: async config => {
  config.module.resolve.alias = {
    'animate-css': path.resolve(__dirname, '../../../node_modules/animate.css'),
    'react-table': path.resolve(__dirname, '../../../node_modules/react-table-v6/react-table.css'),
  }

  ...
}

and then you can import these aliases in your main.scss:

@import 'animate-css';
@import 'react-table';

You also need to remove options from your sass-loader. I specified paths to node_modules assuming it is on the same level as your app directory, also package react-table contains no CSS file, so I specified v6.

like image 188
dajnz Avatar answered Oct 30 '22 05:10

dajnz