From 1caec5de6915b9e021b881e4b57efdb41c5c8235 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Mon, 21 Feb 2022 14:22:51 +0800 Subject: [PATCH] Migrate CSS language to ES Module (#12341) --- .eslintrc.cjs | 1 - scripts/build/bundler.mjs | 4 +- scripts/build/config.mjs | 1 + src/language-css/clean.js | 8 +-- src/language-css/embed.js | 9 +-- src/language-css/index.js | 15 +++-- src/language-css/loc.js | 17 ++---- src/language-css/options.js | 8 +-- src/language-css/package.json | 5 -- src/language-css/parser-postcss.js | 54 +++++++++--------- src/language-css/parsers.js | 12 ++-- src/language-css/pragma.js | 11 +--- src/language-css/printer-postcss.js | 56 ++++++++++--------- .../utils/has-scss-interpolation.js | 6 +- .../utils/has-string-or-function.js | 6 +- src/language-css/utils/index.js | 4 +- src/language-css/utils/is-module-rule-name.js | 4 +- .../utils/is-scss-nested-property-node.js | 4 +- src/language-css/utils/is-scss-variable.js | 4 +- src/language-css/utils/stringify-node.js | 4 +- src/languages.js | 3 +- 21 files changed, 105 insertions(+), 131 deletions(-) delete mode 100644 src/language-css/package.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs index c0faac218..e29c24bf8 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -176,7 +176,6 @@ module.exports = { "src/common/**/*.js", "src/config/**/*.js", "src/document/**/*.js", - "src/language-css/**/*.js", "src/language-handlebars/**/*.js", "src/language-html/**/*.js", "src/language-js/**/*.js", diff --git a/scripts/build/bundler.mjs b/scripts/build/bundler.mjs index 0901f3b5f..e32f24520 100644 --- a/scripts/build/bundler.mjs +++ b/scripts/build/bundler.mjs @@ -87,7 +87,6 @@ function* getEsbuildOptions(bundle, buildOptions) { // Replace parser getters with `undefined` for (const file of [ - "src/language-css/parsers.js", "src/language-handlebars/parsers.js", "src/language-html/parsers.js", "src/language-js/parse/parsers.js", @@ -95,8 +94,7 @@ function* getEsbuildOptions(bundle, buildOptions) { replaceModule[path.join(PROJECT_ROOT, file)] = EMPTY_MODULE_REPLACEMENT; } for (const file of [ - // "src/language-css/parsers.js", - // "src/language-graphql/parsers.js", + "src/language-css/parsers.js", "src/language-graphql/parsers.js", // "src/language-handlebars/parsers.js", // "src/language-html/parsers.js", diff --git a/scripts/build/config.mjs b/scripts/build/config.mjs index c79398812..acc2720d8 100644 --- a/scripts/build/config.mjs +++ b/scripts/build/config.mjs @@ -121,6 +121,7 @@ const parsers = [ // https://github.com/shellscape/postcss-values-parser/blob/c00f858ab8c86ce9f06fdb702e8f26376f467248/lib/parser.js#L499 "node.constructor.name === 'Word'": "node.type === 'word'", }, + isEsm: true, }, { input: "src/language-graphql/parser-graphql.js", diff --git a/src/language-css/clean.js b/src/language-css/clean.js index 071f6ccdf..344874c94 100644 --- a/src/language-css/clean.js +++ b/src/language-css/clean.js @@ -1,7 +1,5 @@ -"use strict"; - -const { isFrontMatterNode } = require("../common/util.js"); -const getLast = require("../utils/get-last.js"); +import { isFrontMatterNode } from "../common/util.js"; +import getLast from "../utils/get-last.js"; const ignoredProperties = new Set([ "raw", // front-matter @@ -194,4 +192,4 @@ function cleanCSSStrings(value) { return value.replace(/'/g, '"').replace(/\\([^\dA-Fa-f])/g, "$1"); } -module.exports = clean; +export default clean; diff --git a/src/language-css/embed.js b/src/language-css/embed.js index 1f96780b4..dd8e5a970 100644 --- a/src/language-css/embed.js +++ b/src/language-css/embed.js @@ -1,8 +1,9 @@ -"use strict"; +import doc from "../document/index.js"; +import printFrontMatter from "../utils/front-matter/print.js"; + const { builders: { hardline }, -} = require("../document/index.js"); -const printFrontMatter = require("../utils/front-matter/print.js"); +} = doc; function embed(path, print, textToDoc /*, options */) { const node = path.getValue(); @@ -13,4 +14,4 @@ function embed(path, print, textToDoc /*, options */) { } } -module.exports = embed; +export default embed; diff --git a/src/language-css/index.js b/src/language-css/index.js index 75f63f98f..4cd6b0286 100644 --- a/src/language-css/index.js +++ b/src/language-css/index.js @@ -1,9 +1,10 @@ -"use strict"; +import { createRequire } from "module"; +import createLanguage from "../utils/create-language.js"; +import printer from "./printer-postcss.js"; +import options from "./options.js"; +import parsers from "./parsers.js"; -const createLanguage = require("../utils/create-language.js"); -const printer = require("./printer-postcss.js"); -const options = require("./options.js"); -const parsers = require("./parsers.js"); +const require = createRequire(import.meta.url); const languages = [ createLanguage(require("linguist-languages/data/CSS.json"), (data) => ({ @@ -38,9 +39,11 @@ const printers = { postcss: printer, }; -module.exports = { +const language = { languages, options, printers, parsers, }; + +export default language; diff --git a/src/language-css/loc.js b/src/language-css/loc.js index fb5088b7f..4344d1eec 100644 --- a/src/language-css/loc.js +++ b/src/language-css/loc.js @@ -1,9 +1,7 @@ -"use strict"; - -const { skipEverythingButNewLine } = require("../utils/text/skip.js"); -const getLast = require("../utils/get-last.js"); -const isNonEmptyArray = require("../utils/is-non-empty-array.js"); -const lineColumnToIndex = require("../utils/line-column-to-index.js"); +import { skipEverythingButNewLine } from "../utils/text/skip.js"; +import getLast from "../utils/get-last.js"; +import isNonEmptyArray from "../utils/is-non-empty-array.js"; +import lineColumnToIndex from "../utils/line-column-to-index.js"; function calculateLocStart(node, text) { // `postcss>=8` @@ -257,9 +255,4 @@ function locEnd(node) { return node.source.endOffset; } -module.exports = { - locStart, - locEnd, - calculateLoc, - replaceQuotesInInlineComments, -}; +export { locStart, locEnd, calculateLoc, replaceQuotesInInlineComments }; diff --git a/src/language-css/options.js b/src/language-css/options.js index f5f381ae9..a2f1bf452 100644 --- a/src/language-css/options.js +++ b/src/language-css/options.js @@ -1,8 +1,8 @@ -"use strict"; - -const commonOptions = require("../common/common-options.js"); +import commonOptions from "../common/common-options.js"; // format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.js -module.exports = { +const options = { singleQuote: commonOptions.singleQuote, }; + +export default options; diff --git a/src/language-css/package.json b/src/language-css/package.json deleted file mode 100644 index 54d221724..000000000 --- a/src/language-css/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "//TODO": "Remove this file when we close #10157", - "type": "commonjs", - "description": "A package.json file to use `.js` files in this directory as CommonJS module." -} diff --git a/src/language-css/parser-postcss.js b/src/language-css/parser-postcss.js index 0cea5e6b3..6add2ffd8 100644 --- a/src/language-css/parser-postcss.js +++ b/src/language-css/parser-postcss.js @@ -1,17 +1,24 @@ -"use strict"; +// TODO[@fisker]: try inline import these modules +// Inline the require to avoid loading all the JS if we don't use it +import postcss from "postcss"; +import less from "postcss-less"; +import scss from "postcss-scss"; +import valueParser from "postcss-values-parser"; +import selectorParser from "postcss-selector-parser"; +import mediaParser from "postcss-media-query-parser"; -const createError = require("../common/parser-create-error.js"); -const getLast = require("../utils/get-last.js"); -const parseFrontMatter = require("../utils/front-matter/parse.js"); -const { hasPragma } = require("./pragma.js"); -const { locStart, locEnd } = require("./loc.js"); -const { calculateLoc, replaceQuotesInInlineComments } = require("./loc.js"); -const hasSCSSInterpolation = require("./utils/has-scss-interpolation.js"); -const hasStringOrFunction = require("./utils/has-string-or-function.js"); -const isSCSSNestedPropertyNode = require("./utils/is-scss-nested-property-node.js"); -const isSCSSVariable = require("./utils/is-scss-variable.js"); -const stringifyNode = require("./utils/stringify-node.js"); -const isModuleRuleName = require("./utils/is-module-rule-name.js"); +import createError from "../common/parser-create-error.js"; +import getLast from "../utils/get-last.js"; +import parseFrontMatter from "../utils/front-matter/parse.js"; +import { hasPragma } from "./pragma.js"; +import { locStart, locEnd } from "./loc.js"; +import { calculateLoc, replaceQuotesInInlineComments } from "./loc.js"; +import hasSCSSInterpolation from "./utils/has-scss-interpolation.js"; +import hasStringOrFunction from "./utils/has-string-or-function.js"; +import isSCSSNestedPropertyNode from "./utils/is-scss-nested-property-node.js"; +import isSCSSVariable from "./utils/is-scss-variable.js"; +import stringifyNode from "./utils/stringify-node.js"; +import isModuleRuleName from "./utils/is-module-rule-name.js"; const getHighestAncestor = (node) => { while (node.parent) { @@ -206,8 +213,6 @@ function parseNestedValue(node, options) { } function parseValue(value, options) { - const valueParser = require("postcss-values-parser"); - let result = null; try { @@ -238,8 +243,6 @@ function parseSelector(selector) { }; } - const selectorParser = require("postcss-selector-parser"); - let result = null; try { @@ -263,12 +266,10 @@ function parseSelector(selector) { } function parseMediaQuery(params) { - const mediaParser = require("postcss-media-query-parser").default; - let result = null; try { - result = mediaParser(params); + result = mediaParser.default(params); } catch { // Ignore bad media queries /* istanbul ignore next */ @@ -680,24 +681,21 @@ function parseWithParser(parse, text, options) { } function parseCss(text, parsers, options = {}) { - const { parse } = require("postcss"); - return parseWithParser(parse, text, options); + return parseWithParser(postcss.parse, text, options); } function parseLess(text, parsers, options = {}) { - const lessParser = require("postcss-less"); return parseWithParser( // Workaround for https://github.com/shellscape/postcss-less/issues/145 // See comments for `replaceQuotesInInlineComments` in `loc.js`. - (text) => lessParser.parse(replaceQuotesInInlineComments(text)), + (text) => less.parse(replaceQuotesInInlineComments(text)), text, options ); } function parseScss(text, parsers, options = {}) { - const { parse } = require("postcss-scss"); - return parseWithParser(parse, text, options); + return parseWithParser(scss.parse, text, options); } const postCssParser = { @@ -708,7 +706,7 @@ const postCssParser = { }; // Export as a plugin so we can reuse the same bundle for UMD loading -module.exports = { +const postcssParser = { parsers: { css: { ...postCssParser, @@ -724,3 +722,5 @@ module.exports = { }, }, }; + +export default postcssParser; diff --git a/src/language-css/parsers.js b/src/language-css/parsers.js index 855020041..498856b60 100644 --- a/src/language-css/parsers.js +++ b/src/language-css/parsers.js @@ -1,14 +1,16 @@ -"use strict"; +import parserPostCss from "./parser-postcss.js"; -module.exports = { +const parsers = { // TODO: switch these to just `postcss` and use `language` instead. get css() { - return require("./parser-postcss.js").parsers.css; + return parserPostCss.parsers.css; }, get less() { - return require("./parser-postcss.js").parsers.less; + return parserPostCss.parsers.less; }, get scss() { - return require("./parser-postcss.js").parsers.scss; + return parserPostCss.parsers.scss; }, }; + +export default parsers; diff --git a/src/language-css/pragma.js b/src/language-css/pragma.js index 407e9f554..d7996db30 100644 --- a/src/language-css/pragma.js +++ b/src/language-css/pragma.js @@ -1,7 +1,5 @@ -"use strict"; - -const jsPragma = require("../language-js/pragma.js"); -const parseFrontMatter = require("../utils/front-matter/parse.js"); +import jsPragma from "../language-js/pragma.js"; +import parseFrontMatter from "../utils/front-matter/parse.js"; function hasPragma(text) { return jsPragma.hasPragma(parseFrontMatter(text).content); @@ -15,7 +13,4 @@ function insertPragma(text) { ); } -module.exports = { - hasPragma, - insertPragma, -}; +export { hasPragma, insertPragma }; diff --git a/src/language-css/printer-postcss.js b/src/language-css/printer-postcss.js index bccf1c4a1..6f4006d49 100644 --- a/src/language-css/printer-postcss.js +++ b/src/language-css/printer-postcss.js @@ -1,34 +1,18 @@ -"use strict"; - -const getLast = require("../utils/get-last.js"); -const { +import getLast from "../utils/get-last.js"; +import { printNumber, printString, hasNewline, isFrontMatterNode, isNextLineEmpty, isNonEmptyArray, -} = require("../common/util.js"); -const { - builders: { - join, - line, - hardline, - softline, - group, - fill, - indent, - dedent, - ifBreak, - breakParent, - }, - utils: { removeLines, getDocParts }, -} = require("../document/index.js"); -const clean = require("./clean.js"); -const embed = require("./embed.js"); -const { insertPragma } = require("./pragma.js"); +} from "../common/util.js"; +import doc from "../document/index.js"; +import clean from "./clean.js"; +import embed from "./embed.js"; +import { insertPragma } from "./pragma.js"; -const { +import { getAncestorNode, getPropOfDeclNode, maybeToLowerCase, @@ -74,8 +58,24 @@ const { isAtWordPlaceholderNode, isConfigurationNode, isParenGroupNode, -} = require("./utils/index.js"); -const { locStart, locEnd } = require("./loc.js"); +} from "./utils/index.js"; +import { locStart, locEnd } from "./loc.js"; + +const { + builders: { + join, + line, + hardline, + softline, + group, + fill, + indent, + dedent, + ifBreak, + breakParent, + }, + utils: { removeLines, getDocParts }, +} = doc; function shouldPrintComma(options) { return options.trailingComma === "es5" || options.trailingComma === "all"; @@ -1118,9 +1118,11 @@ function printCssNumber(rawNumber) { ); } -module.exports = { +const printer = { print: genericPrint, embed, insertPragma, massageAstNode: clean, }; + +export default printer; diff --git a/src/language-css/utils/has-scss-interpolation.js b/src/language-css/utils/has-scss-interpolation.js index 0ef726e18..a2e455959 100644 --- a/src/language-css/utils/has-scss-interpolation.js +++ b/src/language-css/utils/has-scss-interpolation.js @@ -1,6 +1,4 @@ -"use strict"; - -const isNonEmptyArray = require("../../utils/is-non-empty-array.js"); +import isNonEmptyArray from "../../utils/is-non-empty-array.js"; function hasSCSSInterpolation(groupList) { if (isNonEmptyArray(groupList)) { @@ -19,4 +17,4 @@ function hasSCSSInterpolation(groupList) { return false; } -module.exports = hasSCSSInterpolation; +export default hasSCSSInterpolation; diff --git a/src/language-css/utils/has-string-or-function.js b/src/language-css/utils/has-string-or-function.js index d11bde837..486bc456d 100644 --- a/src/language-css/utils/has-string-or-function.js +++ b/src/language-css/utils/has-string-or-function.js @@ -1,6 +1,4 @@ -"use strict"; - -const isNonEmptyArray = require("../../utils/is-non-empty-array.js"); +import isNonEmptyArray from "../../utils/is-non-empty-array.js"; function hasStringOrFunction(groupList) { if (isNonEmptyArray(groupList)) { @@ -13,4 +11,4 @@ function hasStringOrFunction(groupList) { return false; } -module.exports = hasStringOrFunction; +export default hasStringOrFunction; diff --git a/src/language-css/utils/index.js b/src/language-css/utils/index.js index 6a63a3d44..b6c7417e3 100644 --- a/src/language-css/utils/index.js +++ b/src/language-css/utils/index.js @@ -1,5 +1,3 @@ -"use strict"; - const colorAdjusterFunctions = new Set([ "red", "green", @@ -430,7 +428,7 @@ function isParenGroupNode(node) { ); } -module.exports = { +export { getAncestorCounter, getAncestorNode, getPropOfDeclNode, diff --git a/src/language-css/utils/is-module-rule-name.js b/src/language-css/utils/is-module-rule-name.js index 8ee9c47d8..7fe1a0e9e 100644 --- a/src/language-css/utils/is-module-rule-name.js +++ b/src/language-css/utils/is-module-rule-name.js @@ -1,9 +1,7 @@ -"use strict"; - const moduleRuleNames = new Set(["import", "use", "forward"]); function isModuleRuleName(name) { return moduleRuleNames.has(name); } -module.exports = isModuleRuleName; +export default isModuleRuleName; diff --git a/src/language-css/utils/is-scss-nested-property-node.js b/src/language-css/utils/is-scss-nested-property-node.js index a1e3f3e54..49be8e452 100644 --- a/src/language-css/utils/is-scss-nested-property-node.js +++ b/src/language-css/utils/is-scss-nested-property-node.js @@ -1,5 +1,3 @@ -"use strict"; - function isSCSSNestedPropertyNode(node, options) { if (options.parser !== "scss") { return false; @@ -17,4 +15,4 @@ function isSCSSNestedPropertyNode(node, options) { .endsWith(":"); } -module.exports = isSCSSNestedPropertyNode; +export default isSCSSNestedPropertyNode; diff --git a/src/language-css/utils/is-scss-variable.js b/src/language-css/utils/is-scss-variable.js index 2dd4c165f..37646d917 100644 --- a/src/language-css/utils/is-scss-variable.js +++ b/src/language-css/utils/is-scss-variable.js @@ -1,5 +1,3 @@ -"use strict"; - function isSCSSVariable(node, options) { return Boolean( options.parser === "scss" && @@ -9,4 +7,4 @@ function isSCSSVariable(node, options) { ); } -module.exports = isSCSSVariable; +export default isSCSSVariable; diff --git a/src/language-css/utils/stringify-node.js b/src/language-css/utils/stringify-node.js index f0fe3747f..ef92d6be5 100644 --- a/src/language-css/utils/stringify-node.js +++ b/src/language-css/utils/stringify-node.js @@ -1,5 +1,3 @@ -"use strict"; - function stringifyNode(node) { if (node.groups) { const open = node.open && node.open.value ? node.open.value : ""; @@ -29,4 +27,4 @@ function stringifyNode(node) { return before + quote + atword + value + quote + unit + group + after; } -module.exports = stringifyNode; +export default stringifyNode; diff --git a/src/languages.js b/src/languages.js index 4ba70b6cd..5a86a84f7 100644 --- a/src/languages.js +++ b/src/languages.js @@ -1,4 +1,5 @@ import { createRequire } from "module"; +import css from "./language-css/index.js"; import graphql from "./language-graphql/index.js"; import markdown from "./language-markdown/index.js"; import yaml from "./language-yaml/index.js"; @@ -10,7 +11,7 @@ const languages = [ // JS require("./language-js/index.js"), // CSS - require("./language-css/index.js"), + css, // Handlebars require("./language-handlebars/index.js"), // GraphQL