diff --git a/README.md b/README.md index 361f0c84..bc5dbafd 100644 --- a/README.md +++ b/README.md @@ -1479,7 +1479,7 @@ module.exports = { }, }; -// same as above, just asynchronous +// supports an asynchronous callback module.exports = { module: { rules: [ diff --git a/src/utils.js b/src/utils.js index 15096506..9d68a598 100644 --- a/src/utils.js +++ b/src/utils.js @@ -593,8 +593,6 @@ function getModulesOptions(rawOptions, exportType, loaderContext) { ? "camelCaseOnly" : "asIs", exportOnlyLocals: false, - // eslint-disable-next-line no-undefined - getJSON: undefined, ...rawModulesOptions, useExportsAs: rawModulesOptions.exportLocalsConvention === "asIs", }; diff --git a/test/__snapshots__/modules-option.test.js.snap b/test/__snapshots__/modules-option.test.js.snap index 5fdf255c..4184646a 100644 --- a/test/__snapshots__/modules-option.test.js.snap +++ b/test/__snapshots__/modules-option.test.js.snap @@ -1122,26 +1122,18 @@ exports[`"modules" option should emit warning when localIdentName is emoji: erro exports[`"modules" option should emit warning when localIdentName is emoji: warnings 1`] = `Array []`; -exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: args 1`] = ` +exports[`"modules" option should invoke the custom getJSON function if provided: args 1`] = ` Array [ Array [ Object { "exports": Array [ Object { "name": "a", - "value": "RT7ktT7mB7tfBR25sJDZ", + "value": "RT7ktT7mB7tfBR25sJDZ ___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_0___", }, Object { "name": "b", - "value": "IZmhTnK9CIeu6ww6Zjbv ___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_0___", - }, - Object { - "name": "c", - "value": "PV11nPFlF7mzEgCXkQw4 ___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_0___ ___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_1___", - }, - Object { - "name": "d", - "value": "w9tLJiFrGdszjCX9N2R1 ___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_0___ ___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_0___ ___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_1___", + "value": "IZmhTnK9CIeu6ww6Zjbv ___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_1___", }, ], "imports": Array [ @@ -1159,289 +1151,34 @@ Array [ "importName": "___CSS_LOADER_ICSS_IMPORT_0___", "index": 0, "type": "icss_import", - "url": "\\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSourceB.css\\"", - }, - Object { - "icss": true, - "importName": "___CSS_LOADER_ICSS_IMPORT_1___", - "index": 1, - "type": "icss_import", - "url": "\\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSourceC.css\\"", + "url": "\\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSource.css\\"", }, ], "replacements": Array [ Object { "importName": "___CSS_LOADER_ICSS_IMPORT_0___", - "localName": "composedB", + "localName": "composedA", "replacementName": "___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_0___", }, - Object { - "importName": "___CSS_LOADER_ICSS_IMPORT_1___", - "localName": "composedC1", - "replacementName": "___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_0___", - }, - Object { - "importName": "___CSS_LOADER_ICSS_IMPORT_1___", - "localName": "composedC2", - "replacementName": "___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_1___", - }, - ], - "resourcePath": "/Users/skao/workspace/webpack-contrib/css-loader/test/fixtures/modules/getJSON/source.css", - }, - ], - Array [ - Object { - "exports": Array [ - Object { - "name": "composedB", - "value": "gFdUXtR3F_6oyBd_qgU8", - }, - ], - "imports": Array [ - Object { - "importName": "___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___", - "url": "\\"../../../../src/runtime/noSourceMaps.js\\"", - }, - Object { - "importName": "___CSS_LOADER_API_IMPORT___", - "type": "api_import", - "url": "\\"../../../../src/runtime/api.js\\"", - }, - ], - "replacements": Array [], - "resourcePath": "/Users/skao/workspace/webpack-contrib/css-loader/test/fixtures/modules/getJSON/composeSourceB.css", - }, - ], - Array [ - Object { - "exports": Array [ - Object { - "name": "composedC1", - "value": "wzV7_RSrFO8_yYPxKBCs", - }, - Object { - "name": "composedC2", - "value": "vsHct1x_FxZpoD1J8kEc", - }, - ], - "imports": Array [ - Object { - "importName": "___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___", - "url": "\\"../../../../src/runtime/noSourceMaps.js\\"", - }, - Object { - "importName": "___CSS_LOADER_API_IMPORT___", - "type": "api_import", - "url": "\\"../../../../src/runtime/api.js\\"", - }, - ], - "replacements": Array [], - "resourcePath": "/Users/skao/workspace/webpack-contrib/css-loader/test/fixtures/modules/getJSON/composeSourceC.css", - }, - ], -] -`; - -exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: errors 1`] = `Array []`; - -exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: module 1`] = ` -"// Imports -import ___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___ from \\"../../../../src/runtime/noSourceMaps.js\\"; -import ___CSS_LOADER_API_IMPORT___ from \\"../../../../src/runtime/api.js\\"; -import ___CSS_LOADER_ICSS_IMPORT_0___ from \\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSourceB.css\\"; -import ___CSS_LOADER_ICSS_IMPORT_1___ from \\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSourceC.css\\"; -var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___); -___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_0___, \\"\\", true); -___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_1___, \\"\\", true); -// Module -___CSS_LOADER_EXPORT___.push([module.id, \`.RT7ktT7mB7tfBR25sJDZ { - background-color: aliceblue; -} - -.IZmhTnK9CIeu6ww6Zjbv { - - background-color: burlywood; -} - -.PV11nPFlF7mzEgCXkQw4 { - - background-color: chartreuse; -} - -.w9tLJiFrGdszjCX9N2R1 { - - background-color: dodgerblue; -} - -.e { - background-color: firebrick; -} -\`, \\"\\"]); -// Exports -___CSS_LOADER_EXPORT___.locals = { - \\"a\\": \`RT7ktT7mB7tfBR25sJDZ\`, - \\"b\\": \`IZmhTnK9CIeu6ww6Zjbv \${___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"composedB\\"]}\`, - \\"c\\": \`PV11nPFlF7mzEgCXkQw4 \${___CSS_LOADER_ICSS_IMPORT_1___.locals[\\"composedC1\\"]} \${___CSS_LOADER_ICSS_IMPORT_1___.locals[\\"composedC2\\"]}\`, - \\"d\\": \`w9tLJiFrGdszjCX9N2R1 \${___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"composedB\\"]} \${___CSS_LOADER_ICSS_IMPORT_1___.locals[\\"composedC1\\"]} \${___CSS_LOADER_ICSS_IMPORT_1___.locals[\\"composedC2\\"]}\` -}; -export default ___CSS_LOADER_EXPORT___; -" -`; - -exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: result 1`] = ` -Array [ - Array [ - "./modules/getJSON/composeSourceB.css", - ".gFdUXtR3F_6oyBd_qgU8 { - width: 100px; -} -", - "", - ], - Array [ - "./modules/getJSON/composeSourceC.css", - ".wzV7_RSrFO8_yYPxKBCs { - height: 200px; -} - -.vsHct1x_FxZpoD1J8kEc { - border: 1px solid black; -} -", - "", - ], - Array [ - "./modules/getJSON/source.css", - ".RT7ktT7mB7tfBR25sJDZ { - background-color: aliceblue; -} - -.IZmhTnK9CIeu6ww6Zjbv { - - background-color: burlywood; -} - -.PV11nPFlF7mzEgCXkQw4 { - - background-color: chartreuse; -} - -.w9tLJiFrGdszjCX9N2R1 { - - background-color: dodgerblue; -} - -.e { - background-color: firebrick; -} -", - "", - ], -] -`; - -exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: warnings 1`] = `Array []`; - -exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: args 1`] = ` -Array [ - Array [ - Object { - "exports": Array [ - Object { - "name": "a", - "value": "RT7ktT7mB7tfBR25sJDZ", - }, - Object { - "name": "b", - "value": "IZmhTnK9CIeu6ww6Zjbv ___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_0___", - }, - Object { - "name": "c", - "value": "PV11nPFlF7mzEgCXkQw4 ___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_0___ ___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_1___", - }, - Object { - "name": "d", - "value": "w9tLJiFrGdszjCX9N2R1 ___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_0___ ___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_0___ ___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_1___", - }, - ], - "imports": Array [ - Object { - "importName": "___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___", - "url": "\\"../../../../src/runtime/noSourceMaps.js\\"", - }, - Object { - "importName": "___CSS_LOADER_API_IMPORT___", - "type": "api_import", - "url": "\\"../../../../src/runtime/api.js\\"", - }, - Object { - "icss": true, - "importName": "___CSS_LOADER_ICSS_IMPORT_0___", - "index": 0, - "type": "icss_import", - "url": "\\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSourceB.css\\"", - }, - Object { - "icss": true, - "importName": "___CSS_LOADER_ICSS_IMPORT_1___", - "index": 1, - "type": "icss_import", - "url": "\\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSourceC.css\\"", - }, - ], - "replacements": Array [ Object { "importName": "___CSS_LOADER_ICSS_IMPORT_0___", "localName": "composedB", - "replacementName": "___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_0___", - }, - Object { - "importName": "___CSS_LOADER_ICSS_IMPORT_1___", - "localName": "composedC1", - "replacementName": "___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_0___", - }, - Object { - "importName": "___CSS_LOADER_ICSS_IMPORT_1___", - "localName": "composedC2", - "replacementName": "___CSS_LOADER_ICSS_IMPORT_1_REPLACEMENT_1___", - }, - ], - "resourcePath": "/Users/skao/workspace/webpack-contrib/css-loader/test/fixtures/modules/getJSON/source.css", - }, - ], - Array [ - Object { - "exports": Array [ - Object { - "name": "composedB", - "value": "gFdUXtR3F_6oyBd_qgU8", - }, - ], - "imports": Array [ - Object { - "importName": "___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___", - "url": "\\"../../../../src/runtime/noSourceMaps.js\\"", - }, - Object { - "importName": "___CSS_LOADER_API_IMPORT___", - "type": "api_import", - "url": "\\"../../../../src/runtime/api.js\\"", + "replacementName": "___CSS_LOADER_ICSS_IMPORT_0_REPLACEMENT_1___", }, ], - "replacements": Array [], - "resourcePath": "/Users/skao/workspace/webpack-contrib/css-loader/test/fixtures/modules/getJSON/composeSourceB.css", + "resourcePath": "/test/fixtures/modules/getJSON/source.css", }, ], Array [ Object { "exports": Array [ Object { - "name": "composedC1", - "value": "wzV7_RSrFO8_yYPxKBCs", + "name": "composedA", + "value": "mm3SuQiO3doywWWliORs", }, Object { - "name": "composedC2", - "value": "vsHct1x_FxZpoD1J8kEc", + "name": "composedB", + "value": "hFeFcgvjCoj_9RRA4E59 mm3SuQiO3doywWWliORs", }, ], "imports": Array [ @@ -1456,76 +1193,50 @@ Array [ }, ], "replacements": Array [], - "resourcePath": "/Users/skao/workspace/webpack-contrib/css-loader/test/fixtures/modules/getJSON/composeSourceC.css", + "resourcePath": "/test/fixtures/modules/getJSON/composeSource.css", }, ], ] `; -exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: errors 1`] = `Array []`; +exports[`"modules" option should invoke the custom getJSON function if provided: errors 1`] = `Array []`; -exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: module 1`] = ` +exports[`"modules" option should invoke the custom getJSON function if provided: module 1`] = ` "// Imports import ___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___ from \\"../../../../src/runtime/noSourceMaps.js\\"; import ___CSS_LOADER_API_IMPORT___ from \\"../../../../src/runtime/api.js\\"; -import ___CSS_LOADER_ICSS_IMPORT_0___ from \\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSourceB.css\\"; -import ___CSS_LOADER_ICSS_IMPORT_1___ from \\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSourceC.css\\"; +import ___CSS_LOADER_ICSS_IMPORT_0___ from \\"-!../../../../src/index.js??ruleSet[1].rules[0].use[0]!./composeSource.css\\"; var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___); ___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_0___, \\"\\", true); -___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_1___, \\"\\", true); // Module ___CSS_LOADER_EXPORT___.push([module.id, \`.RT7ktT7mB7tfBR25sJDZ { + background-color: aliceblue; } .IZmhTnK9CIeu6ww6Zjbv { - background-color: burlywood; -} - -.PV11nPFlF7mzEgCXkQw4 { - - background-color: chartreuse; -} - -.w9tLJiFrGdszjCX9N2R1 { - - background-color: dodgerblue; -} - -.e { - background-color: firebrick; + background-color: blanchedalmond; } \`, \\"\\"]); // Exports ___CSS_LOADER_EXPORT___.locals = { - \\"a\\": \`RT7ktT7mB7tfBR25sJDZ\`, - \\"b\\": \`IZmhTnK9CIeu6ww6Zjbv \${___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"composedB\\"]}\`, - \\"c\\": \`PV11nPFlF7mzEgCXkQw4 \${___CSS_LOADER_ICSS_IMPORT_1___.locals[\\"composedC1\\"]} \${___CSS_LOADER_ICSS_IMPORT_1___.locals[\\"composedC2\\"]}\`, - \\"d\\": \`w9tLJiFrGdszjCX9N2R1 \${___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"composedB\\"]} \${___CSS_LOADER_ICSS_IMPORT_1___.locals[\\"composedC1\\"]} \${___CSS_LOADER_ICSS_IMPORT_1___.locals[\\"composedC2\\"]}\` + \\"a\\": \`RT7ktT7mB7tfBR25sJDZ \${___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"composedA\\"]}\`, + \\"b\\": \`IZmhTnK9CIeu6ww6Zjbv \${___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"composedB\\"]}\` }; export default ___CSS_LOADER_EXPORT___; " `; -exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: result 1`] = ` +exports[`"modules" option should invoke the custom getJSON function if provided: result 1`] = ` Array [ Array [ - "./modules/getJSON/composeSourceB.css", - ".gFdUXtR3F_6oyBd_qgU8 { - width: 100px; -} -", - "", - ], - Array [ - "./modules/getJSON/composeSourceC.css", - ".wzV7_RSrFO8_yYPxKBCs { + "../../src/index.js??ruleSet[1].rules[0].use[0]!./modules/getJSON/composeSource.css", + ".mm3SuQiO3doywWWliORs { height: 200px; } -.vsHct1x_FxZpoD1J8kEc { - border: 1px solid black; +.hFeFcgvjCoj_9RRA4E59 { } ", "", @@ -1533,26 +1244,13 @@ Array [ Array [ "./modules/getJSON/source.css", ".RT7ktT7mB7tfBR25sJDZ { + background-color: aliceblue; } .IZmhTnK9CIeu6ww6Zjbv { - background-color: burlywood; -} - -.PV11nPFlF7mzEgCXkQw4 { - - background-color: chartreuse; -} - -.w9tLJiFrGdszjCX9N2R1 { - - background-color: dodgerblue; -} - -.e { - background-color: firebrick; + background-color: blanchedalmond; } ", "", @@ -1560,7 +1258,7 @@ Array [ ] `; -exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: warnings 1`] = `Array []`; +exports[`"modules" option should invoke the custom getJSON function if provided: warnings 1`] = `Array []`; exports[`"modules" option should keep order: errors 1`] = `Array []`; diff --git a/test/fixtures/modules/getJSON/composeSource.css b/test/fixtures/modules/getJSON/composeSource.css new file mode 100644 index 00000000..8303fe70 --- /dev/null +++ b/test/fixtures/modules/getJSON/composeSource.css @@ -0,0 +1,7 @@ +.composedA { + height: 200px; +} + +.composedB { + composes: composedA; +} diff --git a/test/fixtures/modules/getJSON/composeSourceB.css b/test/fixtures/modules/getJSON/composeSourceB.css deleted file mode 100644 index 0da76dff..00000000 --- a/test/fixtures/modules/getJSON/composeSourceB.css +++ /dev/null @@ -1,3 +0,0 @@ -.composedB { - width: 100px; -} diff --git a/test/fixtures/modules/getJSON/composeSourceC.css b/test/fixtures/modules/getJSON/composeSourceC.css deleted file mode 100644 index da24d490..00000000 --- a/test/fixtures/modules/getJSON/composeSourceC.css +++ /dev/null @@ -1,7 +0,0 @@ -.composedC1 { - height: 200px; -} - -.composedC2 { - border: 1px solid black; -} diff --git a/test/fixtures/modules/getJSON/source.css b/test/fixtures/modules/getJSON/source.css index b84c2c1d..7007a4e7 100644 --- a/test/fixtures/modules/getJSON/source.css +++ b/test/fixtures/modules/getJSON/source.css @@ -1,28 +1,11 @@ .a { + composes: composedA from "./composeSource.css"; + background-color: aliceblue; } .b { - composes: composedB from "./composeSourceB.css"; - - background-color: burlywood; -} - -.c { - composes: composedC1 from "./composeSourceC.css"; - composes: composedC2 from "./composeSourceC.css"; - - background-color: chartreuse; -} - -.d { - composes: composedB from "./composeSourceB.css"; - composes: composedC1 from "./composeSourceC.css"; - composes: composedC2 from "./composeSourceC.css"; - - background-color: dodgerblue; -} + composes: composedB from "./composeSource.css"; -:global(.e) { - background-color: firebrick; + background-color: blanchedalmond; } diff --git a/test/fixtures/modules/getJSON/source.js b/test/fixtures/modules/getJSON/source.js index 3eb0aedc..1996779e 100644 --- a/test/fixtures/modules/getJSON/source.js +++ b/test/fixtures/modules/getJSON/source.js @@ -1,6 +1,4 @@ import css from './source.css'; -import composeSourceBCss from './composeSourceB.css'; -import composeSourceCCss from './composeSourceC.css'; __export__ = css; diff --git a/test/helpers/normalizeErrors.js b/test/helpers/normalizeErrors.js index e3ef68ab..04ec5673 100644 --- a/test/helpers/normalizeErrors.js +++ b/test/helpers/normalizeErrors.js @@ -1,6 +1,6 @@ import stripAnsi from "strip-ansi"; -function removeCWD(str) { +export function removeCWD(str) { const isWin = process.platform === "win32"; let cwd = process.cwd(); diff --git a/test/modules-option.test.js b/test/modules-option.test.js index 999b2305..7a07a284 100644 --- a/test/modules-option.test.js +++ b/test/modules-option.test.js @@ -12,6 +12,7 @@ import { getWarnings, readAsset, } from "./helpers/index"; +import { removeCWD } from "./helpers/normalizeErrors"; const modulesFixturesPath = path.join(__dirname, "fixtures/modules"); const testCasesPath = path.join(modulesFixturesPath, "tests-cases"); @@ -2419,7 +2420,7 @@ describe('"modules" option', () => { expect(getErrors(stats)).toMatchSnapshot("errors"); }); - it("should invoke the custom getJSON function with getJSON as a synchronous function", async () => { + it("should invoke the custom getJSON function if provided", async () => { const getJSONSpy = jest.fn(); const compiler = getCompiler("./modules/getJSON/source.js", { modules: { @@ -2429,30 +2430,13 @@ describe('"modules" option', () => { }); const stats = await compile(compiler); - const args = getJSONSpy.mock.calls; - expect(args).toMatchSnapshot("args"); - - expect( - getModuleSource("./modules/getJSON/source.css", stats) - ).toMatchSnapshot("module"); - expect(getExecutedCode("main.bundle.js", compiler, stats)).toMatchSnapshot( - "result" - ); - expect(getWarnings(stats)).toMatchSnapshot("warnings"); - expect(getErrors(stats)).toMatchSnapshot("errors"); - }); - - it("should invoke the custom getJSON function with getJSON as an asynchronous function", async () => { - const getJSONSpy = jest.fn(); - const compiler = getCompiler("./modules/getJSON/source.js", { - modules: { - // need to wrap Jest spy since it doesn't pass ajv validation on its own - getJSON: async (...args) => getJSONSpy(...args), + const args = getJSONSpy.mock.calls.map((arg) => [ + { + ...arg[0], + // resourcePaths are absolute so we need to make them relative for snapshots + resourcePath: removeCWD(arg[0].resourcePath), }, - }); - const stats = await compile(compiler); - - const args = getJSONSpy.mock.calls; + ]); expect(args).toMatchSnapshot("args"); expect(