diff --git a/.changeset/little-beers-cheer.md b/.changeset/little-beers-cheer.md new file mode 100644 index 000000000..21c8faf76 --- /dev/null +++ b/.changeset/little-beers-cheer.md @@ -0,0 +1,16 @@ +--- +"@modular-css/css-to-js": patch +"@modular-css/processor": patch +"@modular-css/webpack": patch +--- + +Ensure that aliased values get exported, fixing #982 + +``` +@value * as values from "./other-file.css"; +@value local: values.somevalue; +``` + +Previously that `local` value wouldn't exist in the JS exports, it was mistakenly treated like the `values` external value. + +Also adds semi-colons to variable declarations in the generated JS for vite/rollup/webpack. diff --git a/packages/css-to-js/css-to-js.js b/packages/css-to-js/css-to-js.js index c563b36cb..f34f2aa47 100644 --- a/packages/css-to-js/css-to-js.js +++ b/packages/css-to-js/css-to-js.js @@ -212,7 +212,7 @@ exports.transform = (file, processor, opts = {}) => { internalsMap.set(value, unique); - out.push(`${variableDeclaration} ${unique} = ${JSON.stringify(value)}`); + out.push(`${variableDeclaration} ${unique} = ${JSON.stringify(value)};`); valueExports.set(key, unique); }); @@ -258,7 +258,7 @@ exports.transform = (file, processor, opts = {}) => { elements.push(...details.classes[key].map((t) => JSON.stringify(t))); - out.push(`${variableDeclaration} ${unique} = ${elements.join(` + " " + `)}`); + out.push(`${variableDeclaration} ${unique} = ${elements.join(` + " " + `)};`); defaultExports.push([ key, unique ]); diff --git a/packages/css-to-js/test/__snapshots__/api.test.js.snap b/packages/css-to-js/test/__snapshots__/api.test.js.snap index a12e99aa9..4a94f6b21 100644 --- a/packages/css-to-js/test/__snapshots__/api.test.js.snap +++ b/packages/css-to-js/test/__snapshots__/api.test.js.snap @@ -2,7 +2,7 @@ exports[`@modular-css/css-to-js API should dedupe repeated identifiers: code 1`] = ` import { a } from "/a.css"; -const a1 = a + " " + "mc71966a67_a" +const a1 = a + " " + "mc71966a67_a"; export default { "a" : a1 }; @@ -13,7 +13,7 @@ export { `; exports[`@modular-css/css-to-js API should generate a javscript proxy in dev: code 1`] = ` -const a = "mc74f3fa7b_a" +const a = "mc74f3fa7b_a"; const data = { a }; @@ -44,8 +44,8 @@ exports[`@modular-css/css-to-js API should generate empty results & a warning on `; exports[`@modular-css/css-to-js API should generate javascript from composes: code 1`] = ` -const custom = "mca72bf2bd_custom" -const rule = custom + " " + "mca72bf2bd_rule" +const custom = "mca72bf2bd_custom"; +const rule = custom + " " + "mca72bf2bd_rule"; export default { custom, rule @@ -58,8 +58,8 @@ rule `; exports[`@modular-css/css-to-js API should generate javascript from multiple composes: code 1`] = ` -const rule = custom + " " + "mc9c938a76_rule" -const custom = "mc9c938a76_custom" +const rule = custom + " " + "mc9c938a76_rule"; +const custom = "mc9c938a76_custom"; export default { rule, custom @@ -72,11 +72,11 @@ custom `; exports[`@modular-css/css-to-js API should generate javascript with var variable statements: code 1`] = ` -var str = "\\"string\\"" +var str = "\\"string\\""; var $values = { str, }; -var fooga = "mce1ef44f3_fooga" +var fooga = "mce1ef44f3_fooga"; export default { $values, fooga @@ -89,7 +89,7 @@ fooga `; exports[`@modular-css/css-to-js API should generate javascript: code 1`] = ` -const a = "mc74f3fa7b_a" +const a = "mc74f3fa7b_a"; export default { a }; @@ -100,7 +100,7 @@ export { `; exports[`@modular-css/css-to-js API should handle options.namedExports set to: { rewriteInvalid: false }: code 1`] = ` -const a1 = "mc74f3fa7b_a-1" +const a1 = "mc74f3fa7b_a-1"; export default { "a-1" : a1 }; @@ -115,7 +115,7 @@ exports[`@modular-css/css-to-js API should handle options.namedExports set to: { `; exports[`@modular-css/css-to-js API should handle options.namedExports set to: { rewriteInvalid: false, warn: false }: code 1`] = ` -const a1 = "mc74f3fa7b_a-1" +const a1 = "mc74f3fa7b_a-1"; export default { "a-1" : a1 }; @@ -126,7 +126,7 @@ exports[`@modular-css/css-to-js API should handle options.namedExports set to: { exports[`@modular-css/css-to-js API should handle options.namedExports set to: { rewriteInvalid: false, warn: false }: warnings 1`] = `[]`; exports[`@modular-css/css-to-js API should handle options.namedExports set to: { warn: false }: code 1`] = ` -const a1 = "mc74f3fa7b_a-1" +const a1 = "mc74f3fa7b_a-1"; export default { "a-1" : a1 }; @@ -145,7 +145,7 @@ exports[`@modular-css/css-to-js API should handle options.namedExports set to: { exports[`@modular-css/css-to-js API should handle options.namedExports set to: { warn: false }: warnings 1`] = `[]`; exports[`@modular-css/css-to-js API should handle options.namedExports set to: {}: code 1`] = ` -const a1 = "mc74f3fa7b_a-1" +const a1 = "mc74f3fa7b_a-1"; export default { "a-1" : a1 }; @@ -168,7 +168,7 @@ exports[`@modular-css/css-to-js API should handle options.namedExports set to: { `; exports[`@modular-css/css-to-js API should handle options.namedExports set to: false: code 1`] = ` -const a1 = "mc74f3fa7b_a-1" +const a1 = "mc74f3fa7b_a-1"; export default { "a-1" : a1 }; @@ -179,7 +179,7 @@ exports[`@modular-css/css-to-js API should handle options.namedExports set to: f exports[`@modular-css/css-to-js API should handle options.namedExports set to: false: warnings 1`] = `[]`; exports[`@modular-css/css-to-js API should handle options.namedExports set to: true: code 1`] = ` -const a1 = "mc74f3fa7b_a-1" +const a1 = "mc74f3fa7b_a-1"; export default { "a-1" : a1 }; @@ -202,7 +202,7 @@ exports[`@modular-css/css-to-js API should handle options.namedExports set to: t `; exports[`@modular-css/css-to-js API should output css when requested: code 1`] = ` -const a = "mc74f3fa7b_a" +const a = "mc74f3fa7b_a"; export default { a }; @@ -214,21 +214,40 @@ export const styles = ".mc74f3fa7b_a { color: red; }"; `; exports[`@modular-css/css-to-js API should output without default export: code 1`] = ` -const a = "mc74f3fa7b_a" +const a = "mc74f3fa7b_a"; export { a }; `; +exports[`@modular-css/css-to-js API should represent external @values aliased to local @values: code 1`] = ` +import { $values as $aValues } from "/a.css"; +const v = "#00F"; +const $values = { + "values" : $aValues, +v, +}; +const b = "mc71966a67_b"; +export default { + $values, +b +}; + +export { + $values, +b +}; +`; + exports[`@modular-css/css-to-js API should represent external @values namespaces: code 1`] = ` import { $values as $aValues } from "/a.css"; -const v = "#0F0" +const v = "#0F0"; const $values = { "values" : $aValues, v, }; -const b = "mc71966a67_b" +const b = "mc71966a67_b"; export default { $values, b @@ -245,7 +264,7 @@ import { $values as $aValues } from "/a.css"; const $values = { "v" : $aValues["v"], }; -const b = "mc71966a67_b" +const b = "mc71966a67_b"; export default { $values, b @@ -259,7 +278,7 @@ b exports[`@modular-css/css-to-js API should represent external composition: code 1`] = ` import { a } from "/a.css"; -const b = a + " " + "mc71966a67_b" +const b = a + " " + "mc71966a67_b"; export default { b }; @@ -270,11 +289,11 @@ export { `; exports[`@modular-css/css-to-js API should represent local @values: code 1`] = ` -const v = "#00F" +const v = "#00F"; const $values = { v, }; -const a = "mc74f3fa7b_a" +const a = "mc74f3fa7b_a"; export default { $values, a @@ -287,8 +306,8 @@ a `; exports[`@modular-css/css-to-js API should represent local composition: code 1`] = ` -const a = "mc74f3fa7b_a" -const b = a + " " + "mc74f3fa7b_b" +const a = "mc74f3fa7b_a"; +const b = a + " " + "mc74f3fa7b_b"; export default { a, b @@ -302,7 +321,7 @@ b exports[`@modular-css/css-to-js API should use relative imports when requested: code 1`] = ` import { a } from "./a.css"; -const b = a + " " + "mc71966a67_b" +const b = a + " " + "mc71966a67_b"; export default { b }; diff --git a/packages/css-to-js/test/api.test.js b/packages/css-to-js/test/api.test.js index 61188d9a4..5efb5c48f 100644 --- a/packages/css-to-js/test/api.test.js +++ b/packages/css-to-js/test/api.test.js @@ -175,6 +175,24 @@ describe("@modular-css/css-to-js API", () => { expect(code).toMatchSnapshot("code"); expect(namedExports).toEqual([ "$values", "b" ]); }); + + it("should represent external @values aliased to local @values", async () => { + const processor = new Processor({ resolvers }); + + await processor.string("./a.css", `@value v1: #00F; @value v2: #F00; `); + await processor.string("./b.css", dedent(` + @value * as values from "./a.css"; + @value v: values.v1; + + .b { + border-color: v; + } + `)); + + const { code } = transform("./b.css", processor); + + expect(code).toMatchSnapshot("code"); + }); it("should generate javascript from composes", async () => { diff --git a/packages/processor/plugins/before/values-local.js b/packages/processor/plugins/before/values-local.js index 34f2e64fb..af0f9fa98 100644 --- a/packages/processor/plugins/before/values-local.js +++ b/packages/processor/plugins/before/values-local.js @@ -30,10 +30,15 @@ module.exports = () => ({ return; } - // Simple references to existing values are handled as object references, - // so they're always kept up-to-date + // Simple reference to an existing value if(values[details.value]) { - values[details.name] = values[details.value]; + values[details.name] = { + ...values[details.value], + source : rule.source, + external : false, + }; + + // console.log("values-local after", values[details.name]); } else { // Otherwise need to walk @value body and check for any replacments to make const parsed = value(details.value); @@ -47,8 +52,9 @@ module.exports = () => ({ }); values[details.name] = { - value : parsed.toString(), - source : rule.source, + value : parsed.toString(), + source : rule.source, + external : false, }; } diff --git a/packages/processor/plugins/values-import.js b/packages/processor/plugins/values-import.js index cdb50bde9..1e641cc5b 100644 --- a/packages/processor/plugins/values-import.js +++ b/packages/processor/plugins/values-import.js @@ -121,9 +121,12 @@ module.exports = () => ({ // Update any references that might've been affected by imports for(const name of Object.keys(values)) { const { value } = values[name]; - + if(value in values) { - values[name] = values[value]; + values[name] = { + ...values[value], + external : values[name].external, + }; } } }, diff --git a/packages/webpack/test/__snapshots__/webpack.test.js.snap b/packages/webpack/test/__snapshots__/webpack.test.js.snap index ef4bbe68a..a8e8f1617 100644 --- a/packages/webpack/test/__snapshots__/webpack.test.js.snap +++ b/packages/webpack/test/__snapshots__/webpack.test.js.snap @@ -17,7 +17,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ "styles": () => (/* binding */ styles), /* harmony export */ "wooga": () => (/* binding */ wooga) /* harmony export */ }); -const wooga = "mc8d99986b_wooga" +const wooga = "mc8d99986b_wooga"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ wooga }); @@ -123,7 +123,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ "one": () => (/* binding */ one), /* harmony export */ "styles": () => (/* binding */ styles) /* harmony export */ }); -const one = "mc_one" +const one = "mc_one"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ one }); @@ -229,7 +229,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ "styles": () => (/* binding */ styles), /* harmony export */ "two": () => (/* binding */ two) /* harmony export */ }); -const two = "mc_two" +const two = "mc_two"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ two }); @@ -654,11 +654,11 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ "folder": () => (/* binding */ folder1), /* harmony export */ "styles": () => (/* binding */ styles) /* harmony export */ }); -const folder = "white" +const folder = "white"; const $values = { folder, }; -const folder1 = "mc_folder" +const folder1 = "mc_folder"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ $values, "folder" : folder1 @@ -686,15 +686,15 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ }); /* harmony import */ var _folder_folder_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./folder/folder.css */ "./packages/webpack/test/specimens/folder/folder.css"); -const one = "red" -const two = "blue" +const one = "red"; +const two = "blue"; const $values = { "folder" : _folder_folder_css__WEBPACK_IMPORTED_MODULE_0__.$values.folder, one, two, }; -const booga = "mc_booga" -const looga = booga + " " + "mc_looga" +const booga = "mc_booga"; +const looga = booga + " " + "mc_looga"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ $values, booga, @@ -729,9 +729,9 @@ const $values = { "two" : _local_css__WEBPACK_IMPORTED_MODULE_0__.$values.two, "folder" : _local_css__WEBPACK_IMPORTED_MODULE_0__.$values.folder, }; -const wooga = _local_css__WEBPACK_IMPORTED_MODULE_0__.booga + " " + "mc_wooga" -const booga1 = "mc_booga" -const tooga = "mc_tooga" +const wooga = _local_css__WEBPACK_IMPORTED_MODULE_0__.booga + " " + "mc_wooga"; +const booga1 = "mc_booga"; +const tooga = "mc_tooga"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ $values, wooga, @@ -873,7 +873,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ "styles": () => (/* binding */ styles), /* harmony export */ "wooga": () => (/* binding */ wooga) /* harmony export */ }); -const wooga = "mc_wooga" +const wooga = "mc_wooga"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ wooga }); @@ -985,7 +985,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ "styles": () => (/* binding */ styles), /* harmony export */ "wooga": () => (/* binding */ wooga) /* harmony export */ }); -const wooga = "mc_wooga" +const wooga = "mc_wooga"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ wooga }); @@ -1094,12 +1094,12 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), /* harmony export */ "styles": () => (/* binding */ styles) /* harmony export */ }); -const val = "\\"value\\"" +const val = "\\"value\\""; const $values = { val, }; -const a = "mc_a" -const b = "mc_b" +const a = "mc_a"; +const b = "mc_b"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ $values, a, @@ -1211,12 +1211,12 @@ __webpack_require__.r(__webpack_exports__); /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__), /* harmony export */ "styles": () => (/* binding */ styles) /* harmony export */ }); -const val = "\\"value\\"" +const val = "\\"value\\""; const $values = { val, }; -const a = "mc_a" -const b = "mc_b" +const a = "mc_a"; +const b = "mc_b"; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ $values, a,