I originally asked this question on Stack Overflow but it seems like a lot of people keep pointing me back to asking the questions on the loader's repo, so hopefully this is a good place to ask.
I'm looking to run my :local style class names through a custom method that I've written. In the documentation, I see I can use query tag placeholders like: [path], [name], [local], and [hash:base64], but I couldn't find any information on how to write my own.
Is this possible?
I don't think it's possible to add them without playing with the source code.
I created my own, [dir] and [sourceHash] in a fork: https://github.com/Aluxian/css-loader
Take a look at the last commit to see what I changed.
I was afraid of that.. to the fork machine...
Thanks for the comments/head-start @Aluxian, appreciate it!
I would love to have a [dir] tag. My folder structure for a notional ButtonControl component consumed from a private npm package looks like this,
/button-control
- index.js
- index.css
I'd like a generated classname scheme that was at least somewhat human readable in dev tools. With this scheme, i.e. naming files like index.css, rather than button.css, using [name] always comes out as index which is not that helpful when scanning generated markup. I can use [path] but since this is coming from node_modules I end up with class names like,
... which is a bit, erm, verbose. So I need [dir] tag that resolves to the enclosing folder. Then I could have a classname like [dir][local][hash]:
Would this project be open to a PR that added [dir]?
I have the same problem as @jedrichards, would appreciate that feature!
I asked if they'd be willing to accept a PR this, but no response :(
@jedrichards @caesarsol according to this issue: https://github.com/webpack/css-loader/issues/246
it looks like [folder] already provides the parent directory name
Thanks! [folder] does indeed work. We should document this, it's obviously a common question...
@jedrichards Interally, css-loader uses webpack/loader-utils#interpolateName.
You might want to peruse your own _node-modules_ directory to determine the exact version you're using, but here are the current (0.2.15) features it supports:
The following tokens are replaced in the
nameparameter:
[ext]the extension of the resource[name]the basename of the resource[path]the path of the resource relative to thecontextquery parameter or option.[folder]the folder of the resource is in.[emoji]a random emoji representation ofoptions.content[emoji:<length>]same as above, but with a customizable number of emojis[hash]the hash ofoptions.content(Buffer) (by default it's the hex digest of the md5 hash)[<hashType>:hash:<digestType>:<length>]optionally one can configure
- other
hashTypes, i. e.sha1,md5,sha256,sha512
- other
digestTypes, i. e.hex,base26,base32,base36,base49,base52,base58,base62,base64
- and
lengththe length in chars
[N]the N-th match obtained from matching the current file name againstoptions.regExp
Aha loader-utils. Didn't even know that was a thing. Now makes sense it should be the place to look for such information. Thanks for the tip off.
Do you think it would be worth linking to that part of the loader-utils docs from this part of the readme?
You can configure the generated ident with the localIdentName query parameter (default [hash:base64]). Example: css-loader?localIdentName=[path][name]---[local]---[hash:base64:5] for easier debugging.
I think at least some reference to the possible options would be great, and linking might be the best way to avoid drift between the css-loader README and loader-utils implementation.
There is a way to convert [folder] name from CamelCase (I prefer this for component folders... ) to kebab-case (... and this for css classes)?
Can we provide a custom handler?
Is it at all possible to include the entry point name as part of the localIdentName? Currently [name] refers to the file name rather than the entry point being built out.
@Splact @navgarcha I think these questions (and any further questions about localIdentName) might receive a better response on https://github.com/webpack/loader-utils#interpolatename, the actual source of name interpolation.
I've had a look around the interpolateName stuff and im still none the wiser how to get the entry chunk name as part of the localIdentName - could some one point me in the right direction?
With Webpack 2 my use case has been solved with the ability to set a custom getLocalIdent function. Closing the issue.
@soluml can you please show the code?
Sure.. from the docs:
{
test: /\.css$/,
use: [
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
getLocalIdent: (context, localIdentName, localName, options) => {
return 'whatever_random_class_name'
}
}
}
]
}
Ah, okay. I wanted to use this options with extract-text-webpack-plugin, but seems like it is not possible now.
Using getLocalIdent seems to override any information specified in localIdentName - why would the two need to be defined at the same time if using getLocalIdent means ignoring contents of localIdentName?
Also, we can somehow access the hash inside getLocalIdent?
I'm also wondering the same, why localIdentName is still needed. On a side note, I don't see anyone using something like ``return '_' + (nextLocalIdent++).toString(36) to drastically reduce class name length.
localIdentName gets passed as a parameter to the getLocalIdent function. So it seems reasonably possible that someone may want their getLocalIdent function to behave differently depending on what localIdentName is set to, e.g. to do something similar to what the existing localIdentName generator does, but with one or more differences.
Most helpful comment
@jedrichards Interally, css-loader uses webpack/loader-utils#interpolateName.
You might want to peruse your own _node-modules_ directory to determine the exact version you're using, but here are the current (
0.2.15) features it supports: