feat: added `url` and `import` options for CSS

This commit is contained in:
alexander.akait 2024-11-01 17:51:22 +03:00
parent 5e8317b881
commit 5e09d0e05f
158 changed files with 7221 additions and 4514 deletions

View File

@ -774,10 +774,18 @@ export type CssGeneratorExportsOnly = boolean;
* Configure the generated local ident name.
*/
export type CssGeneratorLocalIdentName = string;
/**
* Enable/disable `@import` at-rules handling.
*/
export type CssParserImport = boolean;
/**
* Use ES modules named export for css exports.
*/
export type CssParserNamedExports = boolean;
/**
* Enable/disable `url()`/`image-set()`/`src()`/`image()` functions handling.
*/
export type CssParserUrl = boolean;
/**
* A Function returning a Promise resolving to a normalized entry.
*/
@ -2906,10 +2914,18 @@ export interface CssAutoGeneratorOptions {
* Parser options for css/auto modules.
*/
export interface CssAutoParserOptions {
/**
* Enable/disable `@import` at-rules handling.
*/
import?: CssParserImport;
/**
* Use ES modules named export for css exports.
*/
namedExports?: CssParserNamedExports;
/**
* Enable/disable `url()`/`image-set()`/`src()`/`image()` functions handling.
*/
url?: CssParserUrl;
}
/**
* Generator options for css modules.
@ -2949,10 +2965,18 @@ export interface CssGlobalGeneratorOptions {
* Parser options for css/global modules.
*/
export interface CssGlobalParserOptions {
/**
* Enable/disable `@import` at-rules handling.
*/
import?: CssParserImport;
/**
* Use ES modules named export for css exports.
*/
namedExports?: CssParserNamedExports;
/**
* Enable/disable `url()`/`image-set()`/`src()`/`image()` functions handling.
*/
url?: CssParserUrl;
}
/**
* Generator options for css/module modules.
@ -2979,19 +3003,35 @@ export interface CssModuleGeneratorOptions {
* Parser options for css/module modules.
*/
export interface CssModuleParserOptions {
/**
* Enable/disable `@import` at-rules handling.
*/
import?: CssParserImport;
/**
* Use ES modules named export for css exports.
*/
namedExports?: CssParserNamedExports;
/**
* Enable/disable `url()`/`image-set()`/`src()`/`image()` functions handling.
*/
url?: CssParserUrl;
}
/**
* Parser options for css modules.
*/
export interface CssParserOptions {
/**
* Enable/disable `@import` at-rules handling.
*/
import?: CssParserImport;
/**
* Use ES modules named export for css exports.
*/
namedExports?: CssParserNamedExports;
/**
* Enable/disable `url()`/`image-set()`/`src()`/`image()` functions handling.
*/
url?: CssParserUrl;
}
/**
* No generator options are supported for this module type.

View File

@ -670,6 +670,8 @@ const applyModuleDefaults = (
if (css) {
F(module.parser, CSS_MODULE_TYPE, () => ({}));
D(module.parser[CSS_MODULE_TYPE], "import", true);
D(module.parser[CSS_MODULE_TYPE], "url", true);
D(module.parser[CSS_MODULE_TYPE], "namedExports", true);
F(module.generator, CSS_MODULE_TYPE, () => ({}));

View File

@ -293,26 +293,34 @@ class CssModulesPlugin {
.for(type)
.tap(PLUGIN_NAME, parserOptions => {
validateParserOptions[type](parserOptions);
const { namedExports } = parserOptions;
const { url, import: importOption, namedExports } = parserOptions;
switch (type) {
case CSS_MODULE_TYPE:
return new CssParser({
importOption,
url,
namedExports
});
case CSS_MODULE_TYPE_GLOBAL:
return new CssParser({
defaultMode: "global",
importOption,
url,
namedExports
});
case CSS_MODULE_TYPE_MODULE:
return new CssParser({
defaultMode: "local",
importOption,
url,
namedExports
});
case CSS_MODULE_TYPE_AUTO:
return new CssParser({
defaultMode: "auto",
importOption,
url,
namedExports
});
}

View File

@ -148,12 +148,21 @@ const CSS_MODE_IN_BLOCK = 1;
class CssParser extends Parser {
/**
* @param {object} options options
* @param {boolean=} options.importOption need handle `@import`
* @param {boolean=} options.url need handle URLs
* @param {("pure" | "global" | "local" | "auto")=} options.defaultMode default mode
* @param {boolean=} options.namedExports is named exports
*/
constructor({ defaultMode = "pure", namedExports = true } = {}) {
constructor({
defaultMode = "pure",
importOption = true,
url = true,
namedExports = true
} = {}) {
super();
this.defaultMode = defaultMode;
this.import = importOption;
this.url = url;
this.namedExports = namedExports;
/** @type {Comment[] | undefined} */
this.comments = undefined;
@ -289,6 +298,7 @@ class CssParser extends Parser {
}
return [pos, text.trimEnd()];
};
const eatSemi = walkCssTokens.eatUntil(";");
const eatExportName = walkCssTokens.eatUntil(":};/");
const eatExportValue = walkCssTokens.eatUntil("};/");
/**
@ -497,6 +507,10 @@ class CssParser extends Parser {
return end;
},
url: (input, start, end, contentStart, contentEnd) => {
if (!this.url) {
return end;
}
const { options, errors: commentErrors } = this.parseCommentOptions([
lastTokenEndForComments,
end
@ -572,6 +586,10 @@ class CssParser extends Parser {
return eatUntilSemi(input, start);
}
case "@import": {
if (!this.import) {
return eatSemi(input, end);
}
if (!allowImportAtRule) {
this._emitWarning(
state,
@ -901,6 +919,10 @@ class CssParser extends Parser {
switch (name) {
case "src":
case "url": {
if (!this.url) {
return end;
}
const string = walkCssTokens.eatString(input, end);
if (!string) return end;
const { options, errors: commentErrors } = this.parseCommentOptions(
@ -955,7 +977,7 @@ class CssParser extends Parser {
return string[1];
}
default: {
if (IMAGE_SET_FUNCTION.test(name)) {
if (this.url && IMAGE_SET_FUNCTION.test(name)) {
lastTokenEndForComments = end;
const values = walkCssTokens.eatImageSetStrings(input, end, {
comment

File diff suppressed because one or more lines are too long

View File

@ -395,8 +395,14 @@
"type": "object",
"additionalProperties": false,
"properties": {
"import": {
"$ref": "#/definitions/CssParserImport"
},
"namedExports": {
"$ref": "#/definitions/CssParserNamedExports"
},
"url": {
"$ref": "#/definitions/CssParserUrl"
}
}
},
@ -483,8 +489,14 @@
"type": "object",
"additionalProperties": false,
"properties": {
"import": {
"$ref": "#/definitions/CssParserImport"
},
"namedExports": {
"$ref": "#/definitions/CssParserNamedExports"
},
"url": {
"$ref": "#/definitions/CssParserUrl"
}
}
},
@ -516,11 +528,21 @@
"type": "object",
"additionalProperties": false,
"properties": {
"import": {
"$ref": "#/definitions/CssParserImport"
},
"namedExports": {
"$ref": "#/definitions/CssParserNamedExports"
},
"url": {
"$ref": "#/definitions/CssParserUrl"
}
}
},
"CssParserImport": {
"description": "Enable/disable `@import` at-rules handling.",
"type": "boolean"
},
"CssParserNamedExports": {
"description": "Use ES modules named export for css exports.",
"type": "boolean"
@ -530,11 +552,21 @@
"type": "object",
"additionalProperties": false,
"properties": {
"import": {
"$ref": "#/definitions/CssParserImport"
},
"namedExports": {
"$ref": "#/definitions/CssParserNamedExports"
},
"url": {
"$ref": "#/definitions/CssParserUrl"
}
}
},
"CssParserUrl": {
"description": "Enable/disable `url()`/`image-set()`/`src()`/`image()` functions handling.",
"type": "boolean"
},
"Dependencies": {
"description": "References to other configurations to depend on.",
"type": "array",

View File

@ -3,4 +3,4 @@
* DO NOT MODIFY BY HAND.
* Run `yarn special-lint-fix` to update
*/
"use strict";function r(t,{instancePath:a="",parentData:e,parentDataProperty:o,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const a=0;for(const a in t)if("namedExports"!==a)return r.errors=[{params:{additionalProperty:a}}],!1;if(0===a&&void 0!==t.namedExports&&"boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}function t(a,{instancePath:e="",parentData:o,parentDataProperty:n,rootData:s=a}={}){let p=null,i=0;return r(a,{instancePath:e,parentData:o,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t;
"use strict";function r(t,{instancePath:e="",parentData:o,parentDataProperty:a,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const e=0;for(const e in t)if("import"!==e&&"namedExports"!==e&&"url"!==e)return r.errors=[{params:{additionalProperty:e}}],!1;if(0===e){if(void 0!==t.import){const e=0;if("boolean"!=typeof t.import)return r.errors=[{params:{type:"boolean"}}],!1;var s=0===e}else s=!0;if(s){if(void 0!==t.namedExports){const e=0;if("boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1;s=0===e}else s=!0;if(s)if(void 0!==t.url){const e=0;if("boolean"!=typeof t.url)return r.errors=[{params:{type:"boolean"}}],!1;s=0===e}else s=!0}}}return r.errors=null,!0}function t(e,{instancePath:o="",parentData:a,parentDataProperty:n,rootData:s=e}={}){let p=null,i=0;return r(e,{instancePath:o,parentData:a,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t;

View File

@ -3,4 +3,4 @@
* DO NOT MODIFY BY HAND.
* Run `yarn special-lint-fix` to update
*/
"use strict";function r(t,{instancePath:a="",parentData:e,parentDataProperty:o,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const a=0;for(const a in t)if("namedExports"!==a)return r.errors=[{params:{additionalProperty:a}}],!1;if(0===a&&void 0!==t.namedExports&&"boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}function t(a,{instancePath:e="",parentData:o,parentDataProperty:n,rootData:s=a}={}){let p=null,i=0;return r(a,{instancePath:e,parentData:o,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t;
"use strict";function r(t,{instancePath:e="",parentData:o,parentDataProperty:a,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const e=0;for(const e in t)if("import"!==e&&"namedExports"!==e&&"url"!==e)return r.errors=[{params:{additionalProperty:e}}],!1;if(0===e){if(void 0!==t.import){const e=0;if("boolean"!=typeof t.import)return r.errors=[{params:{type:"boolean"}}],!1;var s=0===e}else s=!0;if(s){if(void 0!==t.namedExports){const e=0;if("boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1;s=0===e}else s=!0;if(s)if(void 0!==t.url){const e=0;if("boolean"!=typeof t.url)return r.errors=[{params:{type:"boolean"}}],!1;s=0===e}else s=!0}}}return r.errors=null,!0}function t(e,{instancePath:o="",parentData:a,parentDataProperty:n,rootData:s=e}={}){let p=null,i=0;return r(e,{instancePath:o,parentData:a,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t;

View File

@ -3,4 +3,4 @@
* DO NOT MODIFY BY HAND.
* Run `yarn special-lint-fix` to update
*/
"use strict";function r(t,{instancePath:a="",parentData:e,parentDataProperty:o,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const a=0;for(const a in t)if("namedExports"!==a)return r.errors=[{params:{additionalProperty:a}}],!1;if(0===a&&void 0!==t.namedExports&&"boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}function t(a,{instancePath:e="",parentData:o,parentDataProperty:n,rootData:s=a}={}){let p=null,i=0;return r(a,{instancePath:e,parentData:o,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t;
"use strict";function r(t,{instancePath:e="",parentData:o,parentDataProperty:a,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const e=0;for(const e in t)if("import"!==e&&"namedExports"!==e&&"url"!==e)return r.errors=[{params:{additionalProperty:e}}],!1;if(0===e){if(void 0!==t.import){const e=0;if("boolean"!=typeof t.import)return r.errors=[{params:{type:"boolean"}}],!1;var s=0===e}else s=!0;if(s){if(void 0!==t.namedExports){const e=0;if("boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1;s=0===e}else s=!0;if(s)if(void 0!==t.url){const e=0;if("boolean"!=typeof t.url)return r.errors=[{params:{type:"boolean"}}],!1;s=0===e}else s=!0}}}return r.errors=null,!0}function t(e,{instancePath:o="",parentData:a,parentDataProperty:n,rootData:s=e}={}){let p=null,i=0;return r(e,{instancePath:o,parentData:a,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t;

View File

@ -3,4 +3,4 @@
* DO NOT MODIFY BY HAND.
* Run `yarn special-lint-fix` to update
*/
"use strict";function r(t,{instancePath:a="",parentData:e,parentDataProperty:o,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const a=0;for(const a in t)if("namedExports"!==a)return r.errors=[{params:{additionalProperty:a}}],!1;if(0===a&&void 0!==t.namedExports&&"boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1}return r.errors=null,!0}function t(a,{instancePath:e="",parentData:o,parentDataProperty:n,rootData:s=a}={}){let p=null,i=0;return r(a,{instancePath:e,parentData:o,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t;
"use strict";function r(t,{instancePath:e="",parentData:o,parentDataProperty:a,rootData:n=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return r.errors=[{params:{type:"object"}}],!1;{const e=0;for(const e in t)if("import"!==e&&"namedExports"!==e&&"url"!==e)return r.errors=[{params:{additionalProperty:e}}],!1;if(0===e){if(void 0!==t.import){const e=0;if("boolean"!=typeof t.import)return r.errors=[{params:{type:"boolean"}}],!1;var s=0===e}else s=!0;if(s){if(void 0!==t.namedExports){const e=0;if("boolean"!=typeof t.namedExports)return r.errors=[{params:{type:"boolean"}}],!1;s=0===e}else s=!0;if(s)if(void 0!==t.url){const e=0;if("boolean"!=typeof t.url)return r.errors=[{params:{type:"boolean"}}],!1;s=0===e}else s=!0}}}return r.errors=null,!0}function t(e,{instancePath:o="",parentData:a,parentDataProperty:n,rootData:s=e}={}){let p=null,i=0;return r(e,{instancePath:o,parentData:a,parentDataProperty:n,rootData:s})||(p=null===p?r.errors:p.concat(r.errors),i=p.length),t.errors=p,0===i}module.exports=t,module.exports.default=t;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
@import url(https://test.cases/path/../../../../configCases/css/css-import/external.css);
@import url(https://test.cases/path/../../../../configCases/css/import/external.css);
@import "style-imported.css";
body {
background: red;

View File

@ -1,4 +1,4 @@
@import url(https://test.cases/path/../../../../configCases/css/css-import/external.css);
@import url(https://test.cases/path/../../../../configCases/css/import/external.css);
@import "style-imported.css";
body {
background: red;

View File

@ -1,46 +0,0 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
target: "web",
mode: "development",
experiments: {
css: true
},
resolve: {
byDependency: {
"css-import": {
conditionNames: ["custom-name", "..."],
extensions: [".mycss", "..."]
}
}
},
module: {
rules: [
{
test: /\.mycss$/,
loader: "./string-loader",
type: "css/global"
},
{
test: /\.less$/,
loader: "less-loader",
type: "css/global"
}
]
},
externals: {
"external-1.css": "css-import external-1.css",
"external-2.css": "css-import external-2.css",
"external-3.css": "css-import external-3.css",
"external-4.css": "css-import external-4.css",
"external-5.css": "css-import external-5.css",
"external-6.css": "css-import external-6.css",
"external-7.css": "css-import external-7.css",
"external-8.css": "css-import external-8.css",
"external-9.css": "css-import external-9.css",
"external-10.css": "css-import external-10.css",
"external-11.css": "css-import external-11.css",
"external-12.css": "css-import external-12.css",
"external-13.css": "css-import external-13.css",
"external-14.css": "css-import external-14.css"
}
};

View File

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -60,8 +60,8 @@ style2.css?foo=9
@import url(style2.css) screen and (orientation:landscape);
@import url(style2.css) screen and (orientation:landscape);
@import url(style2.css) (min-width: 100px);
@import url(https://test.cases/path/../../../../configCases/css/css-import/external.css);
@import url(https://test.cases/path/../../../../configCases/css/css-import/external.css) screen and (orientation:landscape);
@import url(https://test.cases/path/../../../../configCases/css/import/external.css);
@import url(https://test.cases/path/../../../../configCases/css/import/external.css) screen and (orientation:landscape);
@import "//example.com/style.css";
@import url('test.css?foo=1&bar=1');
@import url('style2.css?foo=1&bar=1#hash');

View File

@ -1,5 +1,5 @@
@import url(./style11.css);
@import url(https://test.cases/path/../../../../configCases/css/css-import/external1.css);
@import url(https://test.cases/path/../../../../configCases/css/import/external1.css);
@import url(./style12.css);
@import url(./style13.css);

View File

@ -1,4 +1,4 @@
@import url(https://test.cases/path/../../../../configCases/css/css-import/external2.css);
@import url(https://test.cases/path/../../../../configCases/css/import/external2.css);
.style12 {
color: red;

Some files were not shown because too many files have changed in this diff Show More