mirror of https://github.com/webpack/webpack.git
				
				
				
			feat: url assets
This commit is contained in:
		
							parent
							
								
									3e4c2ef87a
								
							
						
					
					
						commit
						ddc83b0d70
					
				|  | @ -1011,6 +1011,10 @@ export interface RuleSetRule { | ||||||
| 	 * Match the child compiler name. | 	 * Match the child compiler name. | ||||||
| 	 */ | 	 */ | ||||||
| 	compiler?: RuleSetConditionOrConditions; | 	compiler?: RuleSetConditionOrConditions; | ||||||
|  | 	/** | ||||||
|  | 	 * Match dependency type. | ||||||
|  | 	 */ | ||||||
|  | 	dependency?: string; | ||||||
| 	/** | 	/** | ||||||
| 	 * Match values of properties in the description file (usually package.json). | 	 * Match values of properties in the description file (usually package.json). | ||||||
| 	 */ | 	 */ | ||||||
|  |  | ||||||
|  | @ -0,0 +1,53 @@ | ||||||
|  | /* | ||||||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||||||
|  | 	Author Ivan Kopeykin @vankop | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | const BaseURIRuntimeModule = require("./BaseURIRuntimeModule"); | ||||||
|  | const RuntimeGlobals = require("./RuntimeGlobals"); | ||||||
|  | 
 | ||||||
|  | /** @typedef {import("../declarations/WebpackOptions").Target} Target */ | ||||||
|  | /** @typedef {import("./Compiler")} Compiler */ | ||||||
|  | 
 | ||||||
|  | class BaseURIPlugin { | ||||||
|  | 	/** | ||||||
|  | 	 * @param {Target} target target | ||||||
|  | 	 */ | ||||||
|  | 	constructor(target) { | ||||||
|  | 		switch (target) { | ||||||
|  | 			case "webworker": | ||||||
|  | 				this.environment = /** @type {"webworker"} */ ("webworker"); | ||||||
|  | 				break; | ||||||
|  | 			case "node": | ||||||
|  | 			case "async-node": | ||||||
|  | 			case "node-webkit": | ||||||
|  | 			case "electron-main": | ||||||
|  | 			case "electron-preload": | ||||||
|  | 				this.environment = /** @type {"node"} */ ("node"); | ||||||
|  | 				break; | ||||||
|  | 			default: | ||||||
|  | 				this.environment = /** @type {"web"} */ ("web"); | ||||||
|  | 				break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * @param {Compiler} compiler compiler | ||||||
|  | 	 */ | ||||||
|  | 	apply(compiler) { | ||||||
|  | 		compiler.hooks.compilation.tap("BaseURIPlugin", compilation => { | ||||||
|  | 			compilation.hooks.runtimeRequirementInTree | ||||||
|  | 				.for(RuntimeGlobals.baseURI) | ||||||
|  | 				.tap("BaseURIPlugin", (chunk, set) => { | ||||||
|  | 					compilation.addRuntimeModule( | ||||||
|  | 						chunk, | ||||||
|  | 						new BaseURIRuntimeModule(this.environment) | ||||||
|  | 					); | ||||||
|  | 				}); | ||||||
|  | 		}); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = BaseURIPlugin; | ||||||
|  | @ -0,0 +1,44 @@ | ||||||
|  | /* | ||||||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||||||
|  | 	Author Ivan Kopeykin @vankop | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | const RuntimeGlobals = require("./RuntimeGlobals"); | ||||||
|  | const RuntimeModule = require("./RuntimeModule"); | ||||||
|  | const Template = require("./Template"); | ||||||
|  | 
 | ||||||
|  | class BaseURIRuntimeModule extends RuntimeModule { | ||||||
|  | 	/** | ||||||
|  | 	 * @param {"node"|"web"|"webworker"} environment environment | ||||||
|  | 	 */ | ||||||
|  | 	constructor(environment) { | ||||||
|  | 		super("baseURI"); | ||||||
|  | 		this.env = environment; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * @returns {string} runtime code | ||||||
|  | 	 */ | ||||||
|  | 	generate() { | ||||||
|  | 		switch (this.env) { | ||||||
|  | 			case "web": | ||||||
|  | 				return Template.asString([ | ||||||
|  | 					`${RuntimeGlobals.baseURI} = document.baseURI;` | ||||||
|  | 				]); | ||||||
|  | 			case "webworker": | ||||||
|  | 				return Template.asString([ | ||||||
|  | 					`${RuntimeGlobals.baseURI} = self.location;` | ||||||
|  | 				]); | ||||||
|  | 			case "node": | ||||||
|  | 				return Template.asString([ | ||||||
|  | 					`${RuntimeGlobals.baseURI} = require('url').pathToFileURL(__filename);` | ||||||
|  | 				]); | ||||||
|  | 			default: | ||||||
|  | 				return ""; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = BaseURIRuntimeModule; | ||||||
|  | @ -132,6 +132,7 @@ const dependencyCache = new WeakMap(); | ||||||
| const ruleSetCompiler = new RuleSetCompiler([ | const ruleSetCompiler = new RuleSetCompiler([ | ||||||
| 	new BasicMatcherRulePlugin("test", "resource"), | 	new BasicMatcherRulePlugin("test", "resource"), | ||||||
| 	new BasicMatcherRulePlugin("mimetype"), | 	new BasicMatcherRulePlugin("mimetype"), | ||||||
|  | 	new BasicMatcherRulePlugin("dependency"), | ||||||
| 	new BasicMatcherRulePlugin("include", "resource"), | 	new BasicMatcherRulePlugin("include", "resource"), | ||||||
| 	new BasicMatcherRulePlugin("exclude", "resource", true), | 	new BasicMatcherRulePlugin("exclude", "resource", true), | ||||||
| 	new BasicMatcherRulePlugin("resource"), | 	new BasicMatcherRulePlugin("resource"), | ||||||
|  |  | ||||||
|  | @ -278,3 +278,8 @@ exports.hasOwnProperty = "__webpack_require__.o"; | ||||||
|  * the System.register context object |  * the System.register context object | ||||||
|  */ |  */ | ||||||
| exports.systemContext = "__webpack_require__.y"; | exports.systemContext = "__webpack_require__.y"; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * the baseURI of current document | ||||||
|  |  */ | ||||||
|  | exports.baseURI = "__webpack_require__.b"; | ||||||
|  |  | ||||||
|  | @ -26,6 +26,8 @@ const TemplatedPathPlugin = require("./TemplatedPathPlugin"); | ||||||
| const UseStrictPlugin = require("./UseStrictPlugin"); | const UseStrictPlugin = require("./UseStrictPlugin"); | ||||||
| const WarnCaseSensitiveModulesPlugin = require("./WarnCaseSensitiveModulesPlugin"); | const WarnCaseSensitiveModulesPlugin = require("./WarnCaseSensitiveModulesPlugin"); | ||||||
| 
 | 
 | ||||||
|  | const BaseURIPlugin = require("./BaseURIPlugin"); | ||||||
|  | const URLPlugin = require("./dependencies/URLPlugin"); | ||||||
| const DataUriPlugin = require("./schemes/DataUriPlugin"); | const DataUriPlugin = require("./schemes/DataUriPlugin"); | ||||||
| const FileUriPlugin = require("./schemes/FileUriPlugin"); | const FileUriPlugin = require("./schemes/FileUriPlugin"); | ||||||
| 
 | 
 | ||||||
|  | @ -313,6 +315,8 @@ class WebpackOptionsApply extends OptionsApply { | ||||||
| 				: true | 				: true | ||||||
| 		}).apply(compiler); | 		}).apply(compiler); | ||||||
| 
 | 
 | ||||||
|  | 		new BaseURIPlugin(options.target).apply(compiler); | ||||||
|  | 		new URLPlugin().apply(compiler); | ||||||
| 		new DataUriPlugin().apply(compiler); | 		new DataUriPlugin().apply(compiler); | ||||||
| 		new FileUriPlugin().apply(compiler); | 		new FileUriPlugin().apply(compiler); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -356,6 +356,13 @@ const applyModuleDefaults = ( | ||||||
| 				mimetype: "application/node", | 				mimetype: "application/node", | ||||||
| 				type: "javascript/auto" | 				type: "javascript/auto" | ||||||
| 			}, | 			}, | ||||||
|  | 			{ | ||||||
|  | 				test: /\.js$/, | ||||||
|  | 				dependency: "url", | ||||||
|  | 				resolve: { | ||||||
|  | 					conditionNames: ["esm", "..."] | ||||||
|  | 				} | ||||||
|  | 			}, | ||||||
| 			{ | 			{ | ||||||
| 				test: /\.json$/i, | 				test: /\.json$/i, | ||||||
| 				type: "json" | 				type: "json" | ||||||
|  |  | ||||||
|  | @ -0,0 +1,75 @@ | ||||||
|  | /* | ||||||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||||||
|  | 	Author Ivan Kopeykin @vankop | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | const RuntimeGlobals = require("../RuntimeGlobals"); | ||||||
|  | const ModuleDependency = require("./ModuleDependency"); | ||||||
|  | 
 | ||||||
|  | /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ | ||||||
|  | /** @typedef {import("../ChunkGraph")} ChunkGraph */ | ||||||
|  | /** @typedef {import("../Dependency")} Dependency */ | ||||||
|  | /** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ | ||||||
|  | /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ | ||||||
|  | /** @typedef {import("../ModuleGraph")} ModuleGraph */ | ||||||
|  | /** @typedef {import("../util/Hash")} Hash */ | ||||||
|  | 
 | ||||||
|  | class URLDependency extends ModuleDependency { | ||||||
|  | 	/** | ||||||
|  | 	 * @param {string} request request | ||||||
|  | 	 * @param {[number, number]} range range | ||||||
|  | 	 */ | ||||||
|  | 	constructor(request, range) { | ||||||
|  | 		super(request); | ||||||
|  | 		this.range = range; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	get type() { | ||||||
|  | 		return "new URL()"; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	get category() { | ||||||
|  | 		return "url"; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | URLDependency.Template = class URLDependencyTemplate extends ModuleDependency.Template { | ||||||
|  | 	/** | ||||||
|  | 	 * @param {Dependency} dependency the dependency for which the template should be applied | ||||||
|  | 	 * @param {ReplaceSource} source the current replace source which can be modified | ||||||
|  | 	 * @param {DependencyTemplateContext} templateContext the context object | ||||||
|  | 	 * @returns {void} | ||||||
|  | 	 */ | ||||||
|  | 	apply(dependency, source, templateContext) { | ||||||
|  | 		const { | ||||||
|  | 			chunkGraph, | ||||||
|  | 			moduleGraph, | ||||||
|  | 			runtimeRequirements, | ||||||
|  | 			runtimeTemplate, | ||||||
|  | 			runtime | ||||||
|  | 		} = templateContext; | ||||||
|  | 		const dep = /** @type {URLDependency} */ (dependency); | ||||||
|  | 
 | ||||||
|  | 		const connection = moduleGraph.getConnection(dep); | ||||||
|  | 		if (connection && !connection.isActive(runtime)) return; | ||||||
|  | 
 | ||||||
|  | 		runtimeRequirements.add(RuntimeGlobals.baseURI); | ||||||
|  | 		runtimeRequirements.add(RuntimeGlobals.require); | ||||||
|  | 
 | ||||||
|  | 		source.replace( | ||||||
|  | 			dep.range[0], | ||||||
|  | 			dep.range[1] - 1, | ||||||
|  | 			`new URL(/* asset import */ ${runtimeTemplate.moduleRaw({ | ||||||
|  | 				chunkGraph, | ||||||
|  | 				module: moduleGraph.getModule(dep), | ||||||
|  | 				request: dep.request, | ||||||
|  | 				runtimeRequirements, | ||||||
|  | 				weak: false | ||||||
|  | 			})}, ${RuntimeGlobals.baseURI})` | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | module.exports = URLDependency; | ||||||
|  | @ -0,0 +1,78 @@ | ||||||
|  | /* | ||||||
|  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | ||||||
|  | 	Author Ivan Kopeykin @vankop | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | "use strict"; | ||||||
|  | 
 | ||||||
|  | const URLDependency = require("./URLDependency"); | ||||||
|  | 
 | ||||||
|  | /** @typedef {import("estree").NewExpression} NewExpressionNode */ | ||||||
|  | /** @typedef {import("../Compiler")} Compiler */ | ||||||
|  | /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ | ||||||
|  | 
 | ||||||
|  | class URLPlugin { | ||||||
|  | 	/** | ||||||
|  | 	 * @param {Compiler} compiler compiler | ||||||
|  | 	 */ | ||||||
|  | 	apply(compiler) { | ||||||
|  | 		compiler.hooks.compilation.tap( | ||||||
|  | 			"URLPlugin", | ||||||
|  | 			(compilation, { normalModuleFactory }) => { | ||||||
|  | 				compilation.dependencyFactories.set(URLDependency, normalModuleFactory); | ||||||
|  | 				compilation.dependencyTemplates.set( | ||||||
|  | 					URLDependency, | ||||||
|  | 					new URLDependency.Template() | ||||||
|  | 				); | ||||||
|  | 
 | ||||||
|  | 				/** | ||||||
|  | 				 * @param {JavascriptParser} parser parser | ||||||
|  | 				 */ | ||||||
|  | 				const parserCallback = parser => { | ||||||
|  | 					parser.hooks.new.for("URL").tap("URLPlugin", _expr => { | ||||||
|  | 						const expr = /** @type {NewExpressionNode} */ (_expr); | ||||||
|  | 
 | ||||||
|  | 						if (expr.arguments.length !== 2) return; | ||||||
|  | 
 | ||||||
|  | 						const [arg1, arg2] = expr.arguments; | ||||||
|  | 
 | ||||||
|  | 						if ( | ||||||
|  | 							arg2.type !== "MemberExpression" || | ||||||
|  | 							arg1.type === "SpreadElement" | ||||||
|  | 						) | ||||||
|  | 							return; | ||||||
|  | 
 | ||||||
|  | 						const chain = parser.extractMemberExpressionChain(arg2); | ||||||
|  | 
 | ||||||
|  | 						if ( | ||||||
|  | 							chain.members.length !== 1 || | ||||||
|  | 							chain.object.type !== "MetaProperty" || | ||||||
|  | 							chain.object.property.name !== "meta" || | ||||||
|  | 							chain.members[0] !== "url" | ||||||
|  | 						) | ||||||
|  | 							return; | ||||||
|  | 
 | ||||||
|  | 						const request = parser.evaluateExpression(arg1).asString(); | ||||||
|  | 
 | ||||||
|  | 						if (!request) return; | ||||||
|  | 
 | ||||||
|  | 						const dep = new URLDependency(request, expr.range); | ||||||
|  | 						dep.loc = expr.loc; | ||||||
|  | 						parser.state.module.addDependency(dep); | ||||||
|  | 						return true; | ||||||
|  | 					}); | ||||||
|  | 				}; | ||||||
|  | 
 | ||||||
|  | 				normalModuleFactory.hooks.parser | ||||||
|  | 					.for("javascript/auto") | ||||||
|  | 					.tap("URLPlugin", parserCallback); | ||||||
|  | 
 | ||||||
|  | 				normalModuleFactory.hooks.parser | ||||||
|  | 					.for("javascript/esm") | ||||||
|  | 					.tap("URLPlugin", parserCallback); | ||||||
|  | 			} | ||||||
|  | 		); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = URLPlugin; | ||||||
|  | @ -2551,6 +2551,10 @@ | ||||||
|             } |             } | ||||||
|           ] |           ] | ||||||
|         }, |         }, | ||||||
|  |         "dependency": { | ||||||
|  |           "description": "Match dependency type.", | ||||||
|  |           "type": "string" | ||||||
|  |         }, | ||||||
|         "descriptionData": { |         "descriptionData": { | ||||||
|           "description": "Match values of properties in the description file (usually package.json).", |           "description": "Match values of properties in the description file (usually package.json).", | ||||||
|           "type": "object", |           "type": "object", | ||||||
|  |  | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | a {} | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | const currentDir = require("url").pathToFileURL(__dirname); | ||||||
|  | 
 | ||||||
|  | it("should handle import.meta.url in URL()", () => { | ||||||
|  | 	const {href} = new URL("./index.css", import.meta.url); | ||||||
|  | 
 | ||||||
|  | 	expect(href).toBe(currentDir + "/public/index.css"); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | /** @type {import("../../../../").Configuration} */ | ||||||
|  | module.exports = { | ||||||
|  | 	mode: "development", | ||||||
|  | 	target: "node", | ||||||
|  | 	devtool: false, | ||||||
|  | 	output: { | ||||||
|  | 		assetModuleFilename: "[name][ext]", | ||||||
|  | 		publicPath: "public/" | ||||||
|  | 	}, | ||||||
|  | 	module: { | ||||||
|  | 		rules: [ | ||||||
|  | 			{ | ||||||
|  | 				test: /\.css$/, | ||||||
|  | 				type: "asset/resource" | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	experiments: { | ||||||
|  | 		asset: true | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | a {} | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | const currentDir = require("url").pathToFileURL(__dirname); | ||||||
|  | 
 | ||||||
|  | it("should handle import.meta.url in URL()", () => { | ||||||
|  | 	const {href} = new URL("./index.css", import.meta.url); | ||||||
|  | 
 | ||||||
|  | 	expect(href).toBe(currentDir + "/index.css"); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1,20 @@ | ||||||
|  | /** @type {import("../../../../").Configuration} */ | ||||||
|  | module.exports = { | ||||||
|  | 	mode: "development", | ||||||
|  | 	target: "node", | ||||||
|  | 	devtool: false, | ||||||
|  | 	output: { | ||||||
|  | 		assetModuleFilename: "[name][ext]" | ||||||
|  | 	}, | ||||||
|  | 	module: { | ||||||
|  | 		rules: [ | ||||||
|  | 			{ | ||||||
|  | 				test: /\.css$/, | ||||||
|  | 				type: "asset/resource" | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	experiments: { | ||||||
|  | 		asset: true | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | a {} | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | it("should handle import.meta.url in URL()", () => { | ||||||
|  | 	const {href} = new URL("./index.css", import.meta.url); | ||||||
|  | 
 | ||||||
|  | 	expect(href).toBe("file:///index.css"); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | /** @type {import("../../../../").Configuration} */ | ||||||
|  | module.exports = { | ||||||
|  | 	mode: "development", | ||||||
|  | 	target: "node", | ||||||
|  | 	devtool: false, | ||||||
|  | 	output: { | ||||||
|  | 		assetModuleFilename: "[name][ext]", | ||||||
|  | 		publicPath: "/" | ||||||
|  | 	}, | ||||||
|  | 	module: { | ||||||
|  | 		rules: [ | ||||||
|  | 			{ | ||||||
|  | 				test: /\.css$/, | ||||||
|  | 				type: "asset/resource" | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	experiments: { | ||||||
|  | 		asset: true | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | a {} | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | it("should handle import.meta.url in URL()", () => { | ||||||
|  | 	const {href} = new URL("./index.css", import.meta.url); | ||||||
|  | 
 | ||||||
|  | 	expect(href).toBe("https://test.cases/path/index.css"); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | let _URL = require("url").URL; | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  | 	moduleScope(scope) { | ||||||
|  | 		scope.URL = function URL(a, b) { | ||||||
|  | 			return new _URL(a, b); | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,20 @@ | ||||||
|  | /** @type {import("../../../../").Configuration} */ | ||||||
|  | module.exports = { | ||||||
|  | 	mode: "development", | ||||||
|  | 	target: "web", | ||||||
|  | 	devtool: false, | ||||||
|  | 	output: { | ||||||
|  | 		assetModuleFilename: "[name][ext]" | ||||||
|  | 	}, | ||||||
|  | 	module: { | ||||||
|  | 		rules: [ | ||||||
|  | 			{ | ||||||
|  | 				test: /\.css$/, | ||||||
|  | 				type: "asset/resource" | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	experiments: { | ||||||
|  | 		asset: true | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | a {} | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | it("should handle import.meta.url in URL()", () => { | ||||||
|  | 	const {href} = new URL("./index.css", import.meta.url); | ||||||
|  | 
 | ||||||
|  | 	expect(href).toBe("https://test.cases/path2/index.css"); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | let _URL = require("url").URL; | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  | 	moduleScope(scope) { | ||||||
|  | 		scope.URL = function URL(a, b) { | ||||||
|  | 			return new _URL(a, b); | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | /** @type {import("../../../../").Configuration} */ | ||||||
|  | module.exports = { | ||||||
|  | 	mode: "development", | ||||||
|  | 	target: "web", | ||||||
|  | 	devtool: false, | ||||||
|  | 	output: { | ||||||
|  | 		assetModuleFilename: "[name][ext]", | ||||||
|  | 		publicPath: "/path2/" | ||||||
|  | 	}, | ||||||
|  | 	module: { | ||||||
|  | 		rules: [ | ||||||
|  | 			{ | ||||||
|  | 				test: /\.css$/, | ||||||
|  | 				type: "asset/resource" | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	experiments: { | ||||||
|  | 		asset: true | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | a {} | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | it("should handle import.meta.url in URL()", () => { | ||||||
|  | 	const {href} = new URL("./index.css", import.meta.url); | ||||||
|  | 
 | ||||||
|  | 	expect(href).toBe("https://test.cases/path/index.css"); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | let _URL = require("url").URL; | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  | 	moduleScope(scope) { | ||||||
|  | 		scope.URL = function URL(a, b) { | ||||||
|  | 			return new _URL(a, b); | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,20 @@ | ||||||
|  | /** @type {import("../../../../").Configuration} */ | ||||||
|  | module.exports = { | ||||||
|  | 	mode: "development", | ||||||
|  | 	target: "webworker", | ||||||
|  | 	devtool: false, | ||||||
|  | 	output: { | ||||||
|  | 		assetModuleFilename: "[name][ext]" | ||||||
|  | 	}, | ||||||
|  | 	module: { | ||||||
|  | 		rules: [ | ||||||
|  | 			{ | ||||||
|  | 				test: /\.css$/, | ||||||
|  | 				type: "asset/resource" | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	experiments: { | ||||||
|  | 		asset: true | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | a {} | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | it("should handle import.meta.url in URL()", () => { | ||||||
|  | 	const {href} = new URL("./index.css", import.meta.url); | ||||||
|  | 
 | ||||||
|  | 	expect(href).toBe("https://test.cases/index.css"); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | let _URL = require("url").URL; | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  | 	moduleScope(scope) { | ||||||
|  | 		scope.URL = function URL(a, b) { | ||||||
|  | 			return new _URL(a, b); | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,21 @@ | ||||||
|  | /** @type {import("../../../../").Configuration} */ | ||||||
|  | module.exports = { | ||||||
|  | 	mode: "development", | ||||||
|  | 	target: "webworker", | ||||||
|  | 	devtool: false, | ||||||
|  | 	output: { | ||||||
|  | 		assetModuleFilename: "[name][ext]", | ||||||
|  | 		publicPath: "/" | ||||||
|  | 	}, | ||||||
|  | 	module: { | ||||||
|  | 		rules: [ | ||||||
|  | 			{ | ||||||
|  | 				test: /\.css$/, | ||||||
|  | 				type: "asset/resource" | ||||||
|  | 			} | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | 	experiments: { | ||||||
|  | 		asset: true | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| module.exports = class FakeDocument { | module.exports = class FakeDocument { | ||||||
| 	constructor() { | 	constructor() { | ||||||
| 		this.head = this.createElement("head"); | 		this.head = this.createElement("head"); | ||||||
|  | 		this.baseURI = "https://test.cases/path/index.html"; | ||||||
| 		this._elementsByTagName = new Map([["head", [this.head]]]); | 		this._elementsByTagName = new Map([["head", [this.head]]]); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6948,6 +6948,11 @@ declare interface RuleSetRule { | ||||||
| 	 */ | 	 */ | ||||||
| 	compiler?: RuleSetCondition; | 	compiler?: RuleSetCondition; | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Match dependency type. | ||||||
|  | 	 */ | ||||||
|  | 	dependency?: string; | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Match values of properties in the description file (usually package.json). | 	 * Match values of properties in the description file (usually package.json). | ||||||
| 	 */ | 	 */ | ||||||
|  | @ -8990,6 +8995,7 @@ declare namespace exports { | ||||||
| 		export let system: string; | 		export let system: string; | ||||||
| 		export let hasOwnProperty: string; | 		export let hasOwnProperty: string; | ||||||
| 		export let systemContext: string; | 		export let systemContext: string; | ||||||
|  | 		export let baseURI: string; | ||||||
| 	} | 	} | ||||||
| 	export const UsageState: Readonly<{ | 	export const UsageState: Readonly<{ | ||||||
| 		Unused: 0; | 		Unused: 0; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue