Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't resolve assets file path in SCSS file #10990

Closed
stegano opened this issue May 30, 2020 · 26 comments
Closed

Can't resolve assets file path in SCSS file #10990

stegano opened this issue May 30, 2020 · 26 comments

Comments

@stegano
Copy link
Contributor

stegano commented May 30, 2020

Describe the bug
When importing a file using @import, it seems that there is a problem with the image path of the imported file. The relative path of the file in SCSS should be based on the imported target file, but it doesn't seems to be. (Please see code snippet)

Expected behavior

  • Must search the file path based on the mixins folder path

Code snippets

.storybook/main.js

const path = require('path');
module.exports = {
  stories: ['../src/**/*.stories.tsx'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
  webpack: async config => {
 ...
    config.module.rules.push(
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
        include: path.resolve(__dirname, '../'),
      },
    );
...
    return config;
  },
};

src/index.scss

@import "~src/shared/_mixins";
@include test;

src/shared/_mixin.scss

@mixin test {
  background: url("./images/img.svg"); // << not works, but moving image directory to 'src' work fine.
}

directory

.storybook/
src/
 - index.tsx
 - index.scss
 - shared/
    -_mixin.scss
    - images/
      - img.svg

Output:
ERROR in ./src/index.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js!./src/index.scss)
Module not found: Error: Can't resolve './images/test.svg' in '/Users/test/src/index'

System:

  System:
    OS: macOS High Sierra 10.13.6
    CPU: (4) x64 Intel(R) Core(TM) i5-2500S CPU @ 2.70GHz
  Binaries:
    Node: 10.15.3 - ~/.nvm/versions/node/v10.15.3/bin/node
    npm: 6.12.0 - ~/.nvm/versions/node/v10.15.3/bin/npm
  Browsers:
    Chrome: 83.0.4103.61
    Firefox: 72.0.2
    Safari: 13.1.1
  npmPackages:
    @storybook/addon-actions: ^5.3.19 => 5.3.19 
    @storybook/addon-links: ^5.3.19 => 5.3.19 
    @storybook/addons: ^5.3.19 => 5.3.19 
    @storybook/preset-scss: ^1.0.2 => 1.0.2 
    @storybook/react: ^5.3.19 => 5.3.19 
  npmGlobalPackages:
    @storybook/cli: 5.0.11
    @storybook/react: 5.0.11
@stegano stegano changed the title Can't resolve file path SCSS file Can't resolve assets file path in SCSS file May 30, 2020
@stegano
Copy link
Contributor Author

stegano commented May 30, 2020

I've resolved this issue by referring to the content below.

@stegano stegano closed this as completed May 30, 2020
@PhongVu07
Copy link

@stegano I added resolve-url-loader but couldn't solve the problem, would you mind taking a look?

    newConfig.module.rules.push({
      test: /\.module\.(s*)css$/,
      use: [
        'style-loader',
        {
          loader: 'css-loader',
          options: {
            importLoaders: 1,
            modules: true
          }
        },
        'resolve-url-loader',
        {
          loader: 'sass-loader',
          options: {
            sourceMap: true
          }
        }
      ]
    })

@stegano
Copy link
Contributor Author

stegano commented Jan 4, 2021

Hi @phong10119,
Could you attach your error message that is output?

The settings I've tried are below.
it worked

...
{
    test: /\.scss$/,
    use: [
      'style-loader',
      {
        loader: 'css-loader',
        options: {
          modules: {
            auto: true,
            localIdentName: "[local]--[hash:base64:5]",
          },
        },
      },
      'resolve-url-loader',
      'sass-loader'
    ]
  },
...

@PhongVu07
Copy link

Thank you @stegano, I had to make the import in global.module.scss relative. It works now!

@tult98
Copy link

tult98 commented Jan 4, 2021

Hi, @stegano I'm facing the error exactly the same as you. My config in main.js as below

...
config.module.rules.push({
      test: /\.s[ac]ss$/i,
      use: ['style-loader', 'css-loader', 'resolve-url-loader', 'sass-loader'],
      include: path.resolve(__dirname, '../'),
})

The error output is

Error: Can't resolve '/images/icons/triangle-right.svg' in '/home/tult/RikkeiSoft/pms-frontend/styles/components/elements'

@stegano
Copy link
Contributor Author

stegano commented Jan 5, 2021

Hi, @stegano I'm facing the error exactly the same as you. My config in main.js as below

...
config.module.rules.push({
      test: /\.s[ac]ss$/i,
      use: ['style-loader', 'css-loader', 'resolve-url-loader', 'sass-loader'],
      include: path.resolve(__dirname, '../'),
})

The error output is

Error: Can't resolve '/images/icons/triangle-right.svg' in '/home/tult/RikkeiSoft/pms-frontend/styles/components/elements'

Hi, @lethanhtupk
Could you attach your (s)css file and module path?

@PhongVu07
Copy link

Hi, @stegano I'm facing the error exactly the same as you. My config in main.js as below

...
config.module.rules.push({
      test: /\.s[ac]ss$/i,
      use: ['style-loader', 'css-loader', 'resolve-url-loader', 'sass-loader'],
      include: path.resolve(__dirname, '../'),
})

The error output is

Error: Can't resolve '/images/icons/triangle-right.svg' in '/home/tult/RikkeiSoft/pms-frontend/styles/components/elements'

Seems like you missing this? It's in resolve-url-loader doc

Screen Shot 2021-01-05 at 10 30 01

@stegano
Copy link
Contributor Author

stegano commented Jan 5, 2021

@lethanhtupk
I just checked the output of the added error message and it seems that the image path is not a relative path. Try changing the image path to start with .

@tult98
Copy link

tult98 commented Jan 5, 2021

@phong10119 @stegano thanks for the response
I've tried to put sourceMap option but got the same result
On my scss file. I use background-image with url('/images/icons/triangle-right.svg')

directory

public/ 
  - images/  
      - icons
          .svg files in here
styles/
  - components/ 
      - elements/ 
         - scss files in here

I found that if I changed the path in scss file into ../../../public/images/icon/triangle-right.svg, then bookstory work fine. So I think I need to use resolve-url-loader to change the url into relative path as above but don't know how to do that yet

@stegano
Copy link
Contributor Author

stegano commented Jan 5, 2021

@lethanhtupk
If you want to use absolute path, try using alias feature in webpack.
but, this setting must be applied to both the storybook and the project webpack.

@tult98
Copy link

tult98 commented Jan 5, 2021

@stegano
I don't want to re-config project webpack. Have any solution to use resolve-url-loader to modify the url in scss file to correct it before it being build by storybook?

@stegano
Copy link
Contributor Author

stegano commented Jan 5, 2021

@lethanhtupk Unfortunately, the simplest way I know of is to set an alias for the webpack. 😥

@ajeetshah
Copy link

You can use resolve-url-loader to fix the problem-with-url in one of the following ways:

  1. If you are using inline loaders (e.g. in .storybook/preview.js file):
import '!style-loader!css-loader!resolve-url-loader!sass-loader!../src/styles/my-global-file.scss'

or

  1. If you want to specify the loaders by extending the storybook's webpack config (in .storybook/main.js):
const path = require('path');
module.exports = {
  webpackFinal: async (config, { configType }) => {
    config.module.rules.push({
      test: /\.scss$/,
      use: ['style-loader', 'css-loader', 'resolve-url-loader', 'sass-loader'],
      include: path.resolve(__dirname, '../'),
    });
    return config;
  },
};

@Bruno-Daldegan
Copy link

Bruno-Daldegan commented Jun 8, 2021

Hello @ajeetshah ... which versions of "style-loader, css-loader, resolve-url-loader, sass-loader" worked for you?

@ajeetshah
Copy link

@Bruno-Daldegan

I had solved this (assets file path) issue by using method-1 i.e. import '!style-loader!css-loader!resolve-url-loader!sass-loader!../src/styles/my-global-file.scss' in version 5 of storybook.

After a few months, I upgraded storybook to V6 and found that I no longer needed to use method-1 and I could just write import '../src/styles/my-global-file.scss' in preview.js file (and it would let me resolve assets file paths).

To answer your question, I had style-loader "^1.0.0", css-loader "^3.0.0", resolve-url-loader "^3.1.2" and sass-loader "^10.0.5", in my yarn.lock file, when I was using V5 of storybook. Now, I would simply recommend you to try the latest V6 of Storybook.

PS: I used storybook in a React project built with CRA.

@PFight
Copy link

PFight commented Sep 24, 2021

Found next solution (for css, not scss):

   for (let rule of config.module.rules) {
	if (rule.use && rule.use.length > 0) {
		for (let use of rule.use) {
		  if (use.loader && use.loader.includes("css-loader")) {
			use.options.url = false;
		  }
		}
	}
   }

@jackhkmatthews
Copy link

jackhkmatthews commented Dec 24, 2021

Thanks @PFight , your suggestion helped resolve my path issue (solution below).

I'm using NextJS + SCSS + NextJS public folder for font files + Storybook.

The issue was css-loader was trying to resolve the URL when I needed it left as is.

// .storybook/main.js
module.exports = {
  addons: [
    "@storybook/preset-scss",
  ],
  staticDirs: ["../public"],
  webpackFinal: async (config) => {
    for (let rule of config.module.rules) {
      if (rule.use && rule.use.length > 0) {
        for (let use of rule.use) {
          if (use.loader && use.loader.includes("/css-loader/")) {
            use.options = {
              ...use.options,
              url: (url, resourcePath) => !url.startsWith("/"),
            };
          }
        }
      }
    }
    return config;
  },
};

My erroring SCSS file:

@font-face {
  font-display: optional;
  font-family: "Arial Narrow";
  font-style: normal;
  font-weight: 400;
  src: url("/ArialNarrow.woff2") format("woff2"); // font file is in /public/
}

Error:

ModuleBuildError: Module build failed (from ./node_modules/css-loader/dist/cjs.js):
Error: Can't resolve '/ArialNarrow.woff2' in '/Users/jack.matthews/Development/github/doyoutrackid/next-frontend/styles'

@algomachine007
Copy link

Hi @phong10119, Could you attach your error message that is output?

The settings I've tried are below. it worked

...
{
    test: /\.scss$/,
    use: [
      'style-loader',
      {
        loader: 'css-loader',
        options: {
          modules: {
            auto: true,
            localIdentName: "[local]--[hash:base64:5]",
          },
        },
      },
      'resolve-url-loader',
      'sass-loader'
    ]
  },
...

Hey Stengato, is there a way of using absolute import for asset file in scss?

// absolute imports
$assetPath: "@/assets/vector.png"; (what i want)

// relative imports
$assetPath: "../../../assets"; (wrong)

Your input would be highly appreciated

@stegano
Copy link
Contributor Author

stegano commented Mar 3, 2022

Hi @phong10119, Could you attach your error message that is output?
The settings I've tried are below. it worked

...
{
    test: /\.scss$/,
    use: [
      'style-loader',
      {
        loader: 'css-loader',
        options: {
          modules: {
            auto: true,
            localIdentName: "[local]--[hash:base64:5]",
          },
        },
      },
      'resolve-url-loader',
      'sass-loader'
    ]
  },
...

Hey Stengato, is there a way of using absolute import for asset file in scss?

// absolute imports $assetPath: "@/assets/vector.png"; (what i want)

// relative imports $assetPath: "../../../assets"; (wrong)

Your input would be highly appreciated

Hi @algomachine007
Try using the webpack resolve.alias settings.
https://webpack.js.org/configuration/resolve/

@algomachine007
Copy link

Hey, here are pics, its a next js app and i don't think the app is aware of the webpack config file
Screen Shot 2022-03-03 at 8 40 49 AM
Screen Shot 2022-03-03 at 8 41 18 AM
Screen Shot 2022-03-03 at 8 41 27 AM

@stegano
Copy link
Contributor Author

stegano commented Mar 3, 2022

@algomachine007 Can you show me the next.config.js file you are using?

@algomachine007
Copy link

Yeah, sure

Screen Shot 2022-03-03 at 9 11 07 AM

@stegano
Copy link
Contributor Author

stegano commented Mar 3, 2022

Yeah, sure

Screen Shot 2022-03-03 at 9 11 07 AM

🤔
Can you try this?

module.exports = () => {
  return {
    webpack: (config, { buildId }) => {
      config.resolve = { alias: { images: path.resolve(...) } };
      return config;
    }
  }
}

Set options and restart nextjs

+++

In your Scss/SASS on import use ~ ahead file path.

// some.scss
...
background: url('~image/bg.png');
...

@algomachine007
Copy link

Hey, i've used it but i'm now getting an internal server error
Screen Shot 2022-03-03 at 9 58 33 AM

Screen Shot 2022-03-03 at 10 00 51 AM

Thanks for your help and patience

@stegano
Copy link
Contributor Author

stegano commented Mar 3, 2022

Hey, i've used it but i'm now getting an internal server error Screen Shot 2022-03-03 at 9 58 33 AM

Screen Shot 2022-03-03 at 10 00 51 AM

Thanks for your help and patience

😓
can you like to try again?

// In existing your settings..
module.exports = {
    tailringSlash:true,
    webpackDevMiddleware: (config) => {
        ...
        config.resolve.alias = {
            images: path.resolve(...)
        }
    }
    ...
}

and

// your (s)css file
background: url('~image/bg.png') // <- use `~` ahead file path

@algomachine007
Copy link

// next.config.js
const path = require("path");

module.exports = {
webpack(config, options) {
config.resolve.alias["images"] = path.join(__dirname, "./src/assets");
return config;
},
};

Hey, finally figured it out, wouldn't have been possible without your help, thanks man

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants