2026-05-28 01:45:35 +08:00
|
|
|
import { createRequire } from "node:module";
|
2023-12-17 19:34:12 +00:00
|
|
|
import path from "node:path";
|
2024-06-14 16:34:05 +08:00
|
|
|
import url from "node:url";
|
2023-12-17 19:34:12 +00:00
|
|
|
import browserslistToEsbuild from "browserslist-to-esbuild";
|
2022-01-09 01:15:04 +08:00
|
|
|
import esbuild from "esbuild";
|
2025-12-05 04:53:15 +08:00
|
|
|
import projectPackageJson from "../../../package.json" with { type: "json" };
|
2026-02-01 08:57:18 +08:00
|
|
|
import {
|
|
|
|
|
PRODUCTION_MINIMAL_NODE_JS_VERSION,
|
|
|
|
|
PROJECT_ROOT,
|
|
|
|
|
} from "../../utilities/index.js";
|
2025-12-05 04:53:15 +08:00
|
|
|
import esbuildPluginAddDefaultExport from "../esbuild-plugins/add-default-export.js";
|
|
|
|
|
import esbuildPluginEvaluate from "../esbuild-plugins/evaluate.js";
|
|
|
|
|
import esbuildPluginPrimitiveDefine from "../esbuild-plugins/primitive-define.js";
|
|
|
|
|
import esbuildPluginReplaceModule from "../esbuild-plugins/replace-module.js";
|
|
|
|
|
import esbuildPluginShimCommonjsObjects from "../esbuild-plugins/shim-commonjs-objects.js";
|
|
|
|
|
import esbuildPluginStripNodeProtocol from "../esbuild-plugins/strip-node-protocol.js";
|
|
|
|
|
import esbuildPluginThrowWarnings from "../esbuild-plugins/throw-warnings.js";
|
|
|
|
|
import esbuildPluginUmd from "../esbuild-plugins/umd.js";
|
|
|
|
|
import esbuildPluginVisualizer from "../esbuild-plugins/visualizer.js";
|
|
|
|
|
import transform from "../transform/index.js";
|
|
|
|
|
import { getPackageFile } from "../utilities.js";
|
2018-05-29 14:59:57 -03:00
|
|
|
|
2026-05-28 01:45:35 +08:00
|
|
|
const require = createRequire(import.meta.url);
|
2020-05-11 09:05:06 +08:00
|
|
|
|
2025-12-05 04:53:15 +08:00
|
|
|
const universalTarget = browserslistToEsbuild(projectPackageJson.browserslist);
|
2022-10-06 15:20:19 +08:00
|
|
|
const getRelativePath = (from, to) => {
|
|
|
|
|
const relativePath = path.posix.relative(path.dirname(`/${from}`), `/${to}`);
|
|
|
|
|
if (!relativePath.startsWith(".")) {
|
|
|
|
|
return `./${relativePath}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return relativePath;
|
|
|
|
|
};
|
2020-10-22 13:32:50 +08:00
|
|
|
|
2025-12-05 04:53:15 +08:00
|
|
|
function getEsbuildOptions({ packageConfig, file, cliOptions, buildOptions }) {
|
|
|
|
|
const { sourceDirectory, distDirectory } = packageConfig;
|
2025-04-09 08:38:46 +08:00
|
|
|
|
2022-09-25 11:50:59 +08:00
|
|
|
// Save dependencies to file
|
|
|
|
|
file.dependencies = [];
|
2022-03-13 17:04:22 +08:00
|
|
|
|
2022-03-20 14:04:30 +08:00
|
|
|
const replaceModule = [
|
2024-06-14 16:34:05 +08:00
|
|
|
/*
|
|
|
|
|
`jest-docblock` try to detect new line in code, and it will fallback to `os.EOL`,
|
|
|
|
|
We already replaced line end to `\n` before calling it
|
|
|
|
|
*/
|
|
|
|
|
{
|
2026-05-28 01:45:35 +08:00
|
|
|
module: url.fileURLToPath(import.meta.resolve("jest-docblock")),
|
2024-06-14 16:34:05 +08:00
|
|
|
path: require.resolve("jest-docblock"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
module: require.resolve("jest-docblock"),
|
|
|
|
|
process(text) {
|
2026-06-16 03:11:33 +08:00
|
|
|
const exports = text
|
|
|
|
|
.matchAll(/(?<=\n)exports\.(?<specifier>\w+) = \k<specifier>;/g)
|
|
|
|
|
.map((match) => match.groups.specifier)
|
|
|
|
|
.toArray();
|
2024-06-14 16:34:05 +08:00
|
|
|
|
|
|
|
|
const lines = text.split("\n");
|
|
|
|
|
const startMarkLine = lines.findIndex((line) =>
|
|
|
|
|
line.includes("function _interopRequireDefault"),
|
|
|
|
|
);
|
|
|
|
|
const endMarkLine = lines.indexOf(
|
|
|
|
|
"module.exports = __webpack_exports__;",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
lines[startMarkLine + 1] !== "/**" ||
|
|
|
|
|
lines[endMarkLine - 2] !== "})();"
|
|
|
|
|
) {
|
|
|
|
|
throw new Error("Unexpected source");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
text = lines.slice(startMarkLine + 1, endMarkLine - 2).join("\n");
|
|
|
|
|
|
2026-05-08 14:42:47 +08:00
|
|
|
text = text.replace(
|
|
|
|
|
"const line = (0, _detectNewline().default)(docblock) ?? _nodeOs().EOL;",
|
|
|
|
|
String.raw`const line = "\n"`,
|
|
|
|
|
);
|
|
|
|
|
text = text.replace(
|
|
|
|
|
"const line = (0, _detectNewline().default)(comments) ?? _nodeOs().EOL;",
|
|
|
|
|
String.raw`const line = "\n"`,
|
|
|
|
|
);
|
2024-06-14 16:34:05 +08:00
|
|
|
|
|
|
|
|
text += "\n\n" + `export {${exports.join(", ")}};`;
|
|
|
|
|
|
|
|
|
|
return text;
|
|
|
|
|
},
|
|
|
|
|
},
|
2023-08-15 09:20:40 +08:00
|
|
|
// Transform `.at`, `Object.hasOwn`, and `String#replaceAll`
|
2022-09-18 17:50:14 +08:00
|
|
|
{
|
|
|
|
|
module: "*",
|
2025-11-03 04:54:10 +08:00
|
|
|
process: (text, file) => transform(text, file, buildOptions),
|
2022-09-18 17:50:14 +08:00
|
|
|
},
|
2026-06-16 02:09:45 +08:00
|
|
|
// #12493, not sure what the problem is, but replace the CJS version with ESM version seems fix it
|
2024-06-05 11:32:07 +08:00
|
|
|
{
|
|
|
|
|
module: require.resolve("tslib"),
|
2025-12-21 23:44:08 +08:00
|
|
|
path: require.resolve("tslib").replace(/tslib\.js$/, "tslib.es6.js"),
|
2024-06-05 11:32:07 +08:00
|
|
|
},
|
2022-05-06 18:52:40 +08:00
|
|
|
// https://github.com/evanw/esbuild/issues/2103
|
|
|
|
|
{
|
2023-03-01 15:34:30 +08:00
|
|
|
module: getPackageFile("outdent/lib-module/index.js"),
|
2022-05-06 18:52:40 +08:00
|
|
|
process(text) {
|
|
|
|
|
const index = text.indexOf('if (typeof module !== "undefined") {');
|
|
|
|
|
if (index === -1) {
|
|
|
|
|
throw new Error("Unexpected code");
|
|
|
|
|
}
|
|
|
|
|
return text.slice(0, index);
|
|
|
|
|
},
|
|
|
|
|
},
|
2022-03-14 20:02:02 +08:00
|
|
|
];
|
2022-01-26 19:08:55 +08:00
|
|
|
|
|
|
|
|
const define = {
|
2025-12-05 04:53:15 +08:00
|
|
|
"process.env.PRETTIER_TARGET": buildOptions.platform,
|
2022-10-27 09:29:22 +08:00
|
|
|
"process.env.NODE_ENV": "production",
|
2022-01-26 19:08:55 +08:00
|
|
|
};
|
|
|
|
|
|
2025-12-05 04:53:15 +08:00
|
|
|
if (buildOptions.platform === "universal") {
|
2018-05-29 14:59:57 -03:00
|
|
|
// We can't reference `process` in UMD bundles and this is
|
|
|
|
|
// an undocumented "feature"
|
2022-03-20 14:04:30 +08:00
|
|
|
replaceModule.push({
|
|
|
|
|
module: "*",
|
2022-03-14 20:02:02 +08:00
|
|
|
find: "process.env.PRETTIER_DEBUG",
|
|
|
|
|
replacement: "globalThis.PRETTIER_DEBUG",
|
|
|
|
|
});
|
2022-01-26 19:08:55 +08:00
|
|
|
|
2022-10-27 09:29:22 +08:00
|
|
|
define.process = undefined;
|
|
|
|
|
// @babel/code-frame/lib/index.js
|
|
|
|
|
define["process.emitWarning"] = undefined;
|
|
|
|
|
// postcss/lib/postcss.js
|
|
|
|
|
define["process.env.LANG"] = "";
|
2023-07-29 15:32:17 +09:00
|
|
|
// @typescript-eslint/typescript-estree
|
|
|
|
|
define["process.env.TYPESCRIPT_ESLINT_EXPERIMENTAL_TSSERVER"] = "";
|
2022-01-26 19:08:55 +08:00
|
|
|
|
|
|
|
|
// Replace `__dirname` and `__filename` with a fake value
|
|
|
|
|
// So `parser-typescript.js` won't contain a path of working directory
|
2020-05-11 09:23:13 +08:00
|
|
|
// See #8268
|
2022-10-27 09:29:22 +08:00
|
|
|
define.__filename = "/prettier-security-filename-placeholder.js";
|
|
|
|
|
define.__dirname = "/prettier-security-dirname-placeholder";
|
2018-05-29 14:59:57 -03:00
|
|
|
}
|
2020-05-11 09:05:06 +08:00
|
|
|
|
2025-12-05 04:53:15 +08:00
|
|
|
// External other bundled files
|
|
|
|
|
if (buildOptions.platform === "node") {
|
|
|
|
|
const files = packageConfig.modules
|
|
|
|
|
.flatMap((module) => module.files)
|
|
|
|
|
.filter(
|
|
|
|
|
(bundle) =>
|
|
|
|
|
bundle.input === "package.json" ||
|
|
|
|
|
(file.input &&
|
|
|
|
|
file.input !== bundle.input &&
|
|
|
|
|
bundle.output.endsWith(".mjs")),
|
|
|
|
|
);
|
|
|
|
|
const replacements = files.map((bundle) => {
|
|
|
|
|
let { output } = bundle;
|
|
|
|
|
if (file.output === "index.cjs" && output === "doc.mjs") {
|
|
|
|
|
output = "doc.js";
|
|
|
|
|
}
|
2022-08-11 14:08:08 +08:00
|
|
|
|
2025-12-05 04:53:15 +08:00
|
|
|
return {
|
|
|
|
|
module: path.join(sourceDirectory, bundle.input),
|
|
|
|
|
external: getRelativePath(file.output, output),
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
replaceModule.push(...replacements);
|
2021-07-13 15:16:31 +08:00
|
|
|
}
|
2021-07-12 14:33:52 +08:00
|
|
|
|
2025-05-06 08:18:50 +08:00
|
|
|
// Current version of `yaml` is not tree-shakable,
|
|
|
|
|
// but when we update it, we may reduce size,
|
|
|
|
|
// since the UMD version don't need expose `__parsePrettierYamlConfig`
|
2025-12-05 04:53:15 +08:00
|
|
|
if (buildOptions.format === "umd" && file.output === "plugins/yaml.js") {
|
2025-05-06 08:18:50 +08:00
|
|
|
replaceModule.push({
|
2025-12-05 04:53:15 +08:00
|
|
|
module: path.join(sourceDirectory, file.input),
|
2025-05-06 08:18:50 +08:00
|
|
|
text: 'export * from "../language-yaml/index.js";',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-25 11:50:59 +08:00
|
|
|
const shouldMinify =
|
2025-12-05 04:53:15 +08:00
|
|
|
cliOptions.minify ??
|
|
|
|
|
buildOptions.minify ??
|
|
|
|
|
buildOptions.platform === "universal";
|
2022-03-14 16:30:12 +08:00
|
|
|
|
2022-01-09 01:15:04 +08:00
|
|
|
const esbuildOptions = {
|
2025-12-05 04:53:15 +08:00
|
|
|
entryPoints: [path.join(sourceDirectory, file.input)],
|
2022-01-09 01:15:04 +08:00
|
|
|
bundle: true,
|
|
|
|
|
metafile: true,
|
|
|
|
|
plugins: [
|
2025-05-29 15:30:45 +08:00
|
|
|
esbuildPluginPrimitiveDefine({ ...define, ...buildOptions.define }),
|
2022-01-09 01:15:04 +08:00
|
|
|
esbuildPluginEvaluate(),
|
2022-03-02 13:44:00 +08:00
|
|
|
esbuildPluginStripNodeProtocol(),
|
2022-03-20 14:04:30 +08:00
|
|
|
esbuildPluginReplaceModule({
|
2025-11-21 23:39:09 +08:00
|
|
|
replacements: [...(buildOptions.replaceModule ?? []), ...replaceModule],
|
2022-01-09 01:15:04 +08:00
|
|
|
}),
|
2022-09-25 11:50:59 +08:00
|
|
|
cliOptions.reports &&
|
|
|
|
|
esbuildPluginVisualizer({ formats: cliOptions.reports }),
|
2022-06-01 19:23:13 +08:00
|
|
|
esbuildPluginThrowWarnings({
|
2025-12-05 04:53:15 +08:00
|
|
|
allowDynamicRequire: buildOptions.platform === "node",
|
|
|
|
|
allowDynamicImport: buildOptions.platform === "node",
|
2025-11-25 02:13:03 +08:00
|
|
|
allowedWarnings: buildOptions.allowedWarnings,
|
2022-06-01 19:23:13 +08:00
|
|
|
}),
|
2023-04-25 15:37:56 +08:00
|
|
|
buildOptions.addDefaultExport && esbuildPluginAddDefaultExport(),
|
2022-01-09 01:15:04 +08:00
|
|
|
].filter(Boolean),
|
|
|
|
|
minify: shouldMinify,
|
|
|
|
|
legalComments: "none",
|
2022-09-25 11:50:59 +08:00
|
|
|
external: ["pnpapi", ...(buildOptions.external ?? [])],
|
2022-01-09 01:15:04 +08:00
|
|
|
// Disable esbuild auto discover `tsconfig.json` file
|
2023-06-18 11:05:12 +08:00
|
|
|
tsconfigRaw: JSON.stringify({}),
|
2025-05-27 09:35:31 +08:00
|
|
|
target: [
|
|
|
|
|
...(buildOptions.target ?? [`node${PRODUCTION_MINIMAL_NODE_JS_VERSION}`]),
|
|
|
|
|
],
|
2022-01-14 15:58:13 +08:00
|
|
|
logLevel: "error",
|
2025-12-05 04:53:15 +08:00
|
|
|
format: buildOptions.format,
|
|
|
|
|
outfile: path.join(distDirectory, cliOptions.saveAs ?? file.output),
|
2022-10-20 08:26:35 +08:00
|
|
|
// https://esbuild.github.io/api/#main-fields
|
2025-12-05 04:53:15 +08:00
|
|
|
mainFields:
|
|
|
|
|
buildOptions.platform === "node" ? ["module", "main"] : undefined,
|
2024-06-14 23:21:29 +08:00
|
|
|
supported: {
|
2025-11-25 02:13:03 +08:00
|
|
|
...buildOptions.supported,
|
2024-06-14 23:21:29 +08:00
|
|
|
// https://github.com/evanw/esbuild/issues/3471
|
|
|
|
|
"regexp-unicode-property-escapes": true,
|
2025-09-12 01:35:29 +08:00
|
|
|
// Maybe because Node.js v14 doesn't support "spread parameters after optional chaining" https://node.green/
|
|
|
|
|
"optional-chain": true,
|
2025-10-27 20:23:01 +08:00
|
|
|
// Maybe because https://github.com/evanw/esbuild/pull/3167?
|
|
|
|
|
"class-field": true,
|
|
|
|
|
"class-private-field": true,
|
|
|
|
|
"class-private-method": true,
|
2024-06-14 23:21:29 +08:00
|
|
|
},
|
2024-07-02 10:24:59 +08:00
|
|
|
packages: "bundle",
|
2026-02-01 08:57:18 +08:00
|
|
|
absWorkingDir: PROJECT_ROOT,
|
2022-01-09 01:15:04 +08:00
|
|
|
};
|
2021-09-12 23:26:29 +08:00
|
|
|
|
2025-12-05 04:53:15 +08:00
|
|
|
if (buildOptions.platform === "universal") {
|
2022-09-25 11:50:59 +08:00
|
|
|
if (!buildOptions.target) {
|
|
|
|
|
esbuildOptions.target.push(...universalTarget);
|
2022-03-13 22:47:02 +08:00
|
|
|
}
|
2022-01-09 01:15:04 +08:00
|
|
|
|
2025-12-05 04:53:15 +08:00
|
|
|
if (buildOptions.format === "umd") {
|
2022-09-25 11:50:59 +08:00
|
|
|
esbuildOptions.plugins.push(
|
2022-02-17 09:47:35 +08:00
|
|
|
esbuildPluginUmd({
|
2025-12-05 04:53:15 +08:00
|
|
|
name: buildOptions.umdVariableName,
|
2022-09-25 11:50:59 +08:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-01-09 01:15:04 +08:00
|
|
|
} else {
|
2022-02-28 18:38:33 +08:00
|
|
|
esbuildOptions.platform = "node";
|
2020-10-26 09:44:09 +08:00
|
|
|
|
2022-08-11 14:08:08 +08:00
|
|
|
// https://github.com/evanw/esbuild/issues/1921
|
2025-12-05 04:53:15 +08:00
|
|
|
if (buildOptions.format === "esm") {
|
2022-08-11 14:08:08 +08:00
|
|
|
esbuildOptions.plugins.push(esbuildPluginShimCommonjsObjects());
|
|
|
|
|
}
|
2020-10-26 09:44:09 +08:00
|
|
|
}
|
2022-09-25 11:50:59 +08:00
|
|
|
|
|
|
|
|
return esbuildOptions;
|
2018-05-29 14:59:57 -03:00
|
|
|
}
|
|
|
|
|
|
2025-12-05 04:53:15 +08:00
|
|
|
function createJavascriptModuleBuilder(buildOptions) {
|
|
|
|
|
return async function runEsbuild({ packageConfig, file, cliOptions }) {
|
|
|
|
|
if (typeof buildOptions === "function") {
|
|
|
|
|
buildOptions = await buildOptions();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const esbuildOptions = getEsbuildOptions({
|
|
|
|
|
packageConfig,
|
|
|
|
|
file,
|
|
|
|
|
cliOptions,
|
|
|
|
|
buildOptions,
|
|
|
|
|
});
|
|
|
|
|
return { esbuildResult: await esbuild.build(esbuildOptions) };
|
|
|
|
|
};
|
2018-05-29 14:59:57 -03:00
|
|
|
}
|
|
|
|
|
|
2025-12-05 04:53:15 +08:00
|
|
|
export { createJavascriptModuleBuilder };
|