rsnext/packages/next/build/webpack/config/blocks/css/loaders/getCssModuleLocalIdent.ts
Guy Bedford 005a8abe39
feat: Webpack loader inlining (#21127)
This picks up on the inlining work in https://github.com/vercel/next.js/pull/20598 to also include webpack loader inlining optimizations.

This includes:
* The dependencies of sass-loader
* resolve-url-loader

And for added benefit:
* babel-plugin-transform-define
* babel-plugin-transform-react-remove-prop-types

style-loader and css-loader didn't inline easily. Perhaps we can come back to these ones.
2021-01-15 01:51:45 +00:00

53 lines
1.7 KiB
TypeScript

import loaderUtils from 'next/dist/compiled/loader-utils'
import path from 'path'
import { webpack } from 'next/dist/compiled/webpack/webpack'
const regexLikeIndexModule = /(?<!pages[\\/])index\.module\.(scss|sass|css)$/
export function getCssModuleLocalIdent(
context: webpack.loader.LoaderContext,
_: any,
exportName: string,
options: object
) {
const relativePath = path
.relative(context.rootContext, context.resourcePath)
.replace(/\\+/g, '/')
// Generate a more meaningful name (parent folder) when the user names the
// file `index.module.css`.
const fileNameOrFolder = regexLikeIndexModule.test(relativePath)
? '[folder]'
: '[name]'
// Generate a hash to make the class name unique.
const hash = loaderUtils.getHashDigest(
Buffer.from(`filePath:${relativePath}#className:${exportName}`),
'md5',
'base64',
5
)
// Have webpack interpolate the `[folder]` or `[name]` to its real value.
return (
loaderUtils
.interpolateName(
context,
fileNameOrFolder + '_' + exportName + '__' + hash,
options
)
.replace(
// Webpack name interpolation returns `about.module_root__2oFM9` for
// `.root {}` inside a file named `about.module.css`. Let's simplify
// this.
/\.module_/,
'_'
)
// Replace invalid symbols with underscores instead of escaping
// https://mathiasbynens.be/notes/css-escapes#identifiers-strings
.replace(/[^a-zA-Z0-9-_]/g, '_')
// "they cannot start with a digit, two hyphens, or a hyphen followed by a digit [sic]"
// https://www.w3.org/TR/CSS21/syndata.html#characters
.replace(/^(\d|--|-\d)/, '__$1')
)
}