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

feat: implement regExp option #17

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

lohfu
Copy link

@lohfu lohfu commented Jul 19, 2022

this PR adds a regExp option that is passed to loaderUtils.interpolateName. This option is called localIdentRegExp in webpack.

@lohfu
Copy link
Author

lohfu commented Aug 12, 2022

@longlho @alexander-akait any chance of getting this considered?

@alexander-akait
Copy link
Member

Hello, can you clarify why you need it (example)?

@lohfu
Copy link
Author

lohfu commented Dec 3, 2022

hey sorry for the quick reply, hope i'm not spamming.

i use it mainly through the localIdentRegExp option from css-loader in projects where the css module files are named *.module.s?css to remove module from the resulting class name. for example i often have:

modules: {
  localIdentName: '[1]_[local]',
  localIdentRegExp: /([^/]*).module.s?css/,
},

this results in names like navigation_base instead of navigation-module_base.

projects with SSR use tools (eg babel-plugin-css-modules-transform) that depend more directly on generic-names and only have generateScopedName exposed. to solve the problem in those cases i create a function

export default function generateScopedName(name, path) {
  const parsed = p.parse(path)
  const filename = parsed.name.replace('.module', '')

  return `${filename}__${name}`
}

which i then use in babel.config.js

plugins: [
  [
    'css-modules-transform',
    {
      generateScopedName,
      extensions: ['.scss'],
      processorOpts: { parser: scssParser },
    },
  ],
],

and in webpack.config.js

modules: {
  getLocalIdent: (loaderContext, _localIdentName, localName) =>
    generateScopedName(localName, loaderContext.resourcePath),
},

it would be nice to be able to use the regex option in both cases and avoid having to create the function to share between the contexts.

@alexander-akait
Copy link
Member

I think we don't need it here, I think pre/post processing in css-loader should help here, regexp is limited, with function notation you will have more power and it allows to solve more problems (like this)

@alexander-akait
Copy link
Member

So we can add new options beforeGetLocalIdent and afterGetLocalIdent

@lohfu
Copy link
Author

lohfu commented Dec 5, 2022

I agree function notation is more powerful, but regex is considerably more concise for simple solutions. This PR doesnt really add any logic to this library, it simply exposes an already existing API from loader-utils/lib/interpolateName.js. I also figured there could be some value in having the same functionality in this library as in webpack.config.js.

Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update docs, otherwise it will be PR only for you and me and nobody will know how to use it 😄

@pstrh
Copy link

pstrh commented Nov 21, 2023

@alexander-akait @lohfu It would be great if this PR gets merged. I would be willing to update the docs in another PR if there's a chance to get this merged.

@pstrh
Copy link

pstrh commented Nov 23, 2023

@sapphi-red @madyankin I would like to make you aware of this PR. It would be great if the regExp option would be added subsequently to postcss-modules and Vite. Is there a chance that this gets added? It would allow to interpolate the component name without the -module suffix. I could try to contribute respective PRs to both projects.

Currently if your scss file in Vite is MyComponent.module.scss and generateScopedName: "[name]_[local]__[hash:base64:5]" it resolves to MyComponent-module_LocalName_Hash. With the regExp option it would be possible to get rid of the -module suffix via generateScopedName: "[1]_[local]__[hash:base64:5]" and regExp: /([^/]*).module.s?css/. At the moment we have to implement our own generateScopedName function to achieve this.

@sapphi-red
Copy link

@pstrh I think that's possible by using the function type generateScopedName.

@pstrh
Copy link

pstrh commented Nov 24, 2023

@sapphi-red Thanks for your response. You're right, we could adapt the component name with a custom function. But the problem is that this bloats the vite config. We would also have to reimplement some functionality of interpolateName or add loader-utils as dependency. Something similar was done in Create React App or Next.js. It feels kind of an overhead to reimplement this in several projects. The regExp option looks like a nice shortcut and would only expose existing functionality of interpolateName.

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

Successfully merging this pull request may close these issues.

None yet

4 participants