mirror of https://github.com/webpack/webpack.git
feat(CSS): pathinfo support
This commit is contained in:
commit
a5a06140e2
|
@ -8,6 +8,7 @@
|
||||||
const { ConcatSource, RawSource, CachedSource } = require("webpack-sources");
|
const { ConcatSource, RawSource, CachedSource } = require("webpack-sources");
|
||||||
const { UsageState } = require("./ExportsInfo");
|
const { UsageState } = require("./ExportsInfo");
|
||||||
const Template = require("./Template");
|
const Template = require("./Template");
|
||||||
|
const CssModulesPlugin = require("./css/CssModulesPlugin");
|
||||||
const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
|
const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
|
||||||
|
|
||||||
/** @typedef {import("webpack-sources").Source} Source */
|
/** @typedef {import("webpack-sources").Source} Source */
|
||||||
|
@ -163,8 +164,9 @@ class ModuleInfoHeaderPlugin {
|
||||||
apply(compiler) {
|
apply(compiler) {
|
||||||
const { _verbose: verbose } = this;
|
const { _verbose: verbose } = this;
|
||||||
compiler.hooks.compilation.tap("ModuleInfoHeaderPlugin", compilation => {
|
compiler.hooks.compilation.tap("ModuleInfoHeaderPlugin", compilation => {
|
||||||
const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
|
const javascriptHooks =
|
||||||
hooks.renderModulePackage.tap(
|
JavascriptModulesPlugin.getCompilationHooks(compilation);
|
||||||
|
javascriptHooks.renderModulePackage.tap(
|
||||||
"ModuleInfoHeaderPlugin",
|
"ModuleInfoHeaderPlugin",
|
||||||
(
|
(
|
||||||
moduleSource,
|
moduleSource,
|
||||||
|
@ -195,11 +197,7 @@ class ModuleInfoHeaderPlugin {
|
||||||
const source = new ConcatSource();
|
const source = new ConcatSource();
|
||||||
let header = cacheEntry.header;
|
let header = cacheEntry.header;
|
||||||
if (header === undefined) {
|
if (header === undefined) {
|
||||||
const req = module.readableIdentifier(requestShortener);
|
header = this.generateHeader(module, requestShortener);
|
||||||
const reqStr = req.replace(/\*\//g, "*_/");
|
|
||||||
const reqStrStar = "*".repeat(reqStr.length);
|
|
||||||
const headerStr = `/*!****${reqStrStar}****!*\\\n !*** ${reqStr} ***!\n \\****${reqStrStar}****/\n`;
|
|
||||||
header = new RawSource(headerStr);
|
|
||||||
cacheEntry.header = header;
|
cacheEntry.header = header;
|
||||||
}
|
}
|
||||||
source.add(header);
|
source.add(header);
|
||||||
|
@ -248,11 +246,69 @@ class ModuleInfoHeaderPlugin {
|
||||||
return cachedSource;
|
return cachedSource;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
hooks.chunkHash.tap("ModuleInfoHeaderPlugin", (chunk, hash) => {
|
javascriptHooks.chunkHash.tap(
|
||||||
|
"ModuleInfoHeaderPlugin",
|
||||||
|
(_chunk, hash) => {
|
||||||
|
hash.update("ModuleInfoHeaderPlugin");
|
||||||
|
hash.update("1");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const cssHooks = CssModulesPlugin.getCompilationHooks(compilation);
|
||||||
|
cssHooks.renderModulePackage.tap(
|
||||||
|
"ModuleInfoHeaderPlugin",
|
||||||
|
(moduleSource, module, { runtimeTemplate }) => {
|
||||||
|
const { requestShortener } = runtimeTemplate;
|
||||||
|
let cacheEntry;
|
||||||
|
let cache = caches.get(requestShortener);
|
||||||
|
if (cache === undefined) {
|
||||||
|
caches.set(requestShortener, (cache = new WeakMap()));
|
||||||
|
cache.set(
|
||||||
|
module,
|
||||||
|
(cacheEntry = { header: undefined, full: new WeakMap() })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
cacheEntry = cache.get(module);
|
||||||
|
if (cacheEntry === undefined) {
|
||||||
|
cache.set(
|
||||||
|
module,
|
||||||
|
(cacheEntry = { header: undefined, full: new WeakMap() })
|
||||||
|
);
|
||||||
|
} else if (!verbose) {
|
||||||
|
const cachedSource = cacheEntry.full.get(moduleSource);
|
||||||
|
if (cachedSource !== undefined) return cachedSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const source = new ConcatSource();
|
||||||
|
let header = cacheEntry.header;
|
||||||
|
if (header === undefined) {
|
||||||
|
header = this.generateHeader(module, requestShortener);
|
||||||
|
cacheEntry.header = header;
|
||||||
|
}
|
||||||
|
source.add(header);
|
||||||
|
source.add(moduleSource);
|
||||||
|
const cachedSource = new CachedSource(source);
|
||||||
|
cacheEntry.full.set(moduleSource, cachedSource);
|
||||||
|
return cachedSource;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
cssHooks.chunkHash.tap("ModuleInfoHeaderPlugin", (_chunk, hash) => {
|
||||||
hash.update("ModuleInfoHeaderPlugin");
|
hash.update("ModuleInfoHeaderPlugin");
|
||||||
hash.update("1");
|
hash.update("1");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Module} module the module
|
||||||
|
* @param {RequestShortener} requestShortener request shortener
|
||||||
|
* @returns {RawSource} the header
|
||||||
|
*/
|
||||||
|
generateHeader(module, requestShortener) {
|
||||||
|
const req = module.readableIdentifier(requestShortener);
|
||||||
|
const reqStr = req.replace(/\*\//g, "*_/");
|
||||||
|
const reqStrStar = "*".repeat(reqStr.length);
|
||||||
|
const headerStr = `/*!****${reqStrStar}****!*\\\n !*** ${reqStr} ***!\n \\****${reqStrStar}****/\n`;
|
||||||
|
return new RawSource(headerStr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
module.exports = ModuleInfoHeaderPlugin;
|
module.exports = ModuleInfoHeaderPlugin;
|
||||||
|
|
|
@ -5,13 +5,16 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const { SyncWaterfallHook, SyncHook } = require("tapable");
|
||||||
const {
|
const {
|
||||||
ConcatSource,
|
ConcatSource,
|
||||||
PrefixSource,
|
PrefixSource,
|
||||||
ReplaceSource,
|
ReplaceSource,
|
||||||
CachedSource
|
CachedSource
|
||||||
} = require("webpack-sources");
|
} = require("webpack-sources");
|
||||||
|
const Compilation = require("../Compilation");
|
||||||
const CssModule = require("../CssModule");
|
const CssModule = require("../CssModule");
|
||||||
|
const { tryRunOrWebpackError } = require("../HookWebpackError");
|
||||||
const HotUpdateChunk = require("../HotUpdateChunk");
|
const HotUpdateChunk = require("../HotUpdateChunk");
|
||||||
const {
|
const {
|
||||||
CSS_MODULE_TYPE,
|
CSS_MODULE_TYPE,
|
||||||
|
@ -43,14 +46,27 @@ const CssParser = require("./CssParser");
|
||||||
/** @typedef {import("../Chunk")} Chunk */
|
/** @typedef {import("../Chunk")} Chunk */
|
||||||
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
||||||
/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
|
/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
|
||||||
/** @typedef {import("../Compilation")} Compilation */
|
/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
|
||||||
/** @typedef {import("../Compiler")} Compiler */
|
/** @typedef {import("../Compiler")} Compiler */
|
||||||
/** @typedef {import("../CssModule").Inheritance} Inheritance */
|
/** @typedef {import("../CssModule").Inheritance} Inheritance */
|
||||||
/** @typedef {import("../DependencyTemplate").CssExportsData} CssExportsData */
|
/** @typedef {import("../DependencyTemplate").CssExportsData} CssExportsData */
|
||||||
/** @typedef {import("../Module")} Module */
|
/** @typedef {import("../Module")} Module */
|
||||||
|
/** @typedef {import("../Template").RuntimeTemplate} RuntimeTemplate */
|
||||||
/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */
|
/** @typedef {import("../TemplatedPathPlugin").TemplatePath} TemplatePath */
|
||||||
|
/** @typedef {import("../util/Hash")} Hash */
|
||||||
/** @typedef {import("../util/memoize")} Memoize */
|
/** @typedef {import("../util/memoize")} Memoize */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} ChunkRenderContext
|
||||||
|
* @property {RuntimeTemplate} runtimeTemplate runtime template
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} CompilationHooks
|
||||||
|
* @property {SyncWaterfallHook<[Source, Module, ChunkRenderContext]>} renderModulePackage
|
||||||
|
* @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash
|
||||||
|
*/
|
||||||
|
|
||||||
const getCssLoadingRuntimeModule = memoize(() =>
|
const getCssLoadingRuntimeModule = memoize(() =>
|
||||||
require("./CssLoadingRuntimeModule")
|
require("./CssLoadingRuntimeModule")
|
||||||
);
|
);
|
||||||
|
@ -121,6 +137,9 @@ const validateParserOptions = {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @type {WeakMap<Compilation, CompilationHooks>} */
|
||||||
|
const compilationHooksMap = new WeakMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} str string
|
* @param {string} str string
|
||||||
* @param {boolean=} omitOptionalUnderscore if true, optional underscore is not added
|
* @param {boolean=} omitOptionalUnderscore if true, optional underscore is not added
|
||||||
|
@ -166,9 +185,34 @@ const lzwEncode = str => {
|
||||||
return encoded;
|
return encoded;
|
||||||
};
|
};
|
||||||
|
|
||||||
const plugin = "CssModulesPlugin";
|
const PLUGIN_NAME = "CssModulesPlugin";
|
||||||
|
|
||||||
class CssModulesPlugin {
|
class CssModulesPlugin {
|
||||||
|
/**
|
||||||
|
* @param {Compilation} compilation the compilation
|
||||||
|
* @returns {CompilationHooks} the attached hooks
|
||||||
|
*/
|
||||||
|
static getCompilationHooks(compilation) {
|
||||||
|
if (!(compilation instanceof Compilation)) {
|
||||||
|
throw new TypeError(
|
||||||
|
"The 'compilation' argument must be an instance of Compilation"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let hooks = compilationHooksMap.get(compilation);
|
||||||
|
if (hooks === undefined) {
|
||||||
|
hooks = {
|
||||||
|
renderModulePackage: new SyncWaterfallHook([
|
||||||
|
"source",
|
||||||
|
"module",
|
||||||
|
"renderContext"
|
||||||
|
]),
|
||||||
|
chunkHash: new SyncHook(["chunk", "hash", "context"])
|
||||||
|
};
|
||||||
|
compilationHooksMap.set(compilation, hooks);
|
||||||
|
}
|
||||||
|
return hooks;
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
/** @type {WeakMap<Source, { undoPath: string, inheritance: Inheritance, source: CachedSource }>} */
|
/** @type {WeakMap<Source, { undoPath: string, inheritance: Inheritance, source: CachedSource }>} */
|
||||||
this._moduleCache = new WeakMap();
|
this._moduleCache = new WeakMap();
|
||||||
|
@ -181,8 +225,9 @@ class CssModulesPlugin {
|
||||||
*/
|
*/
|
||||||
apply(compiler) {
|
apply(compiler) {
|
||||||
compiler.hooks.compilation.tap(
|
compiler.hooks.compilation.tap(
|
||||||
plugin,
|
PLUGIN_NAME,
|
||||||
(compilation, { normalModuleFactory }) => {
|
(compilation, { normalModuleFactory }) => {
|
||||||
|
const hooks = CssModulesPlugin.getCompilationHooks(compilation);
|
||||||
const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
|
const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
|
||||||
compilation.dependencyFactories.set(
|
compilation.dependencyFactories.set(
|
||||||
CssUrlDependency,
|
CssUrlDependency,
|
||||||
|
@ -228,7 +273,7 @@ class CssModulesPlugin {
|
||||||
]) {
|
]) {
|
||||||
normalModuleFactory.hooks.createParser
|
normalModuleFactory.hooks.createParser
|
||||||
.for(type)
|
.for(type)
|
||||||
.tap(plugin, parserOptions => {
|
.tap(PLUGIN_NAME, parserOptions => {
|
||||||
validateParserOptions[type](parserOptions);
|
validateParserOptions[type](parserOptions);
|
||||||
const { namedExports } = parserOptions;
|
const { namedExports } = parserOptions;
|
||||||
|
|
||||||
|
@ -252,7 +297,7 @@ class CssModulesPlugin {
|
||||||
});
|
});
|
||||||
normalModuleFactory.hooks.createGenerator
|
normalModuleFactory.hooks.createGenerator
|
||||||
.for(type)
|
.for(type)
|
||||||
.tap(plugin, generatorOptions => {
|
.tap(PLUGIN_NAME, generatorOptions => {
|
||||||
validateGeneratorOptions[type](generatorOptions);
|
validateGeneratorOptions[type](generatorOptions);
|
||||||
|
|
||||||
return generatorOptions.exportsOnly
|
return generatorOptions.exportsOnly
|
||||||
|
@ -269,7 +314,7 @@ class CssModulesPlugin {
|
||||||
});
|
});
|
||||||
normalModuleFactory.hooks.createModuleClass
|
normalModuleFactory.hooks.createModuleClass
|
||||||
.for(type)
|
.for(type)
|
||||||
.tap(plugin, (createData, resolveData) => {
|
.tap(PLUGIN_NAME, (createData, resolveData) => {
|
||||||
if (resolveData.dependencies.length > 0) {
|
if (resolveData.dependencies.length > 0) {
|
||||||
// When CSS is imported from CSS there is only one dependency
|
// When CSS is imported from CSS there is only one dependency
|
||||||
const dependency = resolveData.dependencies[0];
|
const dependency = resolveData.dependencies[0];
|
||||||
|
@ -341,9 +386,18 @@ class CssModulesPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
compilation.hooks.chunkHash.tap(
|
||||||
|
"CssModulesPlugin",
|
||||||
|
(chunk, hash, context) => {
|
||||||
|
hooks.chunkHash.call(chunk, hash, context);
|
||||||
|
}
|
||||||
|
);
|
||||||
compilation.hooks.contentHash.tap("CssModulesPlugin", chunk => {
|
compilation.hooks.contentHash.tap("CssModulesPlugin", chunk => {
|
||||||
const {
|
const {
|
||||||
chunkGraph,
|
chunkGraph,
|
||||||
|
codeGenerationResults,
|
||||||
|
moduleGraph,
|
||||||
|
runtimeTemplate,
|
||||||
outputOptions: {
|
outputOptions: {
|
||||||
hashSalt,
|
hashSalt,
|
||||||
hashDigest,
|
hashDigest,
|
||||||
|
@ -351,19 +405,27 @@ class CssModulesPlugin {
|
||||||
hashFunction
|
hashFunction
|
||||||
}
|
}
|
||||||
} = compilation;
|
} = compilation;
|
||||||
const modules = orderedCssModulesPerChunk.get(chunk);
|
|
||||||
if (modules === undefined) return;
|
|
||||||
const hash = createHash(hashFunction);
|
const hash = createHash(hashFunction);
|
||||||
if (hashSalt) hash.update(hashSalt);
|
if (hashSalt) hash.update(hashSalt);
|
||||||
for (const module of modules) {
|
hooks.chunkHash.call(chunk, hash, {
|
||||||
hash.update(chunkGraph.getModuleHash(module, chunk.runtime));
|
chunkGraph,
|
||||||
|
codeGenerationResults,
|
||||||
|
moduleGraph,
|
||||||
|
runtimeTemplate
|
||||||
|
});
|
||||||
|
const modules = orderedCssModulesPerChunk.get(chunk);
|
||||||
|
if (modules) {
|
||||||
|
for (const module of modules) {
|
||||||
|
hash.update(chunkGraph.getModuleHash(module, chunk.runtime));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const digest = /** @type {string} */ (hash.digest(hashDigest));
|
const digest = /** @type {string} */ (hash.digest(hashDigest));
|
||||||
chunk.contentHash.css = nonNumericOnlyHash(digest, hashDigestLength);
|
chunk.contentHash.css = nonNumericOnlyHash(digest, hashDigestLength);
|
||||||
});
|
});
|
||||||
compilation.hooks.renderManifest.tap(plugin, (result, options) => {
|
compilation.hooks.renderManifest.tap(PLUGIN_NAME, (result, options) => {
|
||||||
const { chunkGraph } = compilation;
|
const { chunkGraph } = compilation;
|
||||||
const { hash, chunk, codeGenerationResults } = options;
|
const { hash, chunk, codeGenerationResults, runtimeTemplate } =
|
||||||
|
options;
|
||||||
|
|
||||||
if (chunk instanceof HotUpdateChunk) return result;
|
if (chunk instanceof HotUpdateChunk) return result;
|
||||||
|
|
||||||
|
@ -397,7 +459,9 @@ class CssModulesPlugin {
|
||||||
cssHeadDataCompression:
|
cssHeadDataCompression:
|
||||||
compilation.outputOptions.cssHeadDataCompression,
|
compilation.outputOptions.cssHeadDataCompression,
|
||||||
undoPath,
|
undoPath,
|
||||||
modules
|
modules,
|
||||||
|
runtimeTemplate,
|
||||||
|
hooks
|
||||||
}),
|
}),
|
||||||
filename,
|
filename,
|
||||||
info,
|
info,
|
||||||
|
@ -441,13 +505,13 @@ class CssModulesPlugin {
|
||||||
};
|
};
|
||||||
compilation.hooks.runtimeRequirementInTree
|
compilation.hooks.runtimeRequirementInTree
|
||||||
.for(RuntimeGlobals.hasCssModules)
|
.for(RuntimeGlobals.hasCssModules)
|
||||||
.tap(plugin, handler);
|
.tap(PLUGIN_NAME, handler);
|
||||||
compilation.hooks.runtimeRequirementInTree
|
compilation.hooks.runtimeRequirementInTree
|
||||||
.for(RuntimeGlobals.ensureChunkHandlers)
|
.for(RuntimeGlobals.ensureChunkHandlers)
|
||||||
.tap(plugin, handler);
|
.tap(PLUGIN_NAME, handler);
|
||||||
compilation.hooks.runtimeRequirementInTree
|
compilation.hooks.runtimeRequirementInTree
|
||||||
.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
|
.for(RuntimeGlobals.hmrDownloadUpdateHandlers)
|
||||||
.tap(plugin, handler);
|
.tap(PLUGIN_NAME, handler);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -600,6 +664,8 @@ class CssModulesPlugin {
|
||||||
* @param {ChunkGraph} options.chunkGraph chunk graph
|
* @param {ChunkGraph} options.chunkGraph chunk graph
|
||||||
* @param {CodeGenerationResults} options.codeGenerationResults code generation results
|
* @param {CodeGenerationResults} options.codeGenerationResults code generation results
|
||||||
* @param {CssModule} options.module css module
|
* @param {CssModule} options.module css module
|
||||||
|
* @param {RuntimeTemplate} options.runtimeTemplate runtime template
|
||||||
|
* @param {CompilationHooks} options.hooks hooks
|
||||||
* @returns {Source} css module source
|
* @returns {Source} css module source
|
||||||
*/
|
*/
|
||||||
renderModule({
|
renderModule({
|
||||||
|
@ -608,7 +674,9 @@ class CssModulesPlugin {
|
||||||
chunk,
|
chunk,
|
||||||
chunkGraph,
|
chunkGraph,
|
||||||
codeGenerationResults,
|
codeGenerationResults,
|
||||||
module
|
module,
|
||||||
|
hooks,
|
||||||
|
runtimeTemplate
|
||||||
}) {
|
}) {
|
||||||
const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
|
const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
|
||||||
const moduleSourceContent =
|
const moduleSourceContent =
|
||||||
|
@ -722,7 +790,13 @@ class CssModulesPlugin {
|
||||||
: ""
|
: ""
|
||||||
}${esModule ? "&" : ""}${escapeCss(moduleId)}`
|
}${esModule ? "&" : ""}${escapeCss(moduleId)}`
|
||||||
);
|
);
|
||||||
return source;
|
return tryRunOrWebpackError(
|
||||||
|
() =>
|
||||||
|
hooks.renderModulePackage.call(source, module, {
|
||||||
|
runtimeTemplate
|
||||||
|
}),
|
||||||
|
"CssModulesPlugin.getCompilationHooks().renderModulePackage"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -734,6 +808,8 @@ class CssModulesPlugin {
|
||||||
* @param {ChunkGraph} options.chunkGraph chunk graph
|
* @param {ChunkGraph} options.chunkGraph chunk graph
|
||||||
* @param {CodeGenerationResults} options.codeGenerationResults code generation results
|
* @param {CodeGenerationResults} options.codeGenerationResults code generation results
|
||||||
* @param {CssModule[]} options.modules ordered css modules
|
* @param {CssModule[]} options.modules ordered css modules
|
||||||
|
* @param {RuntimeTemplate} options.runtimeTemplate runtime template
|
||||||
|
* @param {CompilationHooks} options.hooks hooks
|
||||||
* @returns {Source} generated source
|
* @returns {Source} generated source
|
||||||
*/
|
*/
|
||||||
renderChunk({
|
renderChunk({
|
||||||
|
@ -743,7 +819,9 @@ class CssModulesPlugin {
|
||||||
chunk,
|
chunk,
|
||||||
chunkGraph,
|
chunkGraph,
|
||||||
codeGenerationResults,
|
codeGenerationResults,
|
||||||
modules
|
modules,
|
||||||
|
runtimeTemplate,
|
||||||
|
hooks
|
||||||
}) {
|
}) {
|
||||||
const source = new ConcatSource();
|
const source = new ConcatSource();
|
||||||
/** @type {string[]} */
|
/** @type {string[]} */
|
||||||
|
@ -756,7 +834,9 @@ class CssModulesPlugin {
|
||||||
chunk,
|
chunk,
|
||||||
chunkGraph,
|
chunkGraph,
|
||||||
codeGenerationResults,
|
codeGenerationResults,
|
||||||
module
|
module,
|
||||||
|
runtimeTemplate,
|
||||||
|
hooks
|
||||||
});
|
});
|
||||||
source.add(moduleSource);
|
source.add(moduleSource);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -772,6 +852,7 @@ class CssModulesPlugin {
|
||||||
true
|
true
|
||||||
)}:${cssHeadDataCompression ? lzwEncode(metaDataStr) : metaDataStr};}`
|
)}:${cssHeadDataCompression ? lzwEncode(metaDataStr) : metaDataStr};}`
|
||||||
);
|
);
|
||||||
|
chunk.rendered = true;
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,14 @@
|
||||||
|
import * as style from "./style.css";
|
||||||
|
|
||||||
|
it("should compile and load style on demand", done => {
|
||||||
|
expect(style).toEqual(nsObj({}));
|
||||||
|
import("./style2.css").then(x => {
|
||||||
|
expect(x).toEqual(nsObj({}));
|
||||||
|
const style = getComputedStyle(document.body);
|
||||||
|
expect(style.getPropertyValue("background")).toBe(" red");
|
||||||
|
expect(style.getPropertyValue("margin")).toBe(" 10px");
|
||||||
|
expect(style.getPropertyValue("color")).toBe(" green");
|
||||||
|
expect(style.getPropertyValue("padding")).toBe(" 20px 10px");
|
||||||
|
done();
|
||||||
|
}, done);
|
||||||
|
});
|
|
@ -0,0 +1,3 @@
|
||||||
|
body {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
@import "style-imported.css";
|
||||||
|
body {
|
||||||
|
background: red;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
body {
|
||||||
|
padding: 20px 10px;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
@import "./style2-imported.css";
|
||||||
|
body {
|
||||||
|
color: green;
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
moduleScope(scope) {
|
||||||
|
const link = scope.window.document.createElement("link");
|
||||||
|
link.rel = "stylesheet";
|
||||||
|
link.href = "bundle0.css";
|
||||||
|
scope.window.document.head.appendChild(link);
|
||||||
|
},
|
||||||
|
findBundle: function (i, options) {
|
||||||
|
const source = fs.readFileSync(
|
||||||
|
path.resolve(options.output.path, "bundle0.css"),
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!source.includes(`/*!********************************!*\\
|
||||||
|
!*** css ./style-imported.css ***!
|
||||||
|
\\********************************/`) &&
|
||||||
|
!source.includes(`/*!***********************!*\\
|
||||||
|
!*** css ./style.css ***!
|
||||||
|
\\***********************/`)
|
||||||
|
) {
|
||||||
|
throw new Error("The `pathinfo` option doesn't work.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "./bundle0.js";
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,13 @@
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
target: "web",
|
||||||
|
mode: "development",
|
||||||
|
devtool: false,
|
||||||
|
output: {
|
||||||
|
pathinfo: true,
|
||||||
|
cssChunkFilename: "[name].[chunkhash].css"
|
||||||
|
},
|
||||||
|
experiments: {
|
||||||
|
css: true
|
||||||
|
}
|
||||||
|
};
|
|
@ -207,23 +207,26 @@ class FakeSheet {
|
||||||
.replace(/^https:\/\/example\.com\//, "")
|
.replace(/^https:\/\/example\.com\//, "")
|
||||||
);
|
);
|
||||||
let css = fs.readFileSync(filepath, "utf-8");
|
let css = fs.readFileSync(filepath, "utf-8");
|
||||||
css = css.replace(/@import url\("([^"]+)"\);/g, (match, url) => {
|
css = css
|
||||||
if (!/^https:\/\/test\.cases\/path\//.test(url)) {
|
// Remove comments
|
||||||
return url;
|
.replace(/\/\*.*?\*\//gms, "")
|
||||||
}
|
.replace(/@import url\("([^"]+)"\);/g, (match, url) => {
|
||||||
|
if (!/^https:\/\/test\.cases\/path\//.test(url)) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
if (url.startsWith("#")) {
|
if (url.startsWith("#")) {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs.readFileSync(
|
return fs.readFileSync(
|
||||||
path.resolve(
|
path.resolve(
|
||||||
this._basePath,
|
this._basePath,
|
||||||
url.replace(/^https:\/\/test\.cases\/path\//, "")
|
url.replace(/^https:\/\/test\.cases\/path\//, "")
|
||||||
),
|
),
|
||||||
"utf-8"
|
"utf-8"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
walkCssTokens(css, {
|
walkCssTokens(css, {
|
||||||
isSelector() {
|
isSelector() {
|
||||||
return selector === undefined;
|
return selector === undefined;
|
||||||
|
|
Loading…
Reference in New Issue