Skip to content

Commit 7544c32

Browse files
authored
Build: Combine replace-module and replace-text plugin (#12489)
1 parent ef3fe51 commit 7544c32

7 files changed

Lines changed: 281 additions & 154 deletions

File tree

scripts/build/bundler.mjs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import browserslistToEsbuild from "browserslist-to-esbuild";
88
import { PROJECT_ROOT, DIST_DIR } from "../utils/index.mjs";
99
import esbuildPluginEvaluate from "./esbuild-plugins/evaluate.mjs";
1010
import esbuildPluginReplaceModule from "./esbuild-plugins/replace-module.mjs";
11-
import esbuildPluginReplaceText from "./esbuild-plugins/replace-text.mjs";
1211
import esbuildPluginLicense from "./esbuild-plugins/license.mjs";
1312
import esbuildPluginUmd from "./esbuild-plugins/umd.mjs";
1413
import esbuildPluginVisualizer from "./esbuild-plugins/visualizer.mjs";
@@ -19,7 +18,6 @@ const { __dirname, readJsonSync, require } = createEsmUtils(import.meta);
1918
const packageJson = readJsonSync("../../package.json");
2019

2120
const umdTarget = browserslistToEsbuild(packageJson.browserslist);
22-
const EMPTY_MODULE_REPLACEMENT = { contents: "" };
2321

2422
function getBabelConfig(bundle) {
2523
const config = {
@@ -77,10 +75,10 @@ const bundledFiles = [
7775
}));
7876

7977
function* getEsbuildOptions(bundle, buildOptions) {
80-
const replaceText = [
78+
const replaceModule = [
8179
// `tslib` exports global variables
8280
{
83-
file: require.resolve("tslib"),
81+
module: require.resolve("tslib"),
8482
find: "factory(createExporter(root",
8583
replacement: "factory(createExporter({}",
8684
},
@@ -94,8 +92,8 @@ function* getEsbuildOptions(bundle, buildOptions) {
9492
if (bundle.target === "universal") {
9593
// We can't reference `process` in UMD bundles and this is
9694
// an undocumented "feature"
97-
replaceText.push({
98-
file: "*",
95+
replaceModule.push({
96+
module: "*",
9997
find: "process.env.PRETTIER_DEBUG",
10098
replacement: "globalThis.PRETTIER_DEBUG",
10199
});
@@ -111,20 +109,20 @@ function* getEsbuildOptions(bundle, buildOptions) {
111109
define.__dirname = JSON.stringify("/prettier-security-dirname-placeholder");
112110
}
113111

114-
const replaceModule = {};
115112
// Replace other bundled files
116113
if (bundle.target === "node") {
117114
// Replace bundled files and `package.json` with dynamic `require()`
118115
for (const { input, output } of bundledFiles) {
119-
replaceModule[input] = { path: output, external: true };
116+
replaceModule.push({ module: input, external: output });
120117
}
121118
} else {
122119
// Universal bundle only use version info from package.json
123120
// Replace package.json with `{version: "{VERSION}"}`
124-
replaceModule[path.join(PROJECT_ROOT, "package.json")] = {
125-
contents: JSON.stringify({ version: packageJson.version }),
121+
replaceModule.push({
122+
module: path.join(PROJECT_ROOT, "package.json"),
123+
text: JSON.stringify({ version: packageJson.version }),
126124
loader: "json",
127-
};
125+
});
128126

129127
// Replace parser getters with `undefined`
130128
for (const file of [
@@ -136,11 +134,14 @@ function* getEsbuildOptions(bundle, buildOptions) {
136134
"src/language-markdown/parsers.js",
137135
"src/language-yaml/parsers.js",
138136
]) {
139-
replaceModule[path.join(PROJECT_ROOT, file)] = EMPTY_MODULE_REPLACEMENT;
137+
replaceModule.push({ module: path.join(PROJECT_ROOT, file), text: "" });
140138
}
141139

142140
// Prevent `esbuildPluginNodeModulePolyfills` include shim for this module
143-
replaceModule.assert = require.resolve("./shims/assert.cjs");
141+
replaceModule.push({
142+
module: "assert",
143+
path: require.resolve("./shims/assert.cjs"),
144+
});
144145
}
145146

146147
let shouldMinify = buildOptions.minify;
@@ -155,12 +156,10 @@ function* getEsbuildOptions(bundle, buildOptions) {
155156
metafile: true,
156157
plugins: [
157158
esbuildPluginEvaluate(),
158-
esbuildPluginReplaceModule({ ...replaceModule, ...bundle.replaceModule }),
159-
bundle.target === "universal" && esbuildPluginNodeModulePolyfills(),
160-
esbuildPluginReplaceText({
161-
filter: /\.[cm]?js$/,
162-
replacements: [...replaceText, ...(bundle.replaceText ?? [])],
159+
esbuildPluginReplaceModule({
160+
replacements: [...replaceModule, ...(bundle.replaceModule ?? [])],
163161
}),
162+
bundle.target === "universal" && esbuildPluginNodeModulePolyfills(),
164163
buildOptions.onLicenseFound &&
165164
esbuildPluginLicense({
166165
cwd: PROJECT_ROOT,

scripts/build/config.mjs

Lines changed: 58 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ const { require } = createEsmUtils(import.meta);
1212
* @property {'node' | 'universal'} target - should generate a CJS only for node or universal bundle
1313
* @property {'core' | 'plugin'} type - it's a plugin bundle or core part of prettier
1414
* @property {string[]} external - array of paths that should not be included in the final bundle
15-
* @property {Object.<string, string | {code: string}>} replaceModule - module replacement path or code
16-
* @property {{file: string, find: string, replacement: string}[]} replaceText - Text replacements
15+
* @property {object[]} replaceModule - Module replacements
1716
* @property {string[]} babelPlugins - babel plugins
1817
* @property {boolean?} minify - minify
1918
* @property {string[]?} esbuildTarget - ESBuild target
@@ -31,10 +30,8 @@ To reduce the bundle size, replace the entry with smaller files.
3130
We can switch to deep require once https://github.com/kpdecker/jsdiff/pull/351 get merged
3231
*/
3332
const replaceDiffPackageEntry = (file) => ({
34-
[require.resolve("diff")]: path.join(
35-
path.dirname(require.resolve("diff/package.json")),
36-
file
37-
),
33+
module: require.resolve("diff"),
34+
path: path.join(path.dirname(require.resolve("diff/package.json")), file),
3835
});
3936

4037
/** @type {Bundle[]} */
@@ -44,51 +41,51 @@ const parsers = [
4441
},
4542
{
4643
input: "src/language-js/parse/flow.js",
47-
replaceText: [
44+
replaceModule: [
4845
// `flow-parser` use this for `globalThis`, can't work in strictMode
4946
{
50-
file: require.resolve("flow-parser"),
47+
module: require.resolve("flow-parser"),
5148
find: "(function(){return this}())",
5249
replacement: "(globalThis)",
5350
},
5451
],
5552
},
5653
{
5754
input: "src/language-js/parse/typescript.js",
58-
replaceText: [
55+
replaceModule: [
5956
// `@typescript-eslint/typescript-estree` v4
6057
{
61-
file: "*",
58+
module: "*",
6259
find: 'require("globby")',
6360
replacement: "{}",
6461
},
6562
{
66-
file: "*",
63+
module: "*",
6764
find: "extra.projects = prepareAndTransformProjects(",
6865
replacement: "extra.projects = [] || prepareAndTransformProjects(",
6966
},
7067
{
71-
file: "*",
68+
module: "*",
7269
find: "process.versions.node",
7370
replacement: JSON.stringify("999.999.999"),
7471
},
7572
{
76-
file: "*",
73+
module: "*",
7774
find: "process.cwd()",
7875
replacement: JSON.stringify("/prettier-security-dirname-placeholder"),
7976
},
8077
{
81-
file: "*",
78+
module: "*",
8279
find: 'require("perf_hooks")',
8380
replacement: "{}",
8481
},
8582
{
86-
file: "*",
83+
module: "*",
8784
find: 'require("inspector")',
8885
replacement: "{}",
8986
},
9087
{
91-
file: "*",
88+
module: "*",
9289
find: "typescriptVersionIsAtLeast[version] = semverCheck(version);",
9390
replacement: "typescriptVersionIsAtLeast[version] = true;",
9491
},
@@ -137,29 +134,29 @@ const parsers = [
137134
'require("source-map-support").install()': "",
138135
"require(modulePath)": "undefined",
139136
}).map(([find, replacement]) => ({
140-
file: require.resolve("typescript"),
137+
module: require.resolve("typescript"),
141138
find,
142139
replacement,
143140
})),
141+
{
142+
module: require.resolve("debug/src/browser.js"),
143+
path: require.resolve("./shims/debug.cjs"),
144+
},
144145
],
145-
replaceModule: {
146-
[require.resolve("debug/src/browser.js")]:
147-
require.resolve("./shims/debug.cjs"),
148-
},
149146
},
150147
{
151148
input: "src/language-js/parse/acorn-and-espree.js",
152149
name: "prettierPlugins.espree",
153150
// TODO: Rename this file to `parser-acorn-and-espree.js` or find a better way
154151
output: "parser-espree.js",
155-
replaceText: [
152+
replaceModule: [
156153
{
157-
file: require.resolve("espree"),
154+
module: require.resolve("espree"),
158155
find: "const Syntax = (function() {",
159156
replacement: "const Syntax = undefined && (function() {",
160157
},
161158
{
162-
file: require.resolve("espree"),
159+
module: require.resolve("espree"),
163160
find: "var visitorKeys = require('eslint-visitor-keys');",
164161
replacement: "var visitorKeys;",
165162
},
@@ -170,21 +167,21 @@ const parsers = [
170167
},
171168
{
172169
input: "src/language-js/parse/angular.js",
173-
replaceText: [
170+
replaceModule: [
174171
{
175-
file: "*",
172+
module: "*",
176173
find: 'require("@angular/compiler/src/',
177174
replacement: 'require("@angular/compiler/esm2015/src/',
178175
},
179176
],
180177
},
181178
{
182179
input: "src/language-css/parser-postcss.js",
183-
replaceText: [
180+
replaceModule: [
184181
{
185182
// `postcss-values-parser` uses constructor.name, it will be changed by bundler
186183
// https://github.com/shellscape/postcss-values-parser/blob/c00f858ab8c86ce9f06fdb702e8f26376f467248/lib/parser.js#L499
187-
file: require.resolve("postcss-values-parser/lib/parser.js"),
184+
module: require.resolve("postcss-values-parser/lib/parser.js"),
188185
find: "node.constructor.name === 'Word'",
189186
replacement: "node.type === 'word'",
190187
},
@@ -195,10 +192,12 @@ const parsers = [
195192
},
196193
{
197194
input: "src/language-markdown/parser-markdown.js",
198-
replaceModule: {
199-
[require.resolve("parse-entities/decode-entity.browser.js")]:
200-
require.resolve("parse-entities/decode-entity.js"),
201-
},
195+
replaceModule: [
196+
{
197+
module: require.resolve("parse-entities/decode-entity.browser.js"),
198+
path: require.resolve("parse-entities/decode-entity.js"),
199+
},
200+
],
202201
},
203202
{
204203
input: "src/language-handlebars/parser-glimmer.js",
@@ -208,12 +207,13 @@ const parsers = [
208207
},
209208
{
210209
input: "src/language-yaml/parser-yaml.js",
211-
replaceModule: {
210+
replaceModule: [
212211
// Use `tslib.es6.js`, so we can avoid `globalThis` shim
213-
[require.resolve("tslib")]: require
214-
.resolve("tslib")
215-
.replace(/tslib\.js$/, "tslib.es6.js"),
216-
},
212+
{
213+
module: require.resolve("tslib"),
214+
path: require.resolve("tslib").replace(/tslib\.js$/, "tslib.es6.js"),
215+
},
216+
],
217217
},
218218
].map((bundle) => {
219219
const { name } = bundle.input.match(
@@ -233,14 +233,14 @@ const parsers = [
233233
const coreBundles = [
234234
{
235235
input: "src/index.js",
236-
replaceText: [
236+
replaceModule: [
237237
{
238-
file: require.resolve("@iarna/toml/lib/toml-parser.js"),
238+
module: require.resolve("@iarna/toml/lib/toml-parser.js"),
239239
find: "const utilInspect = eval(\"require('util').inspect\")",
240240
replacement: "const utilInspect = require('util').inspect",
241241
},
242+
replaceDiffPackageEntry("lib/diff/array.js"),
242243
],
243-
replaceModule: replaceDiffPackageEntry("lib/diff/array.js"),
244244
},
245245
{
246246
input: "src/document/index.js",
@@ -254,14 +254,17 @@ const coreBundles = [
254254
input: "src/standalone.js",
255255
name: "prettier",
256256
target: "universal",
257-
replaceModule: {
258-
[require.resolve("@babel/highlight")]: require.resolve(
259-
"./shims/babel-highlight.cjs"
260-
),
261-
[createRequire(require.resolve("vnopts")).resolve("chalk")]:
262-
require.resolve("./shims/chalk.cjs"),
263-
...replaceDiffPackageEntry("lib/diff/array.js"),
264-
},
257+
replaceModule: [
258+
{
259+
module: require.resolve("@babel/highlight"),
260+
path: require.resolve("./shims/babel-highlight.cjs"),
261+
},
262+
{
263+
module: createRequire(require.resolve("vnopts")).resolve("chalk"),
264+
path: require.resolve("./shims/chalk.cjs"),
265+
},
266+
replaceDiffPackageEntry("lib/diff/array.js"),
267+
],
265268
},
266269
{
267270
input: "bin/prettier.js",
@@ -273,16 +276,17 @@ const coreBundles = [
273276
input: "src/cli/index.js",
274277
output: "cli.js",
275278
external: ["benchmark"],
276-
replaceModule: replaceDiffPackageEntry("lib/patch/create.js"),
279+
replaceModule: [replaceDiffPackageEntry("lib/patch/create.js")],
277280
},
278281
{
279282
input: "src/common/third-party.js",
280-
replaceModule: {
283+
replaceModule: [
281284
// cosmiconfig@6 -> import-fresh can't find parentModule, since module is bundled
282-
[require.resolve("parent-module")]: require.resolve(
283-
"./shims/parent-module.cjs"
284-
),
285-
},
285+
{
286+
module: require.resolve("parent-module"),
287+
path: require.resolve("./shims/parent-module.cjs"),
288+
},
289+
],
286290
},
287291
].map((bundle) => ({
288292
type: "core",

scripts/build/esbuild-plugins/license.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export default function esbuildPluginLicense(options) {
1010
build.initialOptions.metafile = true;
1111

1212
build.onEnd((result) => {
13+
if (result.errors.length > 0) {
14+
return;
15+
}
16+
1317
const files = Object.keys(result.metafile.inputs);
1418
const chunk = {
1519
modules: Object.fromEntries(

0 commit comments

Comments
 (0)