Skip to content

Commit 72b92d6

Browse files
committed
Compute esbuild options lazily
1 parent 28cdd63 commit 72b92d6

File tree

1 file changed

+60
-59
lines changed

1 file changed

+60
-59
lines changed

Herebyfile.mjs

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -185,71 +185,72 @@ async function runDtsBundler(entrypoint, output) {
185185
* @param {boolean} exportIsTsObject True if this file exports the TS object and should have relevant code injected.
186186
*/
187187
function esbuildTask(entrypoint, outfile, exportIsTsObject = false) {
188-
// Note: we do not use --minify, as that would hide function names from user backtraces
189-
// (we don't ship our sourcemaps), and would break consumers like monaco which modify
190-
// typescript.js for their own needs. Also, using --sourcesContent=false doesn't help,
191-
// as even though it's a smaller source map that could be shipped to users for better
192-
// stack traces via names, the maps are bigger than the actual source files themselves.
193-
/** @type {esbuild.BuildOptions} */
194-
const options = {
195-
entryPoints: [entrypoint],
196-
banner: { js: getCopyrightHeader() },
197-
bundle: true,
198-
outfile,
199-
platform: "node",
200-
target: "es2018", // Covers Node 10.
201-
format: "cjs",
202-
sourcemap: "linked",
203-
external: ["./node_modules/*"],
204-
conditions: ["require"],
205-
// legalComments: "none", // If we add copyright headers to the source files, uncomment.
206-
plugins: [
207-
{
208-
name: "fix-require",
209-
setup: (build) => {
210-
build.onEnd(async () => {
211-
// esbuild converts calls to "require" to "__require"; this function
212-
// calls the real require if it exists, or throws if it does not (rather than
213-
// throwing an error like "require not defined"). But, since we want typescript
214-
// to be consumable by other bundlers, we need to convert these calls back to
215-
// require so our imports are visible again.
216-
//
217-
// Note that this step breaks source maps, but only for lines that reference
218-
// "__require", which is an okay tradeoff for the performance of not running
219-
// the output through transpileModule/babel/etc.
220-
//
221-
// See: https://github.com/evanw/esbuild/issues/1905
222-
let contents = await fs.promises.readFile(outfile, "utf-8");
223-
contents = contents.replace(/__require\(/g, "require(");
224-
await fs.promises.writeFile(outfile, contents);
225-
});
226-
},
227-
}
228-
]
229-
};
230-
231-
if (exportIsTsObject) {
232-
options.format = "iife"; // We use an IIFE so we can inject the code below.
233-
options.globalName = "ts"; // Name the variable ts, matching our old big bundle and so we can use the code below.
234-
options.footer = {
235-
// These snippets cannot appear in the actual source files, otherwise they will be rewritten
236-
// to things like exports or requires.
237-
js: `
188+
return {
189+
build: async () => {
190+
// Note: we do not use --minify, as that would hide function names from user backtraces
191+
// (we don't ship our sourcemaps), and would break consumers like monaco which modify
192+
// typescript.js for their own needs. Also, using --sourcesContent=false doesn't help,
193+
// as even though it's a smaller source map that could be shipped to users for better
194+
// stack traces via names, the maps are bigger than the actual source files themselves.
195+
/** @type {esbuild.BuildOptions} */
196+
const options = {
197+
entryPoints: [entrypoint],
198+
banner: { js: getCopyrightHeader() },
199+
bundle: true,
200+
outfile,
201+
platform: "node",
202+
target: "es2018", // Covers Node 10.
203+
format: "cjs",
204+
sourcemap: "linked",
205+
external: ["./node_modules/*"],
206+
conditions: ["require"],
207+
// legalComments: "none", // If we add copyright headers to the source files, uncomment.
208+
plugins: [
209+
{
210+
name: "fix-require",
211+
setup: (build) => {
212+
build.onEnd(async () => {
213+
// esbuild converts calls to "require" to "__require"; this function
214+
// calls the real require if it exists, or throws if it does not (rather than
215+
// throwing an error like "require not defined"). But, since we want typescript
216+
// to be consumable by other bundlers, we need to convert these calls back to
217+
// require so our imports are visible again.
218+
//
219+
// Note that this step breaks source maps, but only for lines that reference
220+
// "__require", which is an okay tradeoff for the performance of not running
221+
// the output through transpileModule/babel/etc.
222+
//
223+
// See: https://github.com/evanw/esbuild/issues/1905
224+
let contents = await fs.promises.readFile(outfile, "utf-8");
225+
contents = contents.replace(/__require\(/g, "require(");
226+
await fs.promises.writeFile(outfile, contents);
227+
});
228+
},
229+
}
230+
]
231+
};
232+
233+
if (exportIsTsObject) {
234+
options.format = "iife"; // We use an IIFE so we can inject the code below.
235+
options.globalName = "ts"; // Name the variable ts, matching our old big bundle and so we can use the code below.
236+
options.footer = {
237+
// These snippets cannot appear in the actual source files, otherwise they will be rewritten
238+
// to things like exports or requires.
239+
js: `
238240
if (typeof module !== "undefined" && module.exports) {
239-
// If we are in a CJS context, export the ts namespace.
240-
module.exports = ts;
241+
// If we are in a CJS context, export the ts namespace.
242+
module.exports = ts;
241243
}
242244
if (ts.server) {
243-
// If we are in a server bundle, inject the dynamicImport function.
244-
ts.server.dynamicImport = id => import(id);
245+
// If we are in a server bundle, inject the dynamicImport function.
246+
ts.server.dynamicImport = id => import(id);
245247
}`
246-
};
247-
}
248+
};
249+
}
248250

249-
return {
250-
build: () => esbuild.build(options),
251+
await esbuild.build(options);
252+
},
251253
clean: () => del([outfile, `${outfile}.map`]),
252-
watch: () => esbuild.build({ ...options, watch: true }),
253254
};
254255
}
255256

0 commit comments

Comments
 (0)