Files
test-repo/scripts/build/bundler.mjs
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

232 lines
7.4 KiB
JavaScript
Raw Normal View History

2021-05-15 20:09:52 +08:00
import path from "node:path";
import createEsmUtils from "esm-utils";
2022-01-09 01:15:04 +08:00
import esbuild from "esbuild";
import { NodeModulesPolyfillPlugin as esbuildPluginNodeModulePolyfills } from "@esbuild-plugins/node-modules-polyfill";
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-09 01:15:04 +08:00
import esbuildPluginEvaluate from "./esbuild-plugins/evaluate.mjs";
import esbuildPluginReplaceModule from "./esbuild-plugins/replace-module.mjs";
2022-03-14 20:02:02 +08:00
import esbuildPluginReplaceText from "./esbuild-plugins/replace-text.mjs";
2022-01-09 01:15:04 +08:00
import esbuildPluginLicense from "./esbuild-plugins/license.mjs";
import esbuildPluginUmd from "./esbuild-plugins/umd.mjs";
2022-02-17 09:47:35 +08:00
import esbuildPluginInteropDefault from "./esbuild-plugins/interop-default.mjs";
2022-01-27 11:16:50 +08:00
import esbuildPluginVisualizer from "./esbuild-plugins/visualizer.mjs";
2022-03-02 13:44:00 +08:00
import esbuildPluginStripNodeProtocol from "./esbuild-plugins/strip-node-protocol.mjs";
import esbuildPluginThrowWarnings from "./esbuild-plugins/throw-warnings.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
const umdTarget = browserslistToEsbuild(packageJson.browserslist);
const EXPORT_UNDEFINED_MODULE_REPLACEMENT = {
contents: "export default undefined",
};
2018-05-29 14:59:57 -03:00
const bundledFiles = [
...bundles,
{ input: "package.json", output: "package.json" },
].map(({ input, output }) => ({
input: path.join(PROJECT_ROOT, input),
output: `./${output}`,
}));
2022-02-05 22:51:17 +08:00
function* getEsbuildOptions(bundle, buildOptions) {
2022-03-14 20:02:02 +08:00
const replaceText = [
2022-02-17 09:47:35 +08:00
// Use `require` directly
2022-03-17 09:44:08 +08:00
{
2022-03-17 09:54:48 +08:00
file: "*",
2022-03-17 09:44:08 +08:00
find: "const require = createRequire(import.meta.url);",
replacement: "",
},
2022-03-17 09:54:48 +08:00
// Use `__dirname` directly
{
file: "*",
find: "const __dirname = path.dirname(fileURLToPath(import.meta.url));",
replacement: "",
},
// `tslib` exports global variables
2022-03-14 20:02:02 +08:00
{
file: require.resolve("tslib"),
find: "factory(createExporter(root",
replacement: "factory(createExporter({}",
},
];
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-03-14 20:02:02 +08:00
replaceText.push({
file: "*",
find: "process.env.PRETTIER_DEBUG",
replacement: "globalThis.PRETTIER_DEBUG",
});
2022-01-26 19:08:55 +08:00
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
// See #8268
2022-01-26 19:08:55 +08:00
define.__filename = JSON.stringify(
"/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
2022-03-17 19:56:48 +08:00
const replaceModule = {};
2021-05-27 08:54:42 +08:00
// Replace other bundled files
if (bundle.target === "node") {
2022-03-14 10:34:19 +08:00
// Replace bundled files and `package.json` with dynamic `require()`
for (const { input, output } of bundledFiles) {
replaceModule[input] = { path: output, external: true };
}
} 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",
};
// Replace parser getters with `undefined`
for (const file of [
2022-02-21 14:22:51 +08:00
"src/language-css/parsers.js",
"src/language-graphql/parsers.js",
2022-02-21 16:44:56 +08:00
"src/language-html/parsers.js",
"src/language-handlebars/parsers.js",
2022-02-21 15:53:02 +08:00
"src/language-js/parse/parsers.js",
"src/language-markdown/parsers.js",
2022-02-21 13:49:08 +08:00
"src/language-yaml/parsers.js",
// This module requires file access, should not include in universal bundle
"src/utils/get-interpreter.js",
]) {
replaceModule[path.join(PROJECT_ROOT, file)] =
EXPORT_UNDEFINED_MODULE_REPLACEMENT;
}
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");
2022-03-17 19:56:48 +08:00
// `esbuildPluginNodeModulePolyfills` didn't shim this module
2022-03-17 20:35:49 +08:00
replaceModule.module = {
contents: "export const createRequire = () => {};",
};
}
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-03-14 16:30:12 +08:00
const interopDefault =
!bundle.input.endsWith(".cjs") && bundle.interopDefault !== false;
2022-01-09 01:15:04 +08:00
const esbuildOptions = {
entryPoints: [path.join(PROJECT_ROOT, bundle.input)],
2022-01-26 19:08:55 +08:00
define,
2022-01-09 01:15:04 +08:00
bundle: true,
metafile: true,
plugins: [
esbuildPluginEvaluate(),
2022-03-02 13:44:00 +08:00
esbuildPluginStripNodeProtocol(),
2022-01-09 01:15:04 +08:00
esbuildPluginReplaceModule({ ...replaceModule, ...bundle.replaceModule }),
2022-01-26 08:56:44 +08:00
bundle.target === "universal" && esbuildPluginNodeModulePolyfills(),
2022-03-14 20:02:02 +08:00
esbuildPluginReplaceText({
filter: /\.[cm]?js$/,
replacements: [...replaceText, ...(bundle.replaceText ?? [])],
2022-01-09 01:15:04 +08:00
}),
2022-01-26 20:33:15 +08:00
buildOptions.onLicenseFound &&
2022-01-09 01:15:04 +08:00
esbuildPluginLicense({
cwd: PROJECT_ROOT,
thirdParty: {
includePrivate: true,
2022-01-26 20:33:15 +08:00
output: buildOptions.onLicenseFound,
2022-01-09 01:15:04 +08:00
},
}),
2022-01-27 16:53:07 +08:00
buildOptions.reports &&
esbuildPluginVisualizer({ formats: buildOptions.reports }),
esbuildPluginThrowWarnings(),
2022-01-09 01:15:04 +08:00
].filter(Boolean),
minify: shouldMinify,
legalComments: "none",
2022-03-13 22:47:02 +08:00
external: [...(bundle.external ?? [])],
2022-01-09 01:15:04 +08:00
// Disable esbuild auto discover `tsconfig.json` file
tsconfig: path.join(__dirname, "empty-tsconfig.json"),
2022-03-14 10:54:46 +08:00
target: [...(bundle.esbuildTarget ?? ["node12"])],
logLevel: "error",
2022-01-09 01:15:04 +08:00
};
2021-09-12 23:26:29 +08:00
2022-01-09 01:15:04 +08:00
if (bundle.target === "universal") {
2022-03-13 22:47:02 +08:00
if (!bundle.esbuildTarget) {
esbuildOptions.target.push(...umdTarget);
}
2022-01-09 01:15:04 +08:00
yield {
...esbuildOptions,
2022-01-27 09:37:55 +08:00
outfile: bundle.output,
2022-01-09 01:15:04 +08:00
plugins: [
2022-02-17 09:47:35 +08:00
esbuildPluginUmd({
name: bundle.name,
2022-03-14 16:30:12 +08:00
interopDefault,
2022-02-17 09:47:35 +08:00
}),
2022-01-09 01:15:04 +08:00
...esbuildOptions.plugins,
],
format: "umd",
};
2022-01-27 21:14:31 +08:00
if (/^(?:standalone|parser-.*)\.js$/.test(bundle.output)) {
2022-01-09 01:15:04 +08:00
yield {
...esbuildOptions,
2022-01-27 21:14:31 +08:00
outfile: `esm/${bundle.output.replace(".js", ".mjs")}`,
2022-01-09 01:15:04 +08:00
format: "esm",
};
2020-09-17 01:08:44 +09:00
}
2022-01-09 01:15:04 +08:00
} else {
2022-02-28 18:38:33 +08:00
esbuildOptions.platform = "node";
esbuildOptions.external.push(...bundledFiles.map(({ output }) => output));
2020-10-26 09:44:09 +08:00
2022-03-14 16:30:12 +08:00
if (interopDefault) {
2022-02-17 09:47:35 +08:00
esbuildOptions.plugins.push(esbuildPluginInteropDefault());
}
2022-01-09 01:15:04 +08:00
yield {
...esbuildOptions,
2022-01-27 09:37:55 +08:00
outfile: bundle.output,
2022-01-09 01:15:04 +08:00
format: "cjs",
};
2020-10-26 09:44:09 +08:00
}
2018-05-29 14:59:57 -03:00
}
async function runBuild(bundle, esbuildOptions) {
2022-01-14 16:07:45 +08:00
await esbuild.build(esbuildOptions);
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;
2019-06-08 03:58:05 +08: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;
}
2018-06-18 15:16:40 -03:00
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;