mirror of https://github.com/webpack/webpack.git
test: added
This commit is contained in:
parent
d5f19bf9a4
commit
5e2abae79e
|
@ -453,6 +453,9 @@ class CssLoadingRuntimeModule extends RuntimeModule {
|
||||||
}.css = ${runtimeTemplate.basicFunction(
|
}.css = ${runtimeTemplate.basicFunction(
|
||||||
"chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList",
|
"chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList",
|
||||||
[
|
[
|
||||||
|
isNeutralPlatform
|
||||||
|
? "if (typeof document === 'undefined') return;"
|
||||||
|
: "",
|
||||||
"applyHandlers.push(applyHandler);",
|
"applyHandlers.push(applyHandler);",
|
||||||
`chunkIds.forEach(${runtimeTemplate.basicFunction("chunkId", [
|
`chunkIds.forEach(${runtimeTemplate.basicFunction("chunkId", [
|
||||||
`var filename = ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
|
`var filename = ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
|
||||||
|
|
|
@ -378,14 +378,14 @@ class CssModulesPlugin {
|
||||||
|
|
||||||
const hmrCode = Template.asString([
|
const hmrCode = Template.asString([
|
||||||
"",
|
"",
|
||||||
`var exports = ${stringifiedExports};`,
|
`var __webpack_css_exports__ = ${stringifiedExports};`,
|
||||||
"// only invalidate when locals change",
|
"// only invalidate when locals change",
|
||||||
"if (module.hot.data && module.hot.data.exports && module.hot.data.exports != exports) {",
|
"if (module.hot.data && module.hot.data.__webpack_css_exports__ && module.hot.data.__webpack_css_exports__ != __webpack_css_exports__) {",
|
||||||
Template.indent("module.hot.invalidate();"),
|
Template.indent("module.hot.invalidate();"),
|
||||||
"} else {",
|
"} else {",
|
||||||
Template.indent("module.hot.accept();"),
|
Template.indent("module.hot.accept();"),
|
||||||
"}",
|
"}",
|
||||||
"module.hot.dispose(function(data) { data.exports = exports; });"
|
"module.hot.dispose(function(data) { data.__webpack_css_exports__ = __webpack_css_exports__; });"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return new ConcatSource(source, "\n", new RawSource(hmrCode));
|
return new ConcatSource(source, "\n", new RawSource(hmrCode));
|
||||||
|
|
|
@ -97,6 +97,17 @@ const describeCases = config => {
|
||||||
new webpack.LoaderOptionsPlugin(fakeUpdateLoaderOptions)
|
new webpack.LoaderOptionsPlugin(fakeUpdateLoaderOptions)
|
||||||
);
|
);
|
||||||
if (!options.recordsPath) options.recordsPath = recordsPath;
|
if (!options.recordsPath) options.recordsPath = recordsPath;
|
||||||
|
let testConfig = {};
|
||||||
|
try {
|
||||||
|
// try to load a test file
|
||||||
|
testConfig = Object.assign(
|
||||||
|
testConfig,
|
||||||
|
require(path.join(testDirectory, "test.config.js"))
|
||||||
|
);
|
||||||
|
} catch (_err) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
compiler = webpack(options);
|
compiler = webpack(options);
|
||||||
compiler.run((err, stats) => {
|
compiler.run((err, stats) => {
|
||||||
if (err) return done(err);
|
if (err) return done(err);
|
||||||
|
@ -139,6 +150,7 @@ const describeCases = config => {
|
||||||
return `./${url}`;
|
return `./${url}`;
|
||||||
};
|
};
|
||||||
const window = {
|
const window = {
|
||||||
|
_elements: [],
|
||||||
fetch: async url => {
|
fetch: async url => {
|
||||||
try {
|
try {
|
||||||
const buffer = await new Promise((resolve, reject) => {
|
const buffer = await new Promise((resolve, reject) => {
|
||||||
|
@ -169,30 +181,67 @@ const describeCases = config => {
|
||||||
createElement(type) {
|
createElement(type) {
|
||||||
return {
|
return {
|
||||||
_type: type,
|
_type: type,
|
||||||
_attrs: {},
|
sheet: {},
|
||||||
|
getAttribute(name) {
|
||||||
|
return this[name];
|
||||||
|
},
|
||||||
setAttribute(name, value) {
|
setAttribute(name, value) {
|
||||||
this._attrs[name] = value;
|
this[name] = value;
|
||||||
|
},
|
||||||
|
removeAttribute(name) {
|
||||||
|
delete this[name];
|
||||||
},
|
},
|
||||||
parentNode: {
|
parentNode: {
|
||||||
removeChild(node) {
|
removeChild(node) {
|
||||||
// ok
|
window._elements = window._elements.filter(
|
||||||
|
item => item !== node
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
head: {
|
head: {
|
||||||
appendChild(element) {
|
appendChild(element) {
|
||||||
|
window._elements.push(element);
|
||||||
|
|
||||||
if (element._type === "script") {
|
if (element._type === "script") {
|
||||||
// run it
|
// run it
|
||||||
Promise.resolve().then(() => {
|
Promise.resolve().then(() => {
|
||||||
_require(urlToRelativePath(element.src));
|
_require(urlToRelativePath(element.src));
|
||||||
});
|
});
|
||||||
|
} else if (element._type === "link") {
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
if (element.onload) {
|
||||||
|
// run it
|
||||||
|
element.onload({ type: "load" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
insertBefore(element, before) {
|
||||||
|
window._elements.push(element);
|
||||||
|
|
||||||
|
if (element._type === "script") {
|
||||||
|
// run it
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
_require(urlToRelativePath(element.src));
|
||||||
|
});
|
||||||
|
} else if (element._type === "link") {
|
||||||
|
// run it
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
element.onload({ type: "load" });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getElementsByTagName(name) {
|
getElementsByTagName(name) {
|
||||||
if (name === "head") return [this.head];
|
if (name === "head") return [this.head];
|
||||||
if (name === "script") return [];
|
if (name === "script" || name === "link") {
|
||||||
|
return window._elements.filter(
|
||||||
|
item => item._type === name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
throw new Error("Not supported");
|
throw new Error("Not supported");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -209,6 +258,14 @@ const describeCases = config => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const moduleScope = {
|
||||||
|
window
|
||||||
|
};
|
||||||
|
|
||||||
|
if (testConfig.moduleScope) {
|
||||||
|
testConfig.moduleScope(moduleScope, options);
|
||||||
|
}
|
||||||
|
|
||||||
function _next(callback) {
|
function _next(callback) {
|
||||||
fakeUpdateLoaderOptions.updateIndex++;
|
fakeUpdateLoaderOptions.updateIndex++;
|
||||||
compiler.run((err, stats) => {
|
compiler.run((err, stats) => {
|
||||||
|
@ -249,6 +306,9 @@ const describeCases = config => {
|
||||||
function _require(module) {
|
function _require(module) {
|
||||||
if (module.startsWith("./")) {
|
if (module.startsWith("./")) {
|
||||||
const p = path.join(outputDirectory, module);
|
const p = path.join(outputDirectory, module);
|
||||||
|
if (module.endsWith(".css")) {
|
||||||
|
return fs.readFileSync(p, "utf-8");
|
||||||
|
}
|
||||||
if (module.endsWith(".json")) {
|
if (module.endsWith(".json")) {
|
||||||
return JSON.parse(fs.readFileSync(p, "utf-8"));
|
return JSON.parse(fs.readFileSync(p, "utf-8"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import * as styles from "./style.module.css";
|
||||||
|
|
||||||
|
it("should work", async function (done) {
|
||||||
|
expect(styles).toMatchObject({ class: "_style_module_css-class" });
|
||||||
|
|
||||||
|
const styles2 = await import("./style2.module.css");
|
||||||
|
|
||||||
|
expect(styles2).toMatchObject({
|
||||||
|
foo: "_style2_module_css-foo"
|
||||||
|
});
|
||||||
|
|
||||||
|
module.hot.accept(["./style.module.css", "./style2.module.css"], () => {
|
||||||
|
expect(styles).toMatchObject({
|
||||||
|
"class-other": "_style_module_css-class-other"
|
||||||
|
});
|
||||||
|
import("./style2.module.css").then(styles2 => {
|
||||||
|
expect(styles2).toMatchObject({
|
||||||
|
"bar": "_style2_module_css-bar"
|
||||||
|
});
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
NEXT(require("../../update")(done));
|
||||||
|
});
|
||||||
|
|
||||||
|
module.hot.accept();
|
|
@ -0,0 +1,7 @@
|
||||||
|
.class {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
.class-other {
|
||||||
|
color: blue;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
.foo {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
.bar {
|
||||||
|
color: blue;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
moduleScope(scope) {
|
||||||
|
const link = scope.window.document.createElement("link");
|
||||||
|
link.rel = "stylesheet";
|
||||||
|
link.href = "https://test.cases/path/bundle.css";
|
||||||
|
scope.window.document.head.appendChild(link);
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
mode: "development",
|
||||||
|
devtool: false,
|
||||||
|
experiments: {
|
||||||
|
css: true
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,25 @@
|
||||||
|
it("should work", async function (done) {
|
||||||
|
const styles = await import(/* webpackFetchPriority: "high" */ "./style.module.css");
|
||||||
|
|
||||||
|
expect(styles).toMatchObject({
|
||||||
|
class: "_style_module_css-class"
|
||||||
|
});
|
||||||
|
|
||||||
|
module.hot.accept("./style.module.css", () => {
|
||||||
|
import("./style.module.css").then(styles => {
|
||||||
|
expect(styles).toMatchObject({
|
||||||
|
"class-other": "_style_module_css-class-other"
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
window.document.getElementsByTagName('link')[0].getAttribute('fetchpriority')
|
||||||
|
).toBe('high')
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
NEXT(require("../../update")(done));
|
||||||
|
});
|
||||||
|
|
||||||
|
module.hot.accept();
|
|
@ -0,0 +1,7 @@
|
||||||
|
.class {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
.class-other {
|
||||||
|
color: blue;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
mode: "development",
|
||||||
|
devtool: false,
|
||||||
|
experiments: {
|
||||||
|
css: true
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
import "./style.css";
|
||||||
|
|
||||||
|
const getFile = name =>
|
||||||
|
__non_webpack_require__("fs").readFileSync(
|
||||||
|
__non_webpack_require__("path").join(__dirname, name),
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
|
||||||
|
it("should work", async function (done) {
|
||||||
|
const style = getFile("bundle.css");
|
||||||
|
expect(style).toContain("color: red;");
|
||||||
|
|
||||||
|
await import("./style2.css");
|
||||||
|
|
||||||
|
const style2 = getFile("style2_css.css");
|
||||||
|
expect(style2).toContain("color: red;");
|
||||||
|
|
||||||
|
NEXT(require("../../update")(done, true, () => {
|
||||||
|
const style = getFile("bundle.css");
|
||||||
|
expect(style).toContain("color: blue;");
|
||||||
|
const style2 = getFile("style2_css.css");
|
||||||
|
expect(style2).toContain("color: blue;");
|
||||||
|
|
||||||
|
done();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
module.hot.accept();
|
|
@ -0,0 +1,7 @@
|
||||||
|
.class {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
.class-other {
|
||||||
|
color: blue;
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
.foo {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
.bar {
|
||||||
|
color: blue;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
moduleScope(scope) {
|
||||||
|
const link = scope.window.document.createElement("link");
|
||||||
|
link.rel = "stylesheet";
|
||||||
|
link.href = "https://test.cases/path/bundle.css";
|
||||||
|
scope.window.document.head.appendChild(link);
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,14 @@
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
mode: "development",
|
||||||
|
devtool: false,
|
||||||
|
output: {
|
||||||
|
cssChunkFilename: "[name].css"
|
||||||
|
},
|
||||||
|
node: {
|
||||||
|
__dirname: false
|
||||||
|
},
|
||||||
|
experiments: {
|
||||||
|
css: true
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue