mizdra / happy-css-modules

Typed, definition jumpable CSS Modules. Moreover, easy!
MIT License
246 stars 7 forks source link

Not working webpackResolveAlias with next.js #232

Open yuki153 opened 10 months ago

yuki153 commented 10 months ago

Hello, thank you for the great tool. I had a question about this tool and created this issue.

Link to the code that reproduces this issue

https://github.com/yuki153/test-hcm-with-nextjs

To Reproduce

  1. clone repository (yuki153/test-hcm-with-nextjs)
  2. npm run hcm

※ The code for reproduction uses next.js v14.0.4(latest) but, other version (e.g. v12.0.4) also reproduces.

Problem description

Path resolution of next.js succeed, but happy-css-module only fail to resolve path.

Below code that uses alias path at @use fail to path resolve, so d.ts file also doesn't make. But commented out code that does not use alias succeed to make d.ts file.

// @use "../../src/styles/shared.module.scss" as shared;
@use "~/styles/shared.module.scss" as shared;

.headline {
    font-size: 24px;
    color: shared.$accentColor3;
}

Value of webpackResolveAlias is {"~": "../../src"}. Am I mistaken about how to use this alias option?

Error log

~/p/test-hcm-with-nextjs ❯❯❯ npm run hcm                               ✘ 1 

> test-hcm-with-nextjs@0.1.0 hcm
> hcm 'src/**/*.module.scss' --webpackResolveAlias='{"~": "../../src"}'

[info] Generate .d.ts for src/**/*.module.scss...
`import sass from 'sass'` is deprecated.
Please use `import * as sass from 'sass'` instead.
AggregateError: Failed to process files
    at processAllFiles (file:///Users/user-name/private_git/test-hcm-with-nextjs/node_modules/happy-css-modules/dist/runner.js:90:19)
    at async run (file:///Users/user-name/private_git/test-hcm-with-nextjs/node_modules/happy-css-modules/dist/runner.js:95:9) {
  [errors]: [
    Error: Could not resolve '~/styles/shared.module.scss' in '/Users/user-name/private_git/test-hcm-with-nextjs/src/styles/test2.module.scss'.
      ╷
    3 │ @use "~/styles/shared.module.scss" as shared;
      │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      ╵
      src/styles/test2.module.scss 3:1  root stylesheet
mizdra commented 5 months ago

@yuki153 Thanks for reporting the issue!

happy-css-modules resolves ~foo to node_modules/foo by default. Perhaps the resolve mechanism is taking precedence over resolve.alias.

https://github.com/mizdra/happy-css-modules/blob/1c05ec87098cfcb302ec2a13737cc6c07a83b64a/packages/happy-css-modules/src/resolver/webpack-resolver.ts#L92-L97

https://github.com/mizdra/happy-css-modules/blob/bf035f3e000667bdc2a64f11767bdf2c3e610507/packages/happy-css-modules/src/resolver/webpack-resolver.test.ts#L24-L32

I think the problem will be solved if resolve.alias takes precedence over ~ resolve. However, I am not sure if it is compatible with css-loader, scss-loader, and less-loader.

happy-css-modules mimics the resolve mechanism of existing tools to avoid compatibility issues. So I think we need to investigate the precedence order of the resolve mechanism in css-loader, scss-loader, and less-loader.

mizdra commented 5 months ago

As a workaround, you can use @ instead of ~ for alias.

Also, you should use --webpackResolveAlias='{\"@\": \". /... /src\"}' instead of --webpackResolveAlias='{\"@\": \"src\"}'. The alias should be relative to the directory where happy-css-modules is executed.

// test2.module.scss
@use "@/styles/shared.module.scss" as shared;

.headline {
    font-size: 24px;
    color: shared.$accentColor3;
}
{
  // ...
  "scripts": {
    // ...
    "hcm": "hcm 'src/**/*.module.scss' --webpackResolveAlias='{\"@\": \"src\"}'"
  },
  // ...
}