From 519e5f41539f4c87ec96db0a908aaadecc284a6c Mon Sep 17 00:00:00 2001 From: Evilebot Tnawi Date: Mon, 6 Apr 2020 16:20:43 +0300 Subject: [PATCH] feat: the `exportGlobals` option for export global classes and ids (#1069) --- README.md | 28 ++++ src/options.json | 3 + src/utils.js | 8 +- .../__snapshots__/modules-option.test.js.snap | 156 +++++++++++++++++- .../validate-options.test.js.snap | 33 ++-- .../exportGlobals-global/exportGlobals.css | 11 ++ .../exportGlobals-global/exportGlobals.js | 5 + .../exportGlobals-local/exportGlobals.css | 11 ++ .../exportGlobals-local/exportGlobals.js | 5 + .../exportGlobals-pure/exportGlobals.css | 11 ++ .../exportGlobals-pure/exportGlobals.js | 5 + .../fixtures/modules/issue-1063/issue-1063.js | 5 +- test/fixtures/modules/issue-1063/pure.css | 3 + test/modules-option.test.js | 77 ++++++++- test/validate-options.test.js | 2 + 15 files changed, 336 insertions(+), 27 deletions(-) create mode 100644 test/fixtures/modules/exportGlobals-global/exportGlobals.css create mode 100644 test/fixtures/modules/exportGlobals-global/exportGlobals.js create mode 100644 test/fixtures/modules/exportGlobals-local/exportGlobals.css create mode 100644 test/fixtures/modules/exportGlobals-local/exportGlobals.js create mode 100644 test/fixtures/modules/exportGlobals-pure/exportGlobals.css create mode 100644 test/fixtures/modules/exportGlobals-pure/exportGlobals.js create mode 100644 test/fixtures/modules/issue-1063/pure.css diff --git a/README.md b/README.md index 737f15c5..a6bee2f9 100644 --- a/README.md +++ b/README.md @@ -528,6 +528,7 @@ module.exports = { options: { modules: { mode: 'local', + exportGlobals: true, localIdentName: '[path][name]__[local]--[hash:base64:5]', context: path.resolve(__dirname, 'src'), hashPrefix: 'my-custom-hash', @@ -605,6 +606,33 @@ module.exports = { }; ``` +##### `exportGlobals` + +Type: `Boolean` +Default: `false` + +Allow `css-loader` to export names from global class or id, so you can use that as local name. + +**webpack.config.js** + +```js +module.exports = { + module: { + rules: [ + { + test: /\.css$/i, + loader: 'css-loader', + options: { + modules: { + exportGlobals: true, + }, + }, + }, + ], + }, +}; +``` + ##### `localIdentName` Type: `String` diff --git a/src/options.json b/src/options.json index 742c28ce..706e4e94 100644 --- a/src/options.json +++ b/src/options.json @@ -46,6 +46,9 @@ } ] }, + "exportGlobals": { + "type": "boolean" + }, "localIdentName": { "type": "string" }, diff --git a/src/utils.js b/src/utils.js index 0bfed952..a4c65119 100644 --- a/src/utils.js +++ b/src/utils.js @@ -99,6 +99,7 @@ function getFilter(filter, resourcePath, defaultFilter = null) { function getModulesPlugins(options, loaderContext) { let modulesOptions = { mode: 'local', + exportGlobals: false, localIdentName: '[hash:base64]', getLocalIdent, hashPrefix: '', @@ -116,11 +117,7 @@ function getModulesPlugins(options, loaderContext) { } if (typeof modulesOptions.mode === 'function') { - const modeFromFunction = modulesOptions.mode(loaderContext.resourcePath); - - if (modeFromFunction === 'local' || modeFromFunction === 'global') { - modulesOptions.mode = modeFromFunction; - } + modulesOptions.mode = modulesOptions.mode(loaderContext.resourcePath); } let plugins = []; @@ -158,6 +155,7 @@ function getModulesPlugins(options, loaderContext) { return localIdent; }, + exportGlobals: modulesOptions.exportGlobals, }), ]; } catch (error) { diff --git a/test/__snapshots__/modules-option.test.js.snap b/test/__snapshots__/modules-option.test.js.snap index ae8349df..ceab550c 100644 --- a/test/__snapshots__/modules-option.test.js.snap +++ b/test/__snapshots__/modules-option.test.js.snap @@ -368,6 +368,8 @@ Array [ "ModuleError: Module Error (from \`replaced original path\`): options.mode must be either \\"global\\", \\"local\\" or \\"pure\\" (default \\"local\\")", "ModuleError: Module Error (from \`replaced original path\`): +options.mode must be either \\"global\\", \\"local\\" or \\"pure\\" (default \\"local\\")", + "ModuleError: Module Error (from \`replaced original path\`): options.mode must be either \\"global\\", \\"local\\" or \\"pure\\" (default \\"local\\")", ] `; @@ -409,6 +411,9 @@ exports[`"modules" option issue #1063 throw error: result 1`] = ` :local(.otherClassGlobalFile) { color: coral; } +.foo :local(.bar) { + color: red; +} " `; @@ -416,7 +421,21 @@ exports[`"modules" option issue #1063 throw error: warnings 1`] = `Array []`; exports[`"modules" option issue #1063: errors 1`] = `Array []`; -exports[`"modules" option issue #1063: module 1`] = ` +exports[`"modules" option issue #1063: module with the \`global\` mode 1`] = ` +"// Imports +var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\"); +exports = ___CSS_LOADER_API_IMPORT___(false); +// Module +exports.push([module.id, \\".classNameGlobalFile {\\\\n color: black;\\\\n}\\\\n\\\\n._2rcag09JpwrP4_hfyyRmm- {\\\\n color: coral;\\\\n}\\\\n\\", \\"\\"]); +// Exports +exports.locals = { + \\"otherClassGlobalFile\\": \\"_2rcag09JpwrP4_hfyyRmm-\\" +}; +module.exports = exports; +" +`; + +exports[`"modules" option issue #1063: module with the \`local\` mode 1`] = ` "// Imports var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\"); exports = ___CSS_LOADER_API_IMPORT___(false); @@ -430,15 +449,16 @@ module.exports = exports; " `; -exports[`"modules" option issue #1063: module 2`] = ` +exports[`"modules" option issue #1063: module with the \`pure\` mode 1`] = ` "// Imports var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\"); exports = ___CSS_LOADER_API_IMPORT___(false); // Module -exports.push([module.id, \\".classNameGlobalFile {\\\\n color: black;\\\\n}\\\\n\\\\n._2rcag09JpwrP4_hfyyRmm- {\\\\n color: coral;\\\\n}\\\\n\\", \\"\\"]); +exports.push([module.id, \\"._1rycxa6QkLdgO7vayuTDvk ._3Otdq1jay-xaQGguOXb-0X {\\\\n color: red;\\\\n}\\\\n\\", \\"\\"]); // Exports exports.locals = { - \\"otherClassGlobalFile\\": \\"_2rcag09JpwrP4_hfyyRmm-\\" + \\"foo\\": \\"_1rycxa6QkLdgO7vayuTDvk\\", + \\"bar\\": \\"_3Otdq1jay-xaQGguOXb-0X\\" }; module.exports = exports; " @@ -459,6 +479,9 @@ exports[`"modules" option issue #1063: result 1`] = ` ._2rcag09JpwrP4_hfyyRmm- { color: coral; } +._1rycxa6QkLdgO7vayuTDvk ._3Otdq1jay-xaQGguOXb-0X { + color: red; +} " `; @@ -11098,3 +11121,128 @@ Array [ `; exports[`"modules" option should work with the "[local]" placeholder for the "localIdentName" option: warnings 1`] = `Array []`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`global\`): errors 1`] = `Array []`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`global\`): module 1`] = ` +"// Imports +var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\"); +exports = ___CSS_LOADER_API_IMPORT___(false); +// Module +exports.push([module.id, \\".QLhabfC4HjcIBmobkGW_v {\\\\n background-color: red;\\\\n}\\\\n\\\\n._1fCLE6vkQLICB5aEeEaLgd {\\\\n background-color: green;\\\\n}\\\\n\\\\n.baz {\\\\n background-color: blue;\\\\n}\\\\n\\", \\"\\"]); +// Exports +exports.locals = { + \\"foo\\": \\"QLhabfC4HjcIBmobkGW_v\\", + \\"bar\\": \\"_1fCLE6vkQLICB5aEeEaLgd\\", + \\"baz\\": \\"baz\\" +}; +module.exports = exports; +" +`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`global\`): result 1`] = ` +Array [ + Array [ + "./modules/exportGlobals-global/exportGlobals.css", + ".QLhabfC4HjcIBmobkGW_v { + background-color: red; +} + +._1fCLE6vkQLICB5aEeEaLgd { + background-color: green; +} + +.baz { + background-color: blue; +} +", + "", + ], +] +`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`global\`): warnings 1`] = `Array []`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`local\`): errors 1`] = `Array []`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`local\`): module 1`] = ` +"// Imports +var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\"); +exports = ___CSS_LOADER_API_IMPORT___(false); +// Module +exports.push([module.id, \\".foo {\\\\n background-color: red;\\\\n}\\\\n\\\\n._3loyPgwYlZ-RBGWccx71es {\\\\n background-color: green;\\\\n}\\\\n\\\\n.baz {\\\\n background-color: blue;\\\\n}\\\\n\\", \\"\\"]); +// Exports +exports.locals = { + \\"foo\\": \\"foo\\", + \\"bar\\": \\"_3loyPgwYlZ-RBGWccx71es\\", + \\"baz\\": \\"baz\\" +}; +module.exports = exports; +" +`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`local\`): result 1`] = ` +Array [ + Array [ + "./modules/exportGlobals-local/exportGlobals.css", + ".foo { + background-color: red; +} + +._3loyPgwYlZ-RBGWccx71es { + background-color: green; +} + +.baz { + background-color: blue; +} +", + "", + ], +] +`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`local\`): warnings 1`] = `Array []`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`pure\`): errors 1`] = `Array []`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`pure\`): module 1`] = ` +"// Imports +var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../../src/runtime/api.js\\"); +exports = ___CSS_LOADER_API_IMPORT___(false); +// Module +exports.push([module.id, \\"._3OALfsKrVzw8QnGzfteWls {\\\\n background-color: red;\\\\n}\\\\n\\\\n._3w1OTKuiiZvf8WY1tCPaZH ._1cmRmgT7HI056zoTdHDOVh {\\\\n background-color: green;\\\\n}\\\\n\\\\n._3pB9KhpUqVA1pPH1Y8ei3y .baz {\\\\n background-color: blue;\\\\n}\\\\n\\", \\"\\"]); +// Exports +exports.locals = { + \\"foo\\": \\"_3OALfsKrVzw8QnGzfteWls\\", + \\"one\\": \\"_3w1OTKuiiZvf8WY1tCPaZH\\", + \\"bar\\": \\"_1cmRmgT7HI056zoTdHDOVh\\", + \\"two\\": \\"_3pB9KhpUqVA1pPH1Y8ei3y\\", + \\"baz\\": \\"baz\\" +}; +module.exports = exports; +" +`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`pure\`): result 1`] = ` +Array [ + Array [ + "./modules/exportGlobals-pure/exportGlobals.css", + "._3OALfsKrVzw8QnGzfteWls { + background-color: red; +} + +._3w1OTKuiiZvf8WY1tCPaZH ._1cmRmgT7HI056zoTdHDOVh { + background-color: green; +} + +._3pB9KhpUqVA1pPH1Y8ei3y .baz { + background-color: blue; +} +", + "", + ], +] +`; + +exports[`"modules" option should work with the \`exportGlobals\` option (the \`mode\` option is \`pure\`): warnings 1`] = `Array []`; diff --git a/test/__snapshots__/validate-options.test.js.snap b/test/__snapshots__/validate-options.test.js.snap index e7f0351f..bc1b2367 100644 --- a/test/__snapshots__/validate-options.test.js.snap +++ b/test/__snapshots__/validate-options.test.js.snap @@ -48,10 +48,15 @@ exports[`validate options should throw an error on the "modules" option with "{" - options.modules.context should be a string." `; +exports[`validate options should throw an error on the "modules" option with "{"exportGlobals":"invalid"}" value 1`] = ` +"Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. + - options.modules.exportGlobals should be a boolean." +`; + exports[`validate options should throw an error on the "modules" option with "{"getLocalIdent":[]}" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules.getLocalIdent should be one of these: @@ -74,7 +79,7 @@ exports[`validate options should throw an error on the "modules" option with "{" exports[`validate options should throw an error on the "modules" option with "{"localIdentRegExp":true}" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules.localIdentRegExp should be one of these: @@ -87,7 +92,7 @@ exports[`validate options should throw an error on the "modules" option with "{" exports[`validate options should throw an error on the "modules" option with "{"mode":"globals"}" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules.mode should be one of these: @@ -101,7 +106,7 @@ exports[`validate options should throw an error on the "modules" option with "{" exports[`validate options should throw an error on the "modules" option with "{"mode":"locals"}" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules.mode should be one of these: @@ -115,7 +120,7 @@ exports[`validate options should throw an error on the "modules" option with "{" exports[`validate options should throw an error on the "modules" option with "{"mode":"pures"}" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules.mode should be one of these: @@ -129,7 +134,7 @@ exports[`validate options should throw an error on the "modules" option with "{" exports[`validate options should throw an error on the "modules" option with "{"mode":true}" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules.mode should be one of these: @@ -143,53 +148,53 @@ exports[`validate options should throw an error on the "modules" option with "{" exports[`validate options should throw an error on the "modules" option with "globals" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules should be a boolean. * options.modules should be one of these: \\"local\\" | \\"global\\" | \\"pure\\" * options.modules should be an object: - object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }" + object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }" `; exports[`validate options should throw an error on the "modules" option with "locals" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules should be a boolean. * options.modules should be one of these: \\"local\\" | \\"global\\" | \\"pure\\" * options.modules should be an object: - object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }" + object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }" `; exports[`validate options should throw an error on the "modules" option with "pures" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules should be a boolean. * options.modules should be one of these: \\"local\\" | \\"global\\" | \\"pure\\" * options.modules should be an object: - object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }" + object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }" `; exports[`validate options should throw an error on the "modules" option with "true" value 1`] = ` "Invalid options object. CSS Loader has been initialized using an options object that does not match the API schema. - options.modules should be one of these: - boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } + boolean | \\"local\\" | \\"global\\" | \\"pure\\" | object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? } -> Enables/Disables CSS Modules and their configuration (https://github.com/webpack-contrib/css-loader#modules). Details: * options.modules should be a boolean. * options.modules should be one of these: \\"local\\" | \\"global\\" | \\"pure\\" * options.modules should be an object: - object { mode?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }" + object { mode?, exportGlobals?, localIdentName?, localIdentRegExp?, context?, hashPrefix?, getLocalIdent? }" `; exports[`validate options should throw an error on the "onlyLocals" option with "true" value 1`] = ` diff --git a/test/fixtures/modules/exportGlobals-global/exportGlobals.css b/test/fixtures/modules/exportGlobals-global/exportGlobals.css new file mode 100644 index 00000000..fea8c37c --- /dev/null +++ b/test/fixtures/modules/exportGlobals-global/exportGlobals.css @@ -0,0 +1,11 @@ +.foo { + background-color: red; +} + +:local(.bar) { + background-color: green; +} + +:global(.baz) { + background-color: blue; +} diff --git a/test/fixtures/modules/exportGlobals-global/exportGlobals.js b/test/fixtures/modules/exportGlobals-global/exportGlobals.js new file mode 100644 index 00000000..17cc87d2 --- /dev/null +++ b/test/fixtures/modules/exportGlobals-global/exportGlobals.js @@ -0,0 +1,5 @@ +import css from './exportGlobals.css'; + +__export__ = css; + +export default css; diff --git a/test/fixtures/modules/exportGlobals-local/exportGlobals.css b/test/fixtures/modules/exportGlobals-local/exportGlobals.css new file mode 100644 index 00000000..fea8c37c --- /dev/null +++ b/test/fixtures/modules/exportGlobals-local/exportGlobals.css @@ -0,0 +1,11 @@ +.foo { + background-color: red; +} + +:local(.bar) { + background-color: green; +} + +:global(.baz) { + background-color: blue; +} diff --git a/test/fixtures/modules/exportGlobals-local/exportGlobals.js b/test/fixtures/modules/exportGlobals-local/exportGlobals.js new file mode 100644 index 00000000..17cc87d2 --- /dev/null +++ b/test/fixtures/modules/exportGlobals-local/exportGlobals.js @@ -0,0 +1,5 @@ +import css from './exportGlobals.css'; + +__export__ = css; + +export default css; diff --git a/test/fixtures/modules/exportGlobals-pure/exportGlobals.css b/test/fixtures/modules/exportGlobals-pure/exportGlobals.css new file mode 100644 index 00000000..a334282b --- /dev/null +++ b/test/fixtures/modules/exportGlobals-pure/exportGlobals.css @@ -0,0 +1,11 @@ +.foo { + background-color: red; +} + +.one :local(.bar) { + background-color: green; +} + +.two :global(.baz) { + background-color: blue; +} diff --git a/test/fixtures/modules/exportGlobals-pure/exportGlobals.js b/test/fixtures/modules/exportGlobals-pure/exportGlobals.js new file mode 100644 index 00000000..17cc87d2 --- /dev/null +++ b/test/fixtures/modules/exportGlobals-pure/exportGlobals.js @@ -0,0 +1,5 @@ +import css from './exportGlobals.css'; + +__export__ = css; + +export default css; diff --git a/test/fixtures/modules/issue-1063/issue-1063.js b/test/fixtures/modules/issue-1063/issue-1063.js index c602c8c7..4544dd64 100644 --- a/test/fixtures/modules/issue-1063/issue-1063.js +++ b/test/fixtures/modules/issue-1063/issue-1063.js @@ -1,6 +1,7 @@ import css1 from './local.css'; import css2 from './global.css'; +import css3 from './pure.css'; -__export__ = css1 + css2; +__export__ = css1 + css2 + css3; -export default css1 + css2; +export default css1 + css2 + css3; diff --git a/test/fixtures/modules/issue-1063/pure.css b/test/fixtures/modules/issue-1063/pure.css new file mode 100644 index 00000000..679c427b --- /dev/null +++ b/test/fixtures/modules/issue-1063/pure.css @@ -0,0 +1,3 @@ +.foo :local(.bar) { + color: red; +} diff --git a/test/modules-option.test.js b/test/modules-option.test.js index b62a7084..31762f64 100644 --- a/test/modules-option.test.js +++ b/test/modules-option.test.js @@ -570,6 +570,10 @@ describe('"modules" option', () => { const compiler = getCompiler('./modules/issue-1063/issue-1063.js', { modules: { mode: (resourcePath) => { + if (/pure.css$/i.test(resourcePath)) { + return 'pure'; + } + if (/global.css$/i.test(resourcePath)) { return 'global'; } @@ -582,10 +586,13 @@ describe('"modules" option', () => { expect( getModuleSource('./modules/issue-1063/local.css', stats) - ).toMatchSnapshot('module'); + ).toMatchSnapshot('module with the `local` mode'); expect( getModuleSource('./modules/issue-1063/global.css', stats) - ).toMatchSnapshot('module'); + ).toMatchSnapshot('module with the `global` mode'); + expect( + getModuleSource('./modules/issue-1063/pure.css', stats) + ).toMatchSnapshot('module with the `pure` mode'); expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot( 'result' ); @@ -615,4 +622,70 @@ describe('"modules" option', () => { expect(getWarnings(stats)).toMatchSnapshot('warnings'); expect(getErrors(stats)).toMatchSnapshot('errors'); }); + + it('should work with the `exportGlobals` option (the `mode` option is `global`)', async () => { + const compiler = getCompiler( + './modules/exportGlobals-global/exportGlobals.js', + { + modules: { + mode: 'local', + exportGlobals: true, + }, + } + ); + const stats = await compile(compiler); + + expect( + getModuleSource('./modules/exportGlobals-global/exportGlobals.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 work with the `exportGlobals` option (the `mode` option is `local`)', async () => { + const compiler = getCompiler( + './modules/exportGlobals-local/exportGlobals.js', + { + modules: { + mode: 'global', + exportGlobals: true, + }, + } + ); + const stats = await compile(compiler); + + expect( + getModuleSource('./modules/exportGlobals-local/exportGlobals.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 work with the `exportGlobals` option (the `mode` option is `pure`)', async () => { + const compiler = getCompiler( + './modules/exportGlobals-pure/exportGlobals.js', + { + modules: { + mode: 'pure', + exportGlobals: true, + }, + } + ); + const stats = await compile(compiler); + + expect( + getModuleSource('./modules/exportGlobals-pure/exportGlobals.css', stats) + ).toMatchSnapshot('module'); + expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot( + 'result' + ); + expect(getWarnings(stats)).toMatchSnapshot('warnings'); + expect(getErrors(stats)).toMatchSnapshot('errors'); + }); }); diff --git a/test/validate-options.test.js b/test/validate-options.test.js index db5ad6cd..96a595ce 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -27,6 +27,7 @@ describe('validate options', () => { { getLocalIdent: () => {} }, { localIdentRegExp: 'page-(.*)\\.js' }, { localIdentRegExp: /page-(.*)\.js/ }, + { exportGlobals: true }, ], failure: [ 'true', @@ -42,6 +43,7 @@ describe('validate options', () => { { hashPrefix: true }, { getLocalIdent: [] }, { localIdentRegExp: true }, + { exportGlobals: 'invalid' }, ], }, sourceMap: {