css-loader
Advanced tools
Comparing version 6.11.0 to 7.0.0
@@ -48,5 +48,5 @@ "use strict"; | ||
} | ||
const isSupportDataURL = options.esModule && Boolean("fsStartTime" in this._compiler); | ||
if ((0, _utils.shouldUseImportPlugin)(options)) { | ||
plugins.push((0, _plugins.importParser)({ | ||
// TODO need to fix on webpack side, webpack tries to resolve `./runtime/api.js paths like `http://site.com/runtime/api.js`, maybe we should try first request like absolute, the second like a relative to context | ||
isSupportAbsoluteURL: false, | ||
@@ -67,3 +67,3 @@ isSupportDataURL: false, | ||
isSupportAbsoluteURL, | ||
isSupportDataURL, | ||
isSupportDataURL: options.esModule, | ||
imports: urlPluginImports, | ||
@@ -70,0 +70,0 @@ replacements, |
@@ -157,6 +157,10 @@ { | ||
"asIs", | ||
"as-is", | ||
"camelCase", | ||
"camel-case", | ||
"camelCaseOnly", | ||
"camel-case-only", | ||
"dashes", | ||
"dashesOnly" | ||
"dashesOnly", | ||
"dashes-only" | ||
] | ||
@@ -163,0 +167,0 @@ }, |
@@ -45,39 +45,4 @@ "use strict"; | ||
const WEBPACK_IGNORE_COMMENT_REGEXP = exports.WEBPACK_IGNORE_COMMENT_REGEXP = /webpackIgnore:(\s+)?(true|false)/; | ||
const matchRelativePath = /^\.\.?[/\\]/; | ||
function isAbsolutePath(str) { | ||
return _path.default.posix.isAbsolute(str) || _path.default.win32.isAbsolute(str); | ||
} | ||
function isRelativePath(str) { | ||
return matchRelativePath.test(str); | ||
} | ||
// TODO simplify for the next major release | ||
function stringifyRequest(loaderContext, request) { | ||
if (typeof loaderContext.utils !== "undefined" && typeof loaderContext.utils.contextify === "function") { | ||
return JSON.stringify(loaderContext.utils.contextify(loaderContext.context || loaderContext.rootContext, request)); | ||
} | ||
const splitted = request.split("!"); | ||
const { | ||
context | ||
} = loaderContext; | ||
return JSON.stringify(splitted.map(part => { | ||
// First, separate singlePath from query, because the query might contain paths again | ||
const splittedPart = part.match(/^(.*?)(\?.*)/); | ||
const query = splittedPart ? splittedPart[2] : ""; | ||
let singlePath = splittedPart ? splittedPart[1] : part; | ||
if (isAbsolutePath(singlePath) && context) { | ||
singlePath = _path.default.relative(context, singlePath); | ||
if (isAbsolutePath(singlePath)) { | ||
// If singlePath still matches an absolute path, singlePath was on a different drive than context. | ||
// In this case, we leave the path platform-specific without replacing any separators. | ||
// @see https://github.com/webpack/loader-utils/pull/14 | ||
return singlePath + query; | ||
} | ||
if (isRelativePath(singlePath) === false) { | ||
// Ensure that the relative path starts at least with ./ otherwise it would be a request into the modules directory (like node_modules). | ||
singlePath = `./${singlePath}`; | ||
} | ||
} | ||
return singlePath.replace(/\\/g, "/") + query; | ||
}).join("!")); | ||
return JSON.stringify(loaderContext.utils.contextify(loaderContext.context || loaderContext.rootContext, request)); | ||
} | ||
@@ -276,3 +241,3 @@ | ||
function escapeLocalIdent(localident) { | ||
// TODO simplify in the next major release | ||
// TODO simplify? | ||
return escape(localident | ||
@@ -322,6 +287,4 @@ // For `[hash]` placeholder | ||
for (let tier = 0; localIdentHash.length < hashDigestLength; tier++) { | ||
// TODO remove this in the next major release | ||
const hash = loaderContext.utils && typeof loaderContext.utils.createHash === "function" ? loaderContext.utils.createHash(hashFunction) : | ||
// eslint-disable-next-line no-underscore-dangle | ||
loaderContext._compiler.webpack.util.createHash(hashFunction); | ||
const hash = loaderContext._compiler.webpack.util.createHash(hashFunction); | ||
if (hashSalt) { | ||
@@ -446,3 +409,3 @@ hash.update(hashSalt); | ||
const IS_ICSS = /\.icss\.\w+$/i; | ||
function getModulesOptions(rawOptions, exportType, loaderContext) { | ||
function getModulesOptions(rawOptions, esModule, exportType, loaderContext) { | ||
if (typeof rawOptions.modules === "boolean" && rawOptions.modules === false) { | ||
@@ -477,2 +440,4 @@ return false; | ||
const needNamedExport = exportType === "css-style-sheet" || exportType === "string"; | ||
const namedExport = typeof rawModulesOptions.namedExport !== "undefined" ? rawModulesOptions.namedExport : needNamedExport || esModule; | ||
const exportLocalsConvention = typeof rawModulesOptions.exportLocalsConvention !== "undefined" ? rawModulesOptions.exportLocalsConvention : namedExport ? "as-is" : "camel-case-only"; | ||
const modulesOptions = { | ||
@@ -492,13 +457,16 @@ auto, | ||
getLocalIdent: undefined, | ||
namedExport: needNamedExport || false, | ||
exportLocalsConvention: (rawModulesOptions.namedExport === true || needNamedExport) && typeof rawModulesOptions.exportLocalsConvention === "undefined" ? "camelCaseOnly" : "asIs", | ||
// TODO improve me and enable by default | ||
exportOnlyLocals: false, | ||
...rawModulesOptions, | ||
useExportsAs: rawModulesOptions.exportLocalsConvention === "asIs" | ||
exportLocalsConvention, | ||
namedExport | ||
}; | ||
let exportLocalsConventionType; | ||
if (typeof modulesOptions.exportLocalsConvention === "string") { | ||
exportLocalsConventionType = modulesOptions.exportLocalsConvention; | ||
// eslint-disable-next-line no-shadow | ||
const { | ||
exportLocalsConvention | ||
} = modulesOptions; | ||
modulesOptions.exportLocalsConvention = name => { | ||
switch (exportLocalsConventionType) { | ||
switch (exportLocalsConvention) { | ||
case "camel-case": | ||
case "camelCase": | ||
@@ -508,2 +476,3 @@ { | ||
} | ||
case "camel-case-only": | ||
case "camelCaseOnly": | ||
@@ -517,2 +486,3 @@ { | ||
} | ||
case "dashes-only": | ||
case "dashesOnly": | ||
@@ -522,2 +492,3 @@ { | ||
} | ||
case "as-is": | ||
case "asIs": | ||
@@ -560,3 +531,3 @@ default: | ||
if (needNamedExport) { | ||
if (rawOptions.esModule === false) { | ||
if (esModule === false) { | ||
throw new Error("The 'exportType' option with the 'css-style-sheet' or 'string' value requires the 'esModule' option to be enabled"); | ||
@@ -568,9 +539,4 @@ } | ||
} | ||
if (modulesOptions.namedExport === true) { | ||
if (rawOptions.esModule === false) { | ||
throw new Error("The 'modules.namedExport' option requires the 'esModule' option to be enabled"); | ||
} | ||
if (typeof exportLocalsConventionType === "string" && exportLocalsConventionType !== "asIs" && exportLocalsConventionType !== "camelCaseOnly" && exportLocalsConventionType !== "dashesOnly") { | ||
throw new Error('The "modules.namedExport" option requires the "modules.exportLocalsConvention" option to be "camelCaseOnly" or "dashesOnly"'); | ||
} | ||
if (modulesOptions.namedExport === true && esModule === false) { | ||
throw new Error("The 'modules.namedExport' option requires the 'esModule' option to be enabled"); | ||
} | ||
@@ -581,3 +547,4 @@ return modulesOptions; | ||
const exportType = typeof rawOptions.exportType === "undefined" ? "array" : rawOptions.exportType; | ||
const modulesOptions = getModulesOptions(rawOptions, exportType, loaderContext); | ||
const esModule = typeof rawOptions.esModule === "undefined" ? true : rawOptions.esModule; | ||
const modulesOptions = getModulesOptions(rawOptions, esModule, exportType, loaderContext); | ||
return { | ||
@@ -589,3 +556,3 @@ url: typeof rawOptions.url === "undefined" ? true : rawOptions.url, | ||
importLoaders: typeof rawOptions.importLoaders === "string" ? parseInt(rawOptions.importLoaders, 10) : rawOptions.importLoaders, | ||
esModule: typeof rawOptions.esModule === "undefined" ? true : rawOptions.esModule, | ||
esModule, | ||
exportType | ||
@@ -885,2 +852,4 @@ }; | ||
} | ||
const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u; | ||
const keywords = new Set(["abstract", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with"]); | ||
function getExportCode(exports, replacements, icssPluginUsed, options, isTemplateLiteralSupported) { | ||
@@ -896,3 +865,3 @@ let code = "// Exports\n"; | ||
if (options.modules.namedExport) { | ||
if (options.modules.useExportsAs) { | ||
if (!validIdentifier.test(name) || keywords.has(name)) { | ||
identifierId += 1; | ||
@@ -899,0 +868,0 @@ const id = `_${identifierId.toString(16)}`; |
{ | ||
"name": "css-loader", | ||
"version": "6.11.0", | ||
"version": "7.0.0", | ||
"description": "css loader module for webpack", | ||
@@ -16,3 +16,3 @@ "license": "MIT", | ||
"engines": { | ||
"node": ">= 12.13.0" | ||
"node": ">= 18.12.0" | ||
}, | ||
@@ -28,5 +28,5 @@ "scripts": { | ||
"security": "npm audit --production", | ||
"lint:prettier": "prettier --list-different .", | ||
"lint:prettier": "prettier --cache --list-different .", | ||
"lint:js": "eslint --cache .", | ||
"lint:spelling": "cspell \"**/*.*\"", | ||
"lint:spelling": "cspell --cache --no-must-find-files --quiet \"**/*.*\"", | ||
"lint": "npm-run-all -l -p \"lint:**\"", | ||
@@ -49,3 +49,3 @@ "fix:js": "npm run lint:js -- --fix", | ||
"@rspack/core": "0.x || 1.x", | ||
"webpack": "^5.0.0" | ||
"webpack": "^5.27.0" | ||
}, | ||
@@ -74,34 +74,33 @@ "peerDependenciesMeta": { | ||
"@babel/preset-env": "^7.23.7", | ||
"@commitlint/cli": "^16.3.0", | ||
"@commitlint/config-conventional": "^16.2.4", | ||
"@commitlint/cli": "^19.2.1", | ||
"@commitlint/config-conventional": "^19.1.0", | ||
"@webpack-contrib/eslint-config-webpack": "^3.0.0", | ||
"babel-jest": "^28.1.3", | ||
"babel-jest": "^29.7.0", | ||
"cross-env": "^7.0.3", | ||
"cspell": "^6.31.2", | ||
"del": "^6.1.1", | ||
"del-cli": "^4.0.1", | ||
"cspell": "^8.6.1", | ||
"del-cli": "^5.1.0", | ||
"es-check": "^7.1.0", | ||
"eslint": "^8.54.0", | ||
"eslint-config-prettier": "^8.9.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-import": "^2.29.0", | ||
"file-loader": "^6.2.0", | ||
"husky": "^7.0.1", | ||
"jest": "^28.1.3", | ||
"jest-environment-jsdom": "^28.1.3", | ||
"husky": "^9.0.11", | ||
"jest": "^29.7.0", | ||
"jest-environment-jsdom": "^29.7.0", | ||
"less": "^4.2.0", | ||
"less-loader": "^10.0.1", | ||
"lint-staged": "^12.5.0", | ||
"memfs": "^3.5.3", | ||
"less-loader": "^12.2.0", | ||
"lint-staged": "^15.2.2", | ||
"memfs": "^4.8.1", | ||
"mini-css-extract-plugin": "^2.7.5", | ||
"npm-run-all": "^4.1.5", | ||
"postcss-loader": "^6.2.1", | ||
"postcss-preset-env": "^7.8.3", | ||
"prettier": "^2.8.7", | ||
"postcss-loader": "^8.1.1", | ||
"postcss-preset-env": "^9.5.4", | ||
"prettier": "^3.2.5", | ||
"sass": "^1.69.7", | ||
"sass-loader": "^12.6.0", | ||
"sass-loader": "^14.1.1", | ||
"standard-version": "^9.5.0", | ||
"strip-ansi": "^6.0.0", | ||
"style-loader": "^3.3.2", | ||
"stylus": "^0.59.0", | ||
"stylus-loader": "^6.1.0", | ||
"style-loader": "^3.3.4", | ||
"stylus": "^0.63.0", | ||
"stylus-loader": "^8.1.0", | ||
"url-loader": "^4.1.1", | ||
@@ -108,0 +107,0 @@ "webpack": "^5.89.0" |
@@ -195,3 +195,3 @@ <div align="center"> | ||
supports?: string, | ||
layer?: string | ||
layer?: string, | ||
) => boolean; | ||
@@ -319,3 +319,3 @@ }; | ||
localIdentName: string, | ||
localName: string | ||
localName: string, | ||
) => string; | ||
@@ -325,7 +325,7 @@ namedExport: boolean; | ||
exportLocalsConvention: | ||
| "asIs" | ||
| "camelCase" | ||
| "camelCaseOnly" | ||
| "as-is" | ||
| "camel-case" | ||
| "camel-case-only" | ||
| "dashes" | ||
| "dashesOnly" | ||
| "dashes-only" | ||
| ((name: string) => string); | ||
@@ -495,3 +495,6 @@ exportOnlyLocals: boolean; | ||
:local(.className) { | ||
composes: edit highlight from "./edit.css", button from "module/button.css", classFromThisModule; | ||
composes: | ||
edit highlight from "./edit.css", | ||
button from "module/button.css", | ||
classFromThisModule; | ||
background: red; | ||
@@ -606,3 +609,3 @@ } | ||
namedExport: true, | ||
exportLocalsConvention: "camelCase", | ||
exportLocalsConvention: "as-is", | ||
exportOnlyLocals: false, | ||
@@ -628,3 +631,3 @@ }, | ||
resourceQuery: string, | ||
resourceFragment: string | ||
resourceFragment: string, | ||
) => boolean); | ||
@@ -735,3 +738,3 @@ ``` | ||
resourceQuery: string, | ||
resourceFragment: string | ||
resourceFragment: string, | ||
) => "local" | "global" | "pure" | "icss"); | ||
@@ -1104,3 +1107,3 @@ ``` | ||
localIdentName: string, | ||
localName: string | ||
localName: string, | ||
) => string; | ||
@@ -1146,3 +1149,3 @@ ``` | ||
Default: `false` | ||
Default: Depends on the value of the `esModule` option. If the value of the `esModule` options is `true`, this value will also be `true`, otherwise it will be `false`. | ||
@@ -1153,12 +1156,4 @@ Enables/disables ES modules named export for locals. | ||
> | ||
> Names of locals are converted to camelcase, i.e. the `exportLocalsConvention` option has | ||
> `camelCaseOnly` value by default. You can set this back to any other valid option but selectors | ||
> which are not valid JavaScript identifiers may run into problems which do not implement the entire | ||
> modules specification. | ||
> It is not allowed to use the `default` reserved word in css classes. | ||
> **Warning** | ||
> | ||
> It is not allowed to use JavaScript reserved words in css class names unless | ||
> `exportLocalsConvention` is `"asIs"`. | ||
**styles.css** | ||
@@ -1180,4 +1175,6 @@ | ||
// If using `exportLocalsConvention: "camel-case-only"`: | ||
console.log(styles.fooBaz, styles.bar); | ||
// or if using `exportLocalsConvention: "asIs"`: | ||
// If using `exportLocalsConvention: "as-is"`: | ||
console.log(styles["foo-baz"], styles.bar); | ||
@@ -1250,12 +1247,18 @@ ``` | ||
type exportLocalsConvention = | ||
| "asIs" | ||
| "camelCase" | ||
| "camelCaseOnly" | ||
| "as-is" | ||
| "camel-case" | ||
| "camel-case-only" | ||
| "dashes" | ||
| "dashesOnly" | ||
| "dashes-only" | ||
| ((name: string) => string); | ||
``` | ||
Default: based on the `modules.namedExport` option value, if `true` - `camelCaseOnly`, otherwise `asIs` | ||
Default: Depends on the value of the `modules.namedExport` option, if `true` - `as-is`, otherwise `camel-case-only`. | ||
> **Warning** | ||
> | ||
> Names of locals are converted to camelcase when the named export is `false`, i.e. the `exportLocalsConvention` option has | ||
> `camelCaseOnly` value by default. You can set this back to any other valid option but selectors | ||
> which are not valid JavaScript identifiers may run into problems which do not implement the entire modules specification. | ||
Style of exported class names. | ||
@@ -1265,11 +1268,11 @@ | ||
By default, the exported JSON keys mirror the class names (i.e `asIs` value). | ||
By default, the exported JSON keys mirror the class names (i.e `as-is` value). | ||
| Name | Type | Description | | ||
| :-------------------: | :------: | :----------------------------------------------------------------------------------------------- | | ||
| **`'asIs'`** | `string` | Class names will be exported as is. | | ||
| **`'camelCase'`** | `string` | Class names will be camelized, the original class name will not to be removed from the locals | | ||
| **`'camelCaseOnly'`** | `string` | Class names will be camelized, the original class name will be removed from the locals | | ||
| **`'dashes'`** | `string` | Only dashes in class names will be camelized | | ||
| **`'dashesOnly'`** | `string` | Dashes in class names will be camelized, the original class name will be removed from the locals | | ||
| Name | Type | Description | | ||
| :---------------------: | :------: | :----------------------------------------------------------------------------------------------- | | ||
| **`'as-is'`** | `string` | Class names will be exported as is. | | ||
| **`'camel-case'`** | `string` | Class names will be camelized, the original class name will not to be removed from the locals | | ||
| **`'camel-case-only'`** | `string` | Class names will be camelized, the original class name will be removed from the locals | | ||
| **`'dashes'`** | `string` | Only dashes in class names will be camelized | | ||
| **`'dashes-only'`** | `string` | Dashes in class names will be camelized, the original class name will be removed from the locals | | ||
@@ -1300,3 +1303,3 @@ **file.css** | ||
modules: { | ||
exportLocalsConvention: "camelCase", | ||
exportLocalsConvention: "camel-case-only", | ||
}, | ||
@@ -1350,3 +1353,3 @@ }, | ||
name.replace(/-+(\w)/g, (match, firstLetter) => | ||
firstLetter.toUpperCase() | ||
firstLetter.toUpperCase(), | ||
), | ||
@@ -1788,3 +1791,4 @@ ]; | ||
color: red; | ||
background: url("./url/img.png"), | ||
background: | ||
url("./url/img.png"), | ||
/* webpackIgnore: true */ url("./url/img.png"); | ||
@@ -1923,3 +1927,3 @@ } | ||
__dirname, | ||
"assets/real-path-to-img/img.png" | ||
"assets/real-path-to-img/img.png", | ||
), | ||
@@ -1926,0 +1930,0 @@ }, |
36
2071
132114
2261