From 22b48b77cf55733c84758086eff748905602dc0b Mon Sep 17 00:00:00 2001 From: Pat Cavit Date: Sun, 11 Aug 2019 23:27:20 -0700 Subject: [PATCH 1/3] feat(processor): allow composes anywhere in a rule Fixes #645 BREAKING CHANGE: previously `modular-css` would require that `composes` be the first declaration in a rule. This restriction has been removed due to better solutions for enforcing that behavior existing now (stylelint-order). --- packages/processor/plugins/composition.js | 18 --------- .../__snapshots__/composition.test.js.snap | 10 +++++ packages/processor/test/composition.test.js | 40 +++++++++++-------- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/packages/processor/plugins/composition.js b/packages/processor/plugins/composition.js index d7b7c8c09..44683c94b 100644 --- a/packages/processor/plugins/composition.js +++ b/packages/processor/plugins/composition.js @@ -11,22 +11,6 @@ const parser = require("../parsers/composes.js"); const plugin = "modular-css-composition"; -// Loop through all previous nodes in the container to ensure -// that composes (or a comment) comes first -const composesFirst = (decl) => { - let prev = decl.prev(); - - while(prev) { - if(prev.type !== "comment") { - throw decl.error("composes must be the first declaration", { - word : "composes", - }); - } - - prev = prev.prev(); - } -}; - module.exports = (css, result) => { const { opts } = result; @@ -47,8 +31,6 @@ module.exports = (css, result) => { const details = parser.parse(decl.value); const selectors = decl.parent.selectors.map(identifiers.parse); - composesFirst(decl); - // https://github.com/tivac/modular-css/issues/238 if(selectors.some(({ length }) => length > 1)) { throw decl.error( diff --git a/packages/processor/test/__snapshots__/composition.test.js.snap b/packages/processor/test/__snapshots__/composition.test.js.snap index ca8ed014d..e182270b7 100644 --- a/packages/processor/test/__snapshots__/composition.test.js.snap +++ b/packages/processor/test/__snapshots__/composition.test.js.snap @@ -9,6 +9,16 @@ Object { } `; +exports[`/processor.js composition should allow composes anywhere 1`] = ` +Object { + "multiple-composes.css": Object { + "a": "a", + "b": "a b", + "c": "a b c", + }, +} +`; + exports[`/processor.js composition should compose a single class 1`] = ` Object { "single-composes.css": Object { diff --git a/packages/processor/test/composition.test.js b/packages/processor/test/composition.test.js index 4aff1a8d3..37e7f3320 100644 --- a/packages/processor/test/composition.test.js +++ b/packages/processor/test/composition.test.js @@ -69,23 +69,6 @@ describe("/processor.js", () => { } }); - it("should fail if composes isn't the first property", async () => { - try { - await processor.string( - "./invalid/composes-first.css", - dedent(` - .a { color: red; } - .b { - color: blue; - composes: a; - } - `) - ); - } catch({ message }) { - expect(message).toMatch(`composes must be the first declaration`); - } - }); - it("should fail on rules that use multiple selectors", async () => { try { await processor.string( @@ -130,6 +113,29 @@ describe("/processor.js", () => { expect(compositions).toMatchSnapshot(); }); + + it("should allow composes anywhere", async () => { + await processor.string( + "./multiple-composes.css", + dedent(` + .a { color: red; } + .b { + background: blue; + composes: a; + } + .c { + border: 1px solid red; + composes: a; + text-weight: bold; + composes: b; + } + `) + ); + + const { compositions } = await processor.output(); + + expect(compositions).toMatchSnapshot(); + }); it("should compose from globals", async () => { await processor.string( From 31c0d336cab06109606c5b6492221bb530aabbfa Mon Sep 17 00:00:00 2001 From: Pat Cavit Date: Sun, 11 Aug 2019 23:32:50 -0700 Subject: [PATCH 2/3] feat(docs): Add docs for #646 --- packages/www/src/guide/comparison.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/www/src/guide/comparison.md b/packages/www/src/guide/comparison.md index 0ccfa893a..c95710ed3 100644 --- a/packages/www/src/guide/comparison.md +++ b/packages/www/src/guide/comparison.md @@ -93,3 +93,7 @@ CSS Modules allows for importing multiple values from an external file. ### Support CSS Modules is really only fully-supported as part of webpack these days. The repo is effectively mothballed, and there appears to be almost no one supporting the current codebase. Since webpack is the only live version & we prefer to use rollup for it's cleaner output and smaller bundles we needed an approach that could be flexibly be used with a [variety](#rollup) [of](#browserify) [tools](#cli). + +### `composes` location + +After a long time with `composes` being required to be the first declaration in a rule the ability to use a tool like [`stylelint-order`]() has reduced the need for `modular-css` to enforce positional requirements. After a push in [#645](https://github.com/tivac/modular-css/issues/645) the requirement was removed in [#646](https://github.com/tivac/modular-css/pull/646), which was published in v25. This is a change from CSS Modules, which continues to require that `composes` be the first declaration in a rule. \ No newline at end of file From 8e47c84c39b5ebe55e8f8a77a6864028c92cd07a Mon Sep 17 00:00:00 2001 From: Pat Cavit Date: Sun, 11 Aug 2019 23:37:23 -0700 Subject: [PATCH 3/3] fix(docs): add missing link target --- packages/www/src/guide/comparison.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/www/src/guide/comparison.md b/packages/www/src/guide/comparison.md index c95710ed3..34eeb8d5d 100644 --- a/packages/www/src/guide/comparison.md +++ b/packages/www/src/guide/comparison.md @@ -96,4 +96,4 @@ CSS Modules is really only fully-supported as part of webpack these days. The re ### `composes` location -After a long time with `composes` being required to be the first declaration in a rule the ability to use a tool like [`stylelint-order`]() has reduced the need for `modular-css` to enforce positional requirements. After a push in [#645](https://github.com/tivac/modular-css/issues/645) the requirement was removed in [#646](https://github.com/tivac/modular-css/pull/646), which was published in v25. This is a change from CSS Modules, which continues to require that `composes` be the first declaration in a rule. \ No newline at end of file +After a long time with `composes` being required to be the first declaration in a rule the ability to use a tool like [`stylelint-order`](https://github.com/hudochenkov/stylelint-order) has reduced the need for `modular-css` to enforce positional requirements. After a push in [#645](https://github.com/tivac/modular-css/issues/645) the requirement was removed in [#646](https://github.com/tivac/modular-css/pull/646), which was published in v25. This is a change from CSS Modules, which continues to require that `composes` be the first declaration in a rule. \ No newline at end of file