diff --git a/package-lock.json b/package-lock.json index e15b868..90c60ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,20 +11,19 @@ "dependencies": { "css-declaration-sorter": "^7.0.0", "postcss-less": "^6.0.0", - "postcss-scss": "^4.0.3", - "sync-threads": "^1.0.1" + "postcss-scss": "^4.0.3" }, "engines": { - "node": ">=14" + "node": ">=16" }, "peerDependencies": { - "prettier": "2.x" + "prettier": "3.x" } }, "node_modules/css-declaration-sorter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.0.0.tgz", - "integrity": "sha512-jV48Uxg3jWGLthtZhYAH3JFWMjdurJrSQAgWCc/t2ZE0UUFAIWlgcXcLJNutZT8GXrLAr36Kp+O1w3yBdxCr/A==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.0.3.tgz", + "integrity": "sha512-/PHObPdiAXf0H3LOZCyXgBLt5fiS5XGCml/Ylpkmr7ADgq94GffvdGxJEmsSLDo0XGzItJY79dusRka0e4UVLw==", "engines": { "node": "^14 || ^16 || >=18" }, @@ -33,9 +32,15 @@ } }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" @@ -51,9 +56,9 @@ "peer": true }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", + "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", "funding": [ { "type": "opencollective", @@ -62,11 +67,15 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "peer": true, "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -107,15 +116,15 @@ } }, "node_modules/prettier": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.6.tgz", - "integrity": "sha512-mtuzdiBbHwPEgl7NxWlqOkithPyp4VN93V7VeHVWBF+ad3I5avc0RVDT4oImXQy9H/AqxA2NSQH8pSxHW6FYbQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", + "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", "peer": true, "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" @@ -129,11 +138,6 @@ "engines": { "node": ">=0.10.0" } - }, - "node_modules/sync-threads": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sync-threads/-/sync-threads-1.0.1.tgz", - "integrity": "sha512-hIdwt/c/e1ONnr2RJmfBxEAj/J6KQQWKdToF3Qw8ZNRsTNNteGkOe63rQy9I7J5UNlr8Yl0wkzIr9wgLY94x0Q==" } } } diff --git a/package.json b/package.json index a552367..dfa4bbc 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,14 @@ "name": "prettier-plugin-css-order", "version": "1.3.1", "description": "Sort CSS declarations in a certain order.", - "type": "commonjs", - "main": "./src/main.js", + "type": "module", + "main": "./src/main.mjs", "files": [ - "src/*.js", - "!src/*.test.js" + "src/*.mjs", + "!src/*.test.mjs" ], "scripts": { - "test": "node src/main.test.js", + "test": "node src/main.test.mjs", "lint": "prettier src --check", "format": "prettier src --write", "postversion": "git push --follow-tags" @@ -17,14 +17,13 @@ "dependencies": { "css-declaration-sorter": "^7.0.0", "postcss-less": "^6.0.0", - "postcss-scss": "^4.0.3", - "sync-threads": "^1.0.1" + "postcss-scss": "^4.0.3" }, "peerDependencies": { - "prettier": "2.x" + "prettier": "3.x" }, "engines": { - "node": ">=14" + "node": ">=16" }, "repository": { "type": "git", diff --git a/src/main.js b/src/main.mjs similarity index 51% rename from src/main.js rename to src/main.mjs index 57d806d..e422cd8 100644 --- a/src/main.js +++ b/src/main.mjs @@ -1,28 +1,37 @@ -const path = require("path"); -const prettier = require("prettier/parser-postcss"); -const { createSyncFn } = require("sync-threads"); +import prettierPostcss from "prettier/parser-postcss"; +import postcss from "postcss"; +import { cssDeclarationSorter } from "css-declaration-sorter"; +import postcssLess from "postcss-less"; +import postcssScss from "postcss-scss"; -const preprocess = (text, options) => { - const sorter = createSyncFn( - path.join(__dirname, "sorter.js"), - 2 * 1024 * 1024 - ); +const syntaxMapping = { + less: postcssLess, + scss: postcssScss, +}; - const sortedText = sorter({ - text, - parser: options.parser, - pluginOptions: { +function parseSort(text, options) { + return postcss([ + cssDeclarationSorter({ order: options.order, keepOverrides: options.keepOverrides, - }, - }); - - options.originalText = sortedText; - - return sortedText; -}; + }), + ]) + .process(text, { + from: undefined, + syntax: syntaxMapping[options.parser], + }) + .then((result) => result.css) + .then((sortedCss) => { + options.originalText = sortedCss; + return prettierPostcss.parsers[options.parser].parse( + sortedCss, + [options.parser], + options, + ); + }); +} -module.exports = { +export default { options: { order: { type: "choice", @@ -56,16 +65,16 @@ module.exports = { }, parsers: { css: { - ...prettier.parsers.css, - preprocess, + ...prettierPostcss.parsers.css, + parse: parseSort, }, less: { - ...prettier.parsers.less, - preprocess, + ...prettierPostcss.parsers.less, + parse: parseSort, }, scss: { - ...prettier.parsers.scss, - preprocess, + ...prettierPostcss.parsers.scss, + parse: parseSort, }, }, }; diff --git a/src/main.test.js b/src/main.test.js deleted file mode 100644 index 1fa61ff..0000000 --- a/src/main.test.js +++ /dev/null @@ -1,64 +0,0 @@ -const prettier = require("prettier"); -const assert = require("assert"); - -assert.strictEqual( - prettier.format("a{font-size: 1rem; height: 1rem;}", { - parser: "css", - plugins: ["."], - }), - "a {\n height: 1rem;\n font-size: 1rem;\n}\n", - "sorts given CSS" -); - -assert.strictEqual( - prettier.format( - "a{height: 1rem; margin-left: -#{$grid-default-gutter / 2};}", - { - parser: "scss", - plugins: ["."], - } - ), - "a {\n margin-left: -#{$grid-default-gutter / 2};\n height: 1rem;\n}\n", - "sorts given SCSS" -); - -assert.strictEqual( - prettier.format( - "a{\n // something \n font-size: @hi; \n height: 1rem; \n }", - { - parser: "less", - plugins: ["."], - } - ), - "a {\n height: 1rem;\n // something\n font-size: @hi;\n}\n", - "sorts given Less" -); - -assert.throws( - () => prettier.format("/*/*/* x", { parser: "css", plugins: ["."] }), - "surfaces errors to Prettier" -); - -assert.strictEqual( - prettier.format( - "", - { - parser: "html", - plugins: ["."], - } - ), - "\n", - "sorts embedded CSS with comment" -); - -assert.strictEqual( - prettier.format( - "a{\n font-size: 100%; /* font-size comment */ \n height: 1rem; \n }", - { - parser: "css", - plugins: ["."], - } - ), - "a {\n height: 1rem;\n font-size: 100%; /* font-size comment */\n}\n", - "sorts CSS with comment" -); diff --git a/src/main.test.mjs b/src/main.test.mjs new file mode 100644 index 0000000..316e6b7 --- /dev/null +++ b/src/main.test.mjs @@ -0,0 +1,59 @@ +import { format } from "prettier"; +import assert from "assert"; +import plugin from "./main.mjs"; + +assert.strictEqual( + await format("a{font-size: 1rem; height: 1rem;}", { + parser: "css", + plugins: [plugin], + }), + "a {\n height: 1rem;\n font-size: 1rem;\n}\n", + "sorts given CSS", +); + +assert.strictEqual( + await format("a{height: 1rem; margin-left: -#{$grid-default-gutter / 2};}", { + parser: "scss", + plugins: [plugin], + }), + "a {\n margin-left: -#{$grid-default-gutter / 2};\n height: 1rem;\n}\n", + "sorts given SCSS", +); + +assert.strictEqual( + await format("a{\n // something \n font-size: @hi; \n height: 1rem; \n }", { + parser: "less", + plugins: [plugin], + }), + "a {\n height: 1rem;\n // something\n font-size: @hi;\n}\n", + "sorts given Less", +); + +assert.rejects( + () => format("/*/*/* x", { parser: "css", plugins: [plugin] }), + "surfaces errors to Prettier", +); + +assert.strictEqual( + await format( + "", + { + parser: "html", + plugins: [plugin], + }, + ), + "\n", + "sorts embedded CSS with comment", +); + +assert.strictEqual( + await format( + "a{\n font-size: 100%; /* font-size comment */ \n height: 1rem; \n }", + { + parser: "css", + plugins: [plugin], + }, + ), + "a {\n height: 1rem;\n font-size: 100%; /* font-size comment */\n}\n", + "sorts CSS with comment", +); diff --git a/src/sorter.js b/src/sorter.js deleted file mode 100644 index e387026..0000000 --- a/src/sorter.js +++ /dev/null @@ -1,19 +0,0 @@ -const postcss = require("postcss"); -const cssDeclarationSorter = require("css-declaration-sorter"); -const { runAsWorker } = require("sync-threads"); -const postcssLess = require("postcss-less"); -const postcssScss = require("postcss-scss"); - -runAsWorker(async ({ text, parser, pluginOptions }) => { - const syntaxMapping = { - less: postcssLess, - scss: postcssScss, - }; - - return postcss([cssDeclarationSorter(pluginOptions)]) - .process(text, { - from: undefined, - syntax: syntaxMapping[parser], - }) - .then((result) => result.css); -});