How to use absolute path to import custom scss, when using react + webpack?
Asked Answered
L

7

37

Inside a scss file, I'm trying to import custom, widely used chunk of scss (in a React/SASS/Webpack stack).

So that I can use a shared mixin.

Let's say I'm creating an MyAdminButton and I want to import scss file that concerns all the buttons of the project. (It's custom scss, not vendor/external one).

It would look like this :

//this actually works but it is a code smell : what if the current file moves ?
@import "../../stylesheets/_common-btn-styles.scss";

.my-admin-btn {
    // here I can use a shared mixin defined in _common-btn-styles.scss
}

This sounds not good since if my scss file move, then everything is broken.

Thanks for your help

Libby answered 11/3, 2016 at 10:16 Comment(4)
Because refactoring occurs quite frequently, espescially if I put the scss file next to my js file : put everything that relates to the same component in same folder is very useful.Libby
I have both manual dirty-check and automated tests, but I'm looking for robustness here. I know I will move folder without any fear.Libby
You can use the -I argument to specify an import path. See man scss for more information.Plaid
@Plaid huh? How do you use CLI arguments in code?Paratroops
L
34

Found. Actually you can configure sass-loader in webpack.config.json, as described here : https://github.com/jtangelder/sass-loader

Here is the relevant part :

sassLoader: {
   includePaths: [path.resolve(__dirname, "./some-folder")]
}
Libby answered 11/3, 2016 at 11:36 Comment(3)
Where in the file did you place it? and did absolute path actually work?Paratroops
how i understood, that i should create react app not with npx create-react-app, instead of i should install all packages manual, and set up custom webpack. Only in this case can use it ? Or of i have already created app with create-react-app, can i just create webpack.config.js and use it there ? will it attach to main file a webpack of default react file ? ThxFlay
what would be an example of an absolute path in the actual scss file?Irenics
G
7

If you use Create React App v3 which allows absolute imports you can use the tilde

@import "~theme/colors";
Guesswarp answered 23/9, 2020 at 19:13 Comment(4)
Works also for sass in Angular 11Isaac
Not a real solution unless you are starting a new project using specifically CRA (not recommended anymore).Irenics
@Irenics CRA is indeed outdated, but it works with Next.js as wellGuesswarp
This question is about Webpack and not a specific framework that does inaccessible magic (because it is a framework). People come here because they want to know how to configure their webpack (like me)Irenics
V
4

You could add stylesheets to the Webpack modules with resolve.modules

// webpack.config.js
const path = require('path')

module.exports = {
  // ...
  resolve: {
    modules: [
      'node_modules',
      path.join(__dirname, 'path/to/stylesheets'),
    ],
  },
}

And sass-loader allows you to import _common-btn-styles.scss from the modules. https://webpack.js.org/loaders/sass-loader/#resolving-import-at-rules

@import "~_common-btn-styles.scss";

.my-admin-btn {
  // Use the shared mixins
}
Vevina answered 23/7, 2020 at 1:20 Comment(0)
H
4

Webpack 5

Configuration is different for webpack 5 as includePaths should be specified in the option sassOptions:

// Webpack config
{
  test: /\.scss$/,
  loader: 'sass-loader',
  options: {
    sassOptions: {
      includePaths: [path.resolve(__dirname, '<path to styles>')],
    },
  },
},

Webpack 4

I had to do so more research to solve this issue using other answers so here is my working solution:

// Webpack config
{
  test: /\.scss$/,
  loader: 'sass-loader',
  options: {
    includePaths: [path.resolve(__dirname, '<path to styles>')],
  },
},

Then in your scss file:

@import 'filename.scss'; // Imported from <path to styles> folder.

.style {
  //...
}
Halland answered 4/9, 2020 at 9:21 Comment(0)
S
4

In react-scripts latest version you can add a .env file at the project root with the variable SASS_PATH=node_modules:src.

To specify more directories you can add them to SASS_PATH separated by a : like path1:path2:path3

official doc

Shanna answered 21/5, 2021 at 14:31 Comment(0)
O
2

If using the Dart Sass implementation with sass-loader, the options are slightly different.

The options for sassOptions are here

sassOptions: {
...
  loadPaths: [path.resolve(__dirname, '../src/')],
}
Odessaodetta answered 6/5, 2022 at 16:46 Comment(1)
Already mentioned (by multiple people) here, years before you answeredIrenics
T
1

If you are using NextJS there is a simple implementation. You can read the documentation here.

In my case, I am using Tailwindcss and SASS, and here are the configuration files and sass files.

// next.config.js


const path = require('path');

/** @type {import('next').NextConfig} */
module.exports = {
  experimental: {
    appDir: true,
  },
  sassOptions: {
    // define the absolute path...
    includePaths: [path.join(__dirname, 'styles')],
  },
};

// styles/_components.sass

@import 'tailwindcss/components'

@layer components
  .flex-center
    @apply flex items-center justify-center
  .container
    @apply mx-auto px-3 max-w-xl sm:max-w-lg md:px-6 md:max-w-3xl


// styles/global.sass

@import 'tailwindcss/base'
@import 'tailwindcss/utilities'
@import 'components' // absolute import


// app/styles.module.sass

@import 'components' // absolute import

.header
  @apply container flex h-16 items-center justify-between sticky top-0

Tavie answered 20/1, 2023 at 9:1 Comment(1)
I figured, that if you are using PostCSS, TailwindCSS etc. you don't need to define sassOptions. PostCSS will take care of the paths. For my case, I configured absolute URLs in tsconfig.json, and using the import from its absolute path like: @import 'style/components'Tavie

© 2022 - 2024 — McMap. All rights reserved.