2022-01-14 15:58:13 +08:00
|
|
|
import fs from "node:fs/promises";
|
2021-05-15 20:09:52 +08:00
|
|
|
import path from "node:path";
|
|
|
|
|
import createEsmUtils from "esm-utils";
|
2022-01-14 15:58:13 +08:00
|
|
|
import * as babel from "@babel/core";
|
|
|
|
|
import esbuild from "esbuild";
|
|
|
|
|
import { NodeModulesPolyfillPlugin as esbuildPluginNodeModulePolyfills } from "@esbuild-plugins/node-modules-polyfill";
|
|
|
|
|
import esbuildPluginTextReplace from "esbuild-plugin-text-replace";
|
2022-01-26 17:55:45 +08:00
|
|
|
import browserslistToEsbuild from "browserslist-to-esbuild";
|
2021-09-11 09:55:46 +08:00
|
|
|
import { PROJECT_ROOT, DIST_DIR } from "../utils/index.mjs";
|
2022-01-14 15:58:13 +08:00
|
|
|
import esbuildPluginEvaluate from "./esbuild-plugins/evaluate.mjs";
|
|
|
|
|
import esbuildPluginReplaceModule from "./esbuild-plugins/replace-module.mjs";
|
|
|
|
|
import esbuildPluginLicense from "./esbuild-plugins/license.mjs";
|
|
|
|
|
import esbuildPluginUmd from "./esbuild-plugins/umd.mjs";
|
2022-01-27 11:16:50 +08:00
|
|
|
import esbuildPluginVisualizer from "./esbuild-plugins/visualizer.mjs";
|
2021-05-27 08:54:42 +08:00
|
|
|
import bundles from "./config.mjs";
|
2018-05-29 14:59:57 -03:00
|
|
|
|
2022-02-11 18:02:04 +08:00
|
|
|
const { __dirname, readJsonSync, require } = createEsmUtils(import.meta);
|
|
|
|
|
const packageJson = readJsonSync("../../package.json");
|
2020-05-11 09:05:06 +08:00
|
|
|
|
2022-01-26 17:55:45 +08:00
|
|
|
const umdTarget = browserslistToEsbuild(packageJson.browserslist);
|
2022-02-05 22:51:17 +08:00
|
|
|
const EMPTY_MODULE_REPLACEMENT = { contents: "" };
|
2020-10-22 13:32:50 +08:00
|
|
|
|
2018-05-29 14:59:57 -03:00
|
|
|
function getBabelConfig(bundle) {
|
|
|
|
|
const config = {
|
|
|
|
|
babelrc: false,
|
2021-05-12 08:11:43 +08:00
|
|
|
assumptions: {
|
|
|
|
|
setSpreadProperties: true,
|
|
|
|
|
},
|
2021-05-12 01:05:29 +08:00
|
|
|
sourceType: "unambiguous",
|
2018-06-21 10:29:42 +08:00
|
|
|
plugins: bundle.babelPlugins || [],
|
2022-01-14 15:58:13 +08:00
|
|
|
compact: false,
|
2021-05-12 01:05:29 +08:00
|
|
|
exclude: [/\/core-js\//],
|
2018-05-29 14:59:57 -03:00
|
|
|
};
|
2019-11-14 01:08:40 +08:00
|
|
|
const targets = { node: "10" };
|
2018-05-29 14:59:57 -03:00
|
|
|
if (bundle.target === "universal") {
|
2021-08-16 15:08:19 +08:00
|
|
|
targets.browsers = packageJson.browserslist;
|
2018-05-29 14:59:57 -03:00
|
|
|
}
|
|
|
|
|
config.presets = [
|
2020-01-10 09:21:44 +08:00
|
|
|
[
|
2021-05-12 08:11:43 +08:00
|
|
|
"@babel/preset-env",
|
2020-01-10 09:21:44 +08:00
|
|
|
{
|
|
|
|
|
targets,
|
2021-05-12 01:05:29 +08:00
|
|
|
exclude: [
|
2022-01-14 15:58:13 +08:00
|
|
|
"es.array.unscopables.flat",
|
2021-05-12 01:05:29 +08:00
|
|
|
"es.array.unscopables.flat-map",
|
2022-01-14 15:58:13 +08:00
|
|
|
"es.array.sort",
|
2021-05-12 01:05:29 +08:00
|
|
|
"es.promise",
|
|
|
|
|
"es.promise.finally",
|
|
|
|
|
"es.string.replace",
|
|
|
|
|
"es.symbol.description",
|
|
|
|
|
"es.typed-array.*",
|
|
|
|
|
"web.*",
|
|
|
|
|
],
|
2020-01-10 09:21:44 +08:00
|
|
|
modules: false,
|
2021-05-12 01:05:29 +08:00
|
|
|
useBuiltIns: "usage",
|
|
|
|
|
corejs: {
|
|
|
|
|
version: 3,
|
|
|
|
|
},
|
|
|
|
|
debug: false,
|
2020-01-10 09:21:44 +08:00
|
|
|
},
|
|
|
|
|
],
|
2018-05-29 14:59:57 -03:00
|
|
|
];
|
2021-05-12 08:11:43 +08:00
|
|
|
config.plugins.push([
|
|
|
|
|
"@babel/plugin-proposal-object-rest-spread",
|
|
|
|
|
{ useBuiltIns: true },
|
|
|
|
|
]);
|
2018-05-29 14:59:57 -03:00
|
|
|
return config;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-05 22:51:17 +08:00
|
|
|
function* getEsbuildOptions(bundle, buildOptions) {
|
2018-05-29 14:59:57 -03:00
|
|
|
const replaceStrings = {
|
2022-01-14 15:58:13 +08:00
|
|
|
// `tslib` exports global variables
|
|
|
|
|
"createExporter(root": "createExporter({}",
|
2018-05-29 14:59:57 -03:00
|
|
|
};
|
2022-01-26 19:08:55 +08:00
|
|
|
|
|
|
|
|
const define = {
|
|
|
|
|
"process.env.PRETTIER_TARGET": JSON.stringify(bundle.target),
|
|
|
|
|
"process.env.NODE_ENV": JSON.stringify("production"),
|
|
|
|
|
};
|
|
|
|
|
|
2018-05-29 14:59:57 -03:00
|
|
|
if (bundle.target === "universal") {
|
|
|
|
|
// We can't reference `process` in UMD bundles and this is
|
|
|
|
|
// an undocumented "feature"
|
2022-01-26 19:08:55 +08:00
|
|
|
replaceStrings["process.env.PRETTIER_DEBUG"] = "globalThis.PRETTIER_DEBUG";
|
|
|
|
|
|
|
|
|
|
define.process = JSON.stringify({ env: {}, argv: [] });
|
|
|
|
|
|
|
|
|
|
// 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-01-26 19:08:55 +08:00
|
|
|
define.__filename = JSON.stringify(
|
2020-05-11 09:23:13 +08:00
|
|
|
"/prettier-security-filename-placeholder.js"
|
|
|
|
|
);
|
2022-01-26 19:08:55 +08:00
|
|
|
define.__dirname = JSON.stringify("/prettier-security-dirname-placeholder");
|
2018-05-29 14:59:57 -03:00
|
|
|
}
|
2020-05-11 09:05:06 +08:00
|
|
|
|
2021-05-27 08:54:42 +08:00
|
|
|
const replaceModule = {};
|
|
|
|
|
// Replace other bundled files
|
|
|
|
|
if (bundle.target === "node") {
|
2021-07-13 15:16:31 +08:00
|
|
|
// Replace package.json with dynamic `require("./package.json")`
|
2022-01-24 17:29:31 +08:00
|
|
|
replaceModule[path.join(PROJECT_ROOT, "package.json")] = {
|
|
|
|
|
path: "./package.json",
|
|
|
|
|
external: true,
|
|
|
|
|
};
|
2021-07-13 15:16:31 +08:00
|
|
|
|
|
|
|
|
// Dynamic require bundled files
|
2021-05-27 08:54:42 +08:00
|
|
|
for (const item of bundles) {
|
|
|
|
|
if (item.input !== bundle.input) {
|
|
|
|
|
replaceModule[path.join(PROJECT_ROOT, item.input)] = `./${item.output}`;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-13 15:16:31 +08:00
|
|
|
} else {
|
|
|
|
|
// Universal bundle only use version info from package.json
|
|
|
|
|
// Replace package.json with `{version: "{VERSION}"}`
|
|
|
|
|
replaceModule[path.join(PROJECT_ROOT, "package.json")] = {
|
2022-02-05 22:51:17 +08:00
|
|
|
contents: JSON.stringify({ version: packageJson.version }),
|
|
|
|
|
loader: "json",
|
2021-07-13 15:16:31 +08:00
|
|
|
};
|
2021-07-12 14:33:52 +08:00
|
|
|
|
2021-07-15 09:53:34 +08:00
|
|
|
// Replace parser getters with `undefined`
|
2021-07-13 15:16:31 +08:00
|
|
|
for (const file of [
|
|
|
|
|
"src/language-css/parsers.js",
|
|
|
|
|
"src/language-graphql/parsers.js",
|
|
|
|
|
"src/language-handlebars/parsers.js",
|
|
|
|
|
"src/language-html/parsers.js",
|
2021-07-15 09:53:34 +08:00
|
|
|
"src/language-js/parse/parsers.js",
|
2021-07-13 15:16:31 +08:00
|
|
|
"src/language-markdown/parsers.js",
|
|
|
|
|
"src/language-yaml/parsers.js",
|
|
|
|
|
]) {
|
2022-02-05 22:51:17 +08:00
|
|
|
replaceModule[path.join(PROJECT_ROOT, file)] = EMPTY_MODULE_REPLACEMENT;
|
2021-07-13 15:16:31 +08:00
|
|
|
}
|
2022-01-26 08:56:44 +08:00
|
|
|
|
|
|
|
|
// Prevent `esbuildPluginNodeModulePolyfills` include shim for this module
|
2022-02-05 22:51:17 +08:00
|
|
|
replaceModule.assert = require.resolve("./shims/assert.cjs");
|
2021-07-13 15:16:31 +08:00
|
|
|
}
|
2021-07-12 14:33:52 +08:00
|
|
|
|
2022-01-26 20:33:15 +08:00
|
|
|
let shouldMinify = buildOptions.minify;
|
2021-11-27 18:47:02 +08:00
|
|
|
if (typeof shouldMinify !== "boolean") {
|
|
|
|
|
shouldMinify = bundle.minify !== false && bundle.target === "universal";
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-14 15:58:13 +08:00
|
|
|
const esbuildOptions = {
|
|
|
|
|
entryPoints: [path.join(PROJECT_ROOT, bundle.input)],
|
2022-01-26 19:08:55 +08:00
|
|
|
define,
|
2022-01-14 15:58:13 +08:00
|
|
|
bundle: true,
|
|
|
|
|
metafile: true,
|
|
|
|
|
plugins: [
|
|
|
|
|
esbuildPluginEvaluate(),
|
|
|
|
|
esbuildPluginReplaceModule({ ...replaceModule, ...bundle.replaceModule }),
|
2022-01-26 08:56:44 +08:00
|
|
|
bundle.target === "universal" && esbuildPluginNodeModulePolyfills(),
|
2022-01-14 15:58:13 +08:00
|
|
|
esbuildPluginTextReplace({
|
|
|
|
|
include: /\.[cm]?js$/,
|
|
|
|
|
// TODO[@fisker]: Use RegExp when possible
|
|
|
|
|
pattern: Object.entries({ ...replaceStrings, ...bundle.replace }),
|
|
|
|
|
}),
|
2022-01-26 20:33:15 +08:00
|
|
|
buildOptions.onLicenseFound &&
|
2022-01-14 15:58:13 +08:00
|
|
|
esbuildPluginLicense({
|
|
|
|
|
cwd: PROJECT_ROOT,
|
|
|
|
|
thirdParty: {
|
|
|
|
|
includePrivate: true,
|
2022-01-26 20:33:15 +08:00
|
|
|
output: buildOptions.onLicenseFound,
|
2018-06-13 17:23:33 -03:00
|
|
|
},
|
2022-01-14 15:58:13 +08:00
|
|
|
}),
|
2022-01-27 16:53:07 +08:00
|
|
|
buildOptions.reports &&
|
|
|
|
|
esbuildPluginVisualizer({ formats: buildOptions.reports }),
|
2022-01-14 15:58:13 +08:00
|
|
|
].filter(Boolean),
|
|
|
|
|
minify: shouldMinify,
|
|
|
|
|
legalComments: "none",
|
|
|
|
|
external: [...(bundle.external || [])],
|
|
|
|
|
// Disable esbuild auto discover `tsconfig.json` file
|
|
|
|
|
tsconfig: path.join(__dirname, "empty-tsconfig.json"),
|
|
|
|
|
mainFields: ["main"],
|
|
|
|
|
target: ["node10"],
|
|
|
|
|
logLevel: "error",
|
2018-05-29 14:59:57 -03:00
|
|
|
};
|
2019-09-16 17:13:32 +08:00
|
|
|
|
2022-01-14 15:58:13 +08:00
|
|
|
if (bundle.target === "universal") {
|
|
|
|
|
esbuildOptions.target.push(...umdTarget);
|
2021-11-27 18:47:02 +08:00
|
|
|
|
2022-01-14 15:58:13 +08:00
|
|
|
yield {
|
|
|
|
|
...esbuildOptions,
|
2022-01-27 09:37:55 +08:00
|
|
|
outfile: bundle.output,
|
2022-01-14 15:58:13 +08:00
|
|
|
plugins: [
|
|
|
|
|
esbuildPluginUmd({ name: bundle.name }),
|
|
|
|
|
...esbuildOptions.plugins,
|
|
|
|
|
],
|
|
|
|
|
format: "umd",
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-27 21:14:31 +08:00
|
|
|
if (/^(?:standalone|parser-.*)\.js$/.test(bundle.output)) {
|
|
|
|
|
yield {
|
|
|
|
|
...esbuildOptions,
|
|
|
|
|
outfile: `esm/${bundle.output.replace(".js", ".mjs")}`,
|
|
|
|
|
format: "esm",
|
|
|
|
|
};
|
|
|
|
|
}
|
2021-11-27 18:47:02 +08:00
|
|
|
} else {
|
2022-02-28 18:38:33 +08:00
|
|
|
esbuildOptions.platform = "node";
|
2022-01-14 15:58:13 +08:00
|
|
|
esbuildOptions.external.push(
|
|
|
|
|
...bundles
|
|
|
|
|
.filter((item) => item.input !== bundle.input)
|
2022-01-24 17:29:31 +08:00
|
|
|
.map((item) => `./${item.output}`)
|
2022-01-14 15:58:13 +08:00
|
|
|
);
|
2019-09-16 17:13:32 +08:00
|
|
|
|
2022-01-14 15:58:13 +08:00
|
|
|
yield {
|
|
|
|
|
...esbuildOptions,
|
2022-01-27 09:37:55 +08:00
|
|
|
outfile: bundle.output,
|
2022-01-14 15:58:13 +08:00
|
|
|
format: "cjs",
|
|
|
|
|
};
|
|
|
|
|
}
|
2018-05-29 14:59:57 -03:00
|
|
|
}
|
|
|
|
|
|
2022-01-26 20:33:15 +08:00
|
|
|
async function runBuild(bundle, esbuildOptions, buildOptions) {
|
|
|
|
|
if (!buildOptions.babel) {
|
|
|
|
|
await esbuild.build(esbuildOptions);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-14 15:58:13 +08:00
|
|
|
const { format, plugins, outfile } = esbuildOptions;
|
2020-10-22 13:32:50 +08:00
|
|
|
|
2022-01-14 15:58:13 +08:00
|
|
|
await esbuild.build({
|
|
|
|
|
...esbuildOptions,
|
|
|
|
|
plugins: plugins.filter(({ name }) => name !== "umd"),
|
|
|
|
|
format: format === "umd" ? "cjs" : format,
|
|
|
|
|
minify: false,
|
|
|
|
|
});
|
2020-10-22 13:32:50 +08:00
|
|
|
|
2022-01-14 15:58:13 +08:00
|
|
|
const text = await fs.readFile(outfile);
|
2020-10-22 13:32:50 +08:00
|
|
|
|
2022-01-14 15:58:13 +08:00
|
|
|
const { code } = await babel.transformAsync(text, {
|
|
|
|
|
filename: outfile,
|
|
|
|
|
...getBabelConfig(bundle),
|
|
|
|
|
});
|
|
|
|
|
await fs.writeFile(outfile, code);
|
|
|
|
|
|
|
|
|
|
await esbuild.build({
|
|
|
|
|
...esbuildOptions,
|
2022-01-28 16:31:48 +08:00
|
|
|
define: {},
|
2022-01-14 15:58:13 +08:00
|
|
|
plugins: plugins.filter(({ name }) => name === "umd"),
|
|
|
|
|
entryPoints: [outfile],
|
|
|
|
|
allowOverwrite: true,
|
2018-05-29 14:59:57 -03:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-27 09:37:55 +08:00
|
|
|
async function* createBundle(bundle, buildOptions) {
|
2022-02-05 22:51:17 +08:00
|
|
|
for (const esbuildOptions of getEsbuildOptions(bundle, buildOptions)) {
|
2022-01-27 09:37:55 +08:00
|
|
|
const { outfile: file } = esbuildOptions;
|
2018-06-18 15:16:40 -03:00
|
|
|
|
2022-01-27 09:37:55 +08:00
|
|
|
if (
|
|
|
|
|
(buildOptions.files && !buildOptions.files.has(file)) ||
|
|
|
|
|
(buildOptions.playground && esbuildOptions.format !== "umd")
|
|
|
|
|
) {
|
|
|
|
|
yield { name: file, skipped: true };
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-07 12:00:43 +08:00
|
|
|
const relativePath = buildOptions.saveAs || file;
|
|
|
|
|
const absolutePath = path.join(DIST_DIR, relativePath);
|
|
|
|
|
|
|
|
|
|
esbuildOptions.outfile = absolutePath;
|
2022-01-27 09:37:55 +08:00
|
|
|
|
|
|
|
|
yield { name: file, started: true };
|
|
|
|
|
await runBuild(bundle, esbuildOptions, buildOptions);
|
2022-02-07 12:00:43 +08:00
|
|
|
yield { name: file, relativePath, absolutePath };
|
2022-01-27 09:37:55 +08:00
|
|
|
}
|
2021-05-15 20:09:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default createBundle;
|