diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 2413a2df2..5f46cdcab 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -181,7 +181,6 @@ module.exports = { "src/language-handlebars/**/*.js", "src/language-html/**/*.js", "src/language-js/**/*.js", - "src/language-markdown/**/*.js", "src/language-yaml/**/*.js", "src/main/**/*.js", "src/utils/**/*.js", diff --git a/scripts/build/bundler.mjs b/scripts/build/bundler.mjs index bdb0abc39..6a3327080 100644 --- a/scripts/build/bundler.mjs +++ b/scripts/build/bundler.mjs @@ -19,6 +19,9 @@ const packageJson = readJsonSync("../../package.json"); const umdTarget = browserslistToEsbuild(packageJson.browserslist); const EMPTY_MODULE_REPLACEMENT = { contents: "" }; +const EXPORT_UNDEFINED_MODULE_REPLACEMENT = { + contents: "export default undefined", +}; function* getEsbuildOptions(bundle, buildOptions) { const replaceStrings = { @@ -94,6 +97,10 @@ function* getEsbuildOptions(bundle, buildOptions) { ]) { replaceModule[path.join(PROJECT_ROOT, file)] = EMPTY_MODULE_REPLACEMENT; } + for (const file of ["src/language-markdown/parsers.js"]) { + replaceModule[path.join(PROJECT_ROOT, file)] = + EXPORT_UNDEFINED_MODULE_REPLACEMENT; + } // Prevent `esbuildPluginNodeModulePolyfills` include shim for this module replaceModule.assert = require.resolve("./shims/assert.cjs"); diff --git a/scripts/build/config.mjs b/scripts/build/config.mjs index eae484fec..c5d735513 100644 --- a/scripts/build/config.mjs +++ b/scripts/build/config.mjs @@ -135,6 +135,7 @@ const parsers = [ "inherits/inherits_browser.js" ), }, + isEsm: true, }, { input: "src/language-handlebars/parser-glimmer.js", diff --git a/scripts/build/esbuild-plugins/evaluate.mjs b/scripts/build/esbuild-plugins/evaluate.mjs index ba76a0159..3f78d00a6 100644 --- a/scripts/build/esbuild-plugins/evaluate.mjs +++ b/scripts/build/esbuild-plugins/evaluate.mjs @@ -1,14 +1,16 @@ import createEsmUtils from "esm-utils"; -const { require } = createEsmUtils(import.meta); +const { importModule } = createEsmUtils(import.meta); export default function esbuildPluginEvaluate() { return { name: "evaluate", setup(build) { - build.onLoad({ filter: /\.evaluate\.js$/ }, ({ path }) => { - const json = JSON.stringify(require(path), (_, v) => { + build.onLoad({ filter: /\.evaluate\.js$/ }, async ({ path }) => { + const data = await importModule(path); + + const json = JSON.stringify(data, (_, v) => { if (typeof v === "function") { throw new TypeError("Cannot evaluate functions."); } diff --git a/scripts/bundle-eslint-config.cjs b/scripts/bundle-eslint-config.cjs index e1f3c4bb8..6729aab20 100644 --- a/scripts/bundle-eslint-config.cjs +++ b/scripts/bundle-eslint-config.cjs @@ -39,20 +39,21 @@ module.exports = { "compat/compat": "error", }, }, - { - files: ["index.js", "bin-prettier.js", "third-party.js"], - rules: { - "no-restricted-syntax": [ - "error", - // Forbid top level `require()` parsers - { - selector: - 'CallExpression:not(:function *)[callee.name="require"][arguments.0.value=/parser-/]', - message: "Parsers should be inline `require()`d.", - }, - ], - }, - }, + // TODO[@fisker]: Find a way to inline `require` parsers + // { + // files: ["index.js", "bin-prettier.js", "third-party.js"], + // rules: { + // "no-restricted-syntax": [ + // "error", + // // Forbid top level `require()` parsers + // { + // selector: + // 'CallExpression:not(:function *)[callee.name="require"][arguments.0.value=/parser-/]', + // message: "Parsers should be inline `require()`d.", + // }, + // ], + // }, + // }, { files: ["doc.js", "parser-*.js", "standalone.js"], rules: { diff --git a/src/language-markdown/clean.js b/src/language-markdown/clean.js index 60c3c7caa..52b718902 100644 --- a/src/language-markdown/clean.js +++ b/src/language-markdown/clean.js @@ -1,7 +1,5 @@ -"use strict"; - -const { isFrontMatterNode } = require("../common/util.js"); -const { startWithPragma } = require("./pragma.js"); +import { isFrontMatterNode } from "../common/util.js"; +import { startWithPragma } from "./pragma.js"; const ignoredProperties = new Set([ "position", @@ -74,4 +72,4 @@ function clean(ast, newObj, parent) { clean.ignoredProperties = ignoredProperties; -module.exports = clean; +export default clean; diff --git a/src/language-markdown/constants.evaluate.js b/src/language-markdown/constants.evaluate.js index 45c799f9e..8f3f14480 100644 --- a/src/language-markdown/constants.evaluate.js +++ b/src/language-markdown/constants.evaluate.js @@ -1,8 +1,6 @@ -"use strict"; - -const cjkRegex = require("cjk-regex"); -const regexpUtil = require("regexp-util"); -const unicodeRegex = require("unicode-regex"); +import cjkRegex from "cjk-regex"; +import regexpUtil from "regexp-util"; +import unicodeRegex from "unicode-regex"; const cjkPattern = `(?:${cjkRegex() .union( @@ -51,8 +49,4 @@ const punctuationCharset = unicodeRegex({ const punctuationPattern = punctuationCharset.toString(); -module.exports = { - cjkPattern, - kPattern, - punctuationPattern, -}; +export { cjkPattern, kPattern, punctuationPattern }; diff --git a/src/language-markdown/embed.js b/src/language-markdown/embed.js index 2f448c52d..7b93fd158 100644 --- a/src/language-markdown/embed.js +++ b/src/language-markdown/embed.js @@ -1,15 +1,15 @@ -"use strict"; - -const { +import { inferParserByLanguage, getMaxContinuousCount, -} = require("../common/util.js"); +} from "../common/util.js"; +import doc from "../document/index.js"; +import printFrontMatter from "../utils/front-matter/print.js"; +import { getFencedCodeBlockValue } from "./utils.js"; + const { builders: { hardline, markAsRoot }, utils: { replaceEndOfLine }, -} = require("../document/index.js"); -const printFrontMatter = require("../utils/front-matter/print.js"); -const { getFencedCodeBlockValue } = require("./utils.js"); +} = doc; function embed(path, print, textToDoc, options) { const node = path.getValue(); @@ -70,4 +70,4 @@ function embed(path, print, textToDoc, options) { return null; } -module.exports = embed; +export default embed; diff --git a/src/language-markdown/index.js b/src/language-markdown/index.js index 7d195073c..f8f38b177 100644 --- a/src/language-markdown/index.js +++ b/src/language-markdown/index.js @@ -1,9 +1,10 @@ -"use strict"; +import { createRequire } from "module"; +import createLanguage from "../utils/create-language.js"; +import printer from "./printer-markdown.js"; +import options from "./options.js"; +import parsers from "./parsers.js"; -const createLanguage = require("../utils/create-language.js"); -const printer = require("./printer-markdown.js"); -const options = require("./options.js"); -const parsers = require("./parsers.js"); +const require = createRequire(import.meta.url); const languages = [ createLanguage(require("linguist-languages/data/Markdown.json"), (data) => ({ @@ -27,9 +28,11 @@ const printers = { mdast: printer, }; -module.exports = { +const language = { languages, options, printers, parsers, }; + +export default language; diff --git a/src/language-markdown/loc.js b/src/language-markdown/loc.js index 097ca3b54..23c2bebd3 100644 --- a/src/language-markdown/loc.js +++ b/src/language-markdown/loc.js @@ -1,5 +1,3 @@ -"use strict"; - function locStart(node) { return node.position.start.offset; } @@ -8,4 +6,4 @@ function locEnd(node) { return node.position.end.offset; } -module.exports = { locStart, locEnd }; +export { locStart, locEnd }; diff --git a/src/language-markdown/mdx.js b/src/language-markdown/mdx.js index 4a39cdaf5..84e7629fc 100644 --- a/src/language-markdown/mdx.js +++ b/src/language-markdown/mdx.js @@ -1,5 +1,3 @@ -"use strict"; - /** * modified from https://github.com/mdx-js/mdx/blob/master/packages/mdx * @@ -75,8 +73,4 @@ function esSyntax() { inlineMethods.splice(inlineMethods.indexOf("text"), 0, "esComment"); } -module.exports = { - esSyntax, - BLOCKS_REGEX, - COMMENT_REGEX, -}; +export { esSyntax, BLOCKS_REGEX, COMMENT_REGEX }; diff --git a/src/language-markdown/options.js b/src/language-markdown/options.js index edb5fd4c4..fc5925d25 100644 --- a/src/language-markdown/options.js +++ b/src/language-markdown/options.js @@ -1,9 +1,9 @@ -"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 = { proseWrap: commonOptions.proseWrap, singleQuote: commonOptions.singleQuote, }; + +export default options; diff --git a/src/language-markdown/package.json b/src/language-markdown/package.json deleted file mode 100644 index 54d221724..000000000 --- a/src/language-markdown/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-markdown/parser-markdown.js b/src/language-markdown/parser-markdown.js index f5f1348a7..7e75d5c65 100644 --- a/src/language-markdown/parser-markdown.js +++ b/src/language-markdown/parser-markdown.js @@ -1,17 +1,15 @@ -"use strict"; - -const remarkParse = require("remark-parse"); -const unified = require("unified"); -const remarkMath = require("remark-math"); -const footnotes = require("remark-footnotes"); -const pragma = require("./pragma.js"); -const { locStart, locEnd } = require("./loc.js"); -const mdx = require("./mdx.js"); -const htmlToJsx = require("./unified-plugins/html-to-jsx.js"); -const frontMatter = require("./unified-plugins/front-matter.js"); -const liquid = require("./unified-plugins/liquid.js"); -const wikiLink = require("./unified-plugins/wiki-link.js"); -const looseItems = require("./unified-plugins/loose-items.js"); +import remarkParse from "remark-parse"; +import unified from "unified"; +import remarkMath from "remark-math"; +import footnotes from "remark-footnotes"; +import { hasPragma } from "./pragma.js"; +import { locStart, locEnd } from "./loc.js"; +import { BLOCKS_REGEX, esSyntax } from "./mdx.js"; +import htmlToJsx from "./unified-plugins/html-to-jsx.js"; +import frontMatter from "./unified-plugins/front-matter.js"; +import liquid from "./unified-plugins/liquid.js"; +import wikiLink from "./unified-plugins/wiki-link.js"; +import looseItems from "./unified-plugins/loose-items.js"; /** * based on [MDAST](https://github.com/syntax-tree/mdast) with following modifications: @@ -32,12 +30,12 @@ function createParse({ isMDX }) { const processor = unified() .use(remarkParse, { commonmark: true, - ...(isMDX && { blocks: [mdx.BLOCKS_REGEX] }), + ...(isMDX && { blocks: [BLOCKS_REGEX] }), }) .use(footnotes) .use(frontMatter) .use(remarkMath) - .use(isMDX ? mdx.esSyntax : identity) + .use(isMDX ? esSyntax : identity) .use(liquid) .use(isMDX ? htmlToJsx : identity) .use(wikiLink) @@ -52,7 +50,7 @@ function identity(x) { const baseParser = { astFormat: "mdast", - hasPragma: pragma.hasPragma, + hasPragma, locStart, locEnd, }; @@ -61,10 +59,12 @@ const markdownParser = { ...baseParser, parse: createParse({ isMDX: false }) }; const mdxParser = { ...baseParser, parse: createParse({ isMDX: true }) }; -module.exports = { +const markdown = { parsers: { remark: markdownParser, markdown: markdownParser, mdx: mdxParser, }, }; + +export default markdown; diff --git a/src/language-markdown/parsers.js b/src/language-markdown/parsers.js index 333e56cd6..27546c0e2 100644 --- a/src/language-markdown/parsers.js +++ b/src/language-markdown/parsers.js @@ -1,14 +1,16 @@ -"use strict"; +import markdownParser from "./parser-markdown.js"; -module.exports = { +const parsers = { /* istanbul ignore next */ get remark() { - return require("./parser-markdown.js").parsers.remark; + return markdownParser.parsers.remark; }, get markdown() { - return require("./parser-markdown.js").parsers.remark; + return markdownParser.parsers.remark; }, get mdx() { - return require("./parser-markdown.js").parsers.mdx; + return markdownParser.parsers.mdx; }, }; + +export default parsers; diff --git a/src/language-markdown/pragma.js b/src/language-markdown/pragma.js index 463751b8d..e985e2a8c 100644 --- a/src/language-markdown/pragma.js +++ b/src/language-markdown/pragma.js @@ -1,6 +1,4 @@ -"use strict"; - -const parseFrontMatter = require("../utils/front-matter/parse.js"); +import parseFrontMatter from "../utils/front-matter/parse.js"; const pragmas = ["format", "prettier"]; @@ -18,15 +16,15 @@ function startWithPragma(text) { return matched && matched.index === 0; } -module.exports = { - startWithPragma, - hasPragma: (text) => - startWithPragma(parseFrontMatter(text).content.trimStart()), - insertPragma: (text) => { - const extracted = parseFrontMatter(text); - const pragma = ``; - return extracted.frontMatter - ? `${extracted.frontMatter.raw}\n\n${pragma}\n\n${extracted.content}` - : `${pragma}\n\n${extracted.content}`; - }, +const hasPragma = (text) => + startWithPragma(parseFrontMatter(text).content.trimStart()); + +const insertPragma = (text) => { + const extracted = parseFrontMatter(text); + const pragma = ``; + return extracted.frontMatter + ? `${extracted.frontMatter.raw}\n\n${pragma}\n\n${extracted.content}` + : `${pragma}\n\n${extracted.content}`; }; + +export { startWithPragma, hasPragma, insertPragma }; diff --git a/src/language-markdown/print-preprocess.js b/src/language-markdown/print-preprocess.js index fa1b04335..cfd903fe9 100644 --- a/src/language-markdown/print-preprocess.js +++ b/src/language-markdown/print-preprocess.js @@ -1,7 +1,5 @@ -"use strict"; - -const getLast = require("../utils/get-last.js"); -const { getOrderedListItemInfo, mapAst, splitText } = require("./utils.js"); +import getLast from "../utils/get-last.js"; +import { getOrderedListItemInfo, mapAst, splitText } from "./utils.js"; // 0x0 ~ 0x10ffff const isSingleCharRegex = /^.$/su; @@ -271,4 +269,4 @@ function markAlignedList(ast, options) { } } -module.exports = preprocess; +export default preprocess; diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index 1cd5f82ca..3d4d92232 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -1,12 +1,26 @@ -"use strict"; - -const { +import { getLast, getMinNotPresentContinuousCount, getMaxContinuousCount, getStringWidth, isNonEmptyArray, -} = require("../common/util.js"); +} from "../common/util.js"; +import doc from "../document/index.js"; +import embed from "./embed.js"; +import { insertPragma } from "./pragma.js"; +import { locStart, locEnd } from "./loc.js"; +import preprocess from "./print-preprocess.js"; +import clean from "./clean.js"; +import { + getFencedCodeBlockValue, + hasGitDiffFriendlyOrderedList, + splitText, + punctuationPattern, + INLINE_NODE_TYPES, + INLINE_NODE_WRAPPER_TYPES, + isAutolink, +} from "./utils.js"; + const { builders: { breakParent, @@ -25,21 +39,7 @@ const { }, utils: { normalizeDoc, replaceTextEndOfLine }, printer: { printDocToString }, -} = require("../document/index.js"); -const embed = require("./embed.js"); -const { insertPragma } = require("./pragma.js"); -const { locStart, locEnd } = require("./loc.js"); -const preprocess = require("./print-preprocess.js"); -const clean = require("./clean.js"); -const { - getFencedCodeBlockValue, - hasGitDiffFriendlyOrderedList, - splitText, - punctuationPattern, - INLINE_NODE_TYPES, - INLINE_NODE_WRAPPER_TYPES, - isAutolink, -} = require("./utils.js"); +} = doc; /** * @typedef {import("../document").Doc} Doc @@ -915,7 +915,7 @@ function hasPrettierIgnore(path) { return isPrettierIgnore(prevNode) === "next"; } -module.exports = { +const printer = { preprocess, print: genericPrint, embed, @@ -923,3 +923,5 @@ module.exports = { hasPrettierIgnore, insertPragma, }; + +export default printer; diff --git a/src/language-markdown/unified-plugins/front-matter.js b/src/language-markdown/unified-plugins/front-matter.js index b941178c8..402d1b50f 100644 --- a/src/language-markdown/unified-plugins/front-matter.js +++ b/src/language-markdown/unified-plugins/front-matter.js @@ -1,6 +1,4 @@ -"use strict"; - -const parseFrontMatter = require("../../utils/front-matter/parse.js"); +import parseFrontMatter from "../../utils/front-matter/parse.js"; function frontMatter() { const proto = this.Parser.prototype; @@ -17,4 +15,4 @@ function frontMatter() { tokenizer.onlyAtStart = true; } -module.exports = frontMatter; +export default frontMatter; diff --git a/src/language-markdown/unified-plugins/html-to-jsx.js b/src/language-markdown/unified-plugins/html-to-jsx.js index c61beb759..0b952d28a 100644 --- a/src/language-markdown/unified-plugins/html-to-jsx.js +++ b/src/language-markdown/unified-plugins/html-to-jsx.js @@ -1,7 +1,5 @@ -"use strict"; - -const mdx = require("../mdx.js"); -const { mapAst, INLINE_NODE_WRAPPER_TYPES } = require("../utils.js"); +import { COMMENT_REGEX } from "../mdx.js"; +import { mapAst, INLINE_NODE_WRAPPER_TYPES } from "../utils.js"; function htmlToJsx() { return (ast) => @@ -9,7 +7,7 @@ function htmlToJsx() { if ( node.type !== "html" || // Keep HTML-style comments (legacy MDX) - mdx.COMMENT_REGEX.test(node.value) || + COMMENT_REGEX.test(node.value) || INLINE_NODE_WRAPPER_TYPES.includes(parent.type) ) { return node; @@ -18,4 +16,4 @@ function htmlToJsx() { }); } -module.exports = htmlToJsx; +export default htmlToJsx; diff --git a/src/language-markdown/unified-plugins/liquid.js b/src/language-markdown/unified-plugins/liquid.js index 0be6b7641..3d5889c81 100644 --- a/src/language-markdown/unified-plugins/liquid.js +++ b/src/language-markdown/unified-plugins/liquid.js @@ -1,5 +1,3 @@ -"use strict"; - function liquid() { const proto = this.Parser.prototype; const methods = proto.inlineMethods; @@ -21,4 +19,4 @@ function liquid() { }; } -module.exports = liquid; +export default liquid; diff --git a/src/language-markdown/unified-plugins/loose-items.js b/src/language-markdown/unified-plugins/loose-items.js index 12e1fa144..c718a2462 100644 --- a/src/language-markdown/unified-plugins/loose-items.js +++ b/src/language-markdown/unified-plugins/loose-items.js @@ -1,5 +1,3 @@ -"use strict"; - function looseItems() { const proto = this.Parser.prototype; const originalList = proto.blockTokenizers.list; @@ -32,4 +30,4 @@ function looseItems() { }; } -module.exports = looseItems; +export default looseItems; diff --git a/src/language-markdown/unified-plugins/wiki-link.js b/src/language-markdown/unified-plugins/wiki-link.js index 53b6e263f..ef88f5855 100644 --- a/src/language-markdown/unified-plugins/wiki-link.js +++ b/src/language-markdown/unified-plugins/wiki-link.js @@ -1,5 +1,3 @@ -"use strict"; - function wikiLink() { const entityType = "wikiLink"; const wikiLinkRegex = /^\[\[(?.+?)]]/s; @@ -26,4 +24,4 @@ function wikiLink() { }; } -module.exports = wikiLink; +export default wikiLink; diff --git a/src/language-markdown/utils.js b/src/language-markdown/utils.js index 1cc85e2bf..f907a4079 100644 --- a/src/language-markdown/utils.js +++ b/src/language-markdown/utils.js @@ -1,12 +1,10 @@ -"use strict"; - -const { getLast } = require("../common/util.js"); -const { locStart, locEnd } = require("./loc.js"); -const { +import { getLast } from "../common/util.js"; +import { locStart, locEnd } from "./loc.js"; +import { cjkPattern, kPattern, punctuationPattern, -} = require("./constants.evaluate.js"); +} from "./constants.evaluate.js"; const INLINE_NODE_TYPES = [ "liquidNode", @@ -232,7 +230,7 @@ function isAutolink(node) { ); } -module.exports = { +export { mapAst, splitText, punctuationPattern, diff --git a/src/languages.js b/src/languages.js index 289756b09..a94e969c5 100644 --- a/src/languages.js +++ b/src/languages.js @@ -1,5 +1,7 @@ import { createRequire } from "module"; +import markdown from "./language-markdown/index.js"; + const require = createRequire(import.meta.url); // We need to list the parsers and getters so we can load them only when necessary. @@ -13,7 +15,7 @@ const languages = [ // GraphQL require("./language-graphql/index.js"), // Markdown - require("./language-markdown/index.js"), + markdown, // HTML require("./language-html/index.js"), // YAML