1
1
// @ts -check
2
2
import { CancelToken } from "@esfx/canceltoken" ;
3
- import assert from "assert" ;
4
3
import chalk from "chalk" ;
5
4
import chokidar from "chokidar" ;
6
5
import esbuild from "esbuild" ;
@@ -172,25 +171,22 @@ async function runDtsBundler(entrypoint, output) {
172
171
* @param {BundlerTaskOptions } [taskOptions]
173
172
*
174
173
* @typedef BundlerTaskOptions
175
- * @property {boolean } [exportIsTsObject]
176
174
* @property {boolean } [treeShaking]
177
175
* @property {boolean } [usePublicAPI]
178
176
* @property {() => void } [onWatchRebuild]
179
177
*/
180
178
function createBundler ( entrypoint , outfile , taskOptions = { } ) {
181
179
const getOptions = memoize ( async ( ) => {
182
180
const copyright = await getCopyrightHeader ( ) ;
183
- const banner = taskOptions . exportIsTsObject ? "var ts = {}; ((module) => {" : "" ;
184
-
185
181
/** @type {esbuild.BuildOptions } */
186
182
const options = {
187
183
entryPoints : [ entrypoint ] ,
188
- banner : { js : copyright + banner } ,
184
+ banner : { js : copyright } ,
189
185
bundle : true ,
190
186
outfile,
191
187
platform : "node" ,
192
188
target : [ "es2020" , "node14.17" ] ,
193
- format : "cjs " ,
189
+ format : "esm " ,
194
190
sourcemap : "linked" ,
195
191
sourcesContent : false ,
196
192
treeShaking : taskOptions . treeShaking ,
@@ -200,66 +196,17 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
200
196
} ;
201
197
202
198
if ( taskOptions . usePublicAPI ) {
203
- options . external = [ "./typescript.js" ] ;
204
199
options . plugins = options . plugins || [ ] ;
205
200
options . plugins . push ( {
206
- name : "remap-typescript-to-require " ,
201
+ name : "remap-typescript-to-public-api " ,
207
202
setup ( build ) {
208
- build . onLoad ( { filter : / s r c [ \\ / ] t y p e s c r i p t [ \\ / ] t y p e s c r i p t \. t s $ / } , ( ) => {
209
- return { contents : `export * from "./typescript.js"` } ;
203
+ build . onResolve ( { filter : / ^ (?: \. \. [ \\ / ] ) * t y p e s c r i p t [ \\ / ] t y p e s c r i p t \. j s $ / } , ( ) => {
204
+ return { path : "./typescript.js" , external : true } ;
210
205
} ) ;
211
206
} ,
212
207
} ) ;
213
208
}
214
209
215
- if ( taskOptions . exportIsTsObject ) {
216
- // Monaco bundles us as ESM by wrapping our code with something that defines module.exports
217
- // but then does not use it, instead using the `ts` variable. Ensure that if we think we're CJS
218
- // that we still set `ts` to the module.exports object.
219
- options . footer = { js : `})(typeof module !== "undefined" && module.exports ? module : { exports: ts });\nif (typeof module !== "undefined" && module.exports) { ts = module.exports; }` } ;
220
-
221
- // esbuild converts calls to "require" to "__require"; this function
222
- // calls the real require if it exists, or throws if it does not (rather than
223
- // throwing an error like "require not defined"). But, since we want typescript
224
- // to be consumable by other bundlers, we need to convert these calls back to
225
- // require so our imports are visible again.
226
- //
227
- // To fix this, we redefine "require" to a name we're unlikely to use with the
228
- // same length as "require", then replace it back to "require" after bundling,
229
- // ensuring that source maps still work.
230
- //
231
- // See: https://github.com/evanw/esbuild/issues/1905
232
- const require = "require" ;
233
- const fakeName = "Q" . repeat ( require . length ) ;
234
- const fakeNameRegExp = new RegExp ( fakeName , "g" ) ;
235
- options . define = { [ require ] : fakeName } ;
236
-
237
- // For historical reasons, TypeScript does not set __esModule. Hack esbuild's __toCommonJS to be a noop.
238
- // We reference `__copyProps` to ensure the final bundle doesn't have any unreferenced code.
239
- const toCommonJsRegExp = / v a r _ _ t o C o m m o n J S .* / ;
240
- const toCommonJsRegExpReplacement = "var __toCommonJS = (mod) => (__copyProps, mod); // Modified helper to skip setting __esModule." ;
241
-
242
- options . plugins = options . plugins || [ ] ;
243
- options . plugins . push (
244
- {
245
- name : "post-process" ,
246
- setup : build => {
247
- build . onEnd ( async ( ) => {
248
- let contents = await fs . promises . readFile ( outfile , "utf-8" ) ;
249
- contents = contents . replace ( fakeNameRegExp , require ) ;
250
- let matches = 0 ;
251
- contents = contents . replace ( toCommonJsRegExp , ( ) => {
252
- matches ++ ;
253
- return toCommonJsRegExpReplacement ;
254
- } ) ;
255
- assert ( matches === 1 , "Expected exactly one match for __toCommonJS" ) ;
256
- await fs . promises . writeFile ( outfile , contents ) ;
257
- } ) ;
258
- } ,
259
- } ,
260
- ) ;
261
- }
262
-
263
210
return options ;
264
211
} ) ;
265
212
@@ -304,6 +251,7 @@ let printedWatchWarning = false;
304
251
* @param {string } options.builtEntrypoint
305
252
* @param {string } options.output
306
253
* @param {Task[] } [options.mainDeps]
254
+ * @param {boolean } [options.reexportDefault]
307
255
* @param {BundlerTaskOptions } [options.bundlerOptions]
308
256
*/
309
257
function entrypointBuildTask ( options ) {
@@ -324,22 +272,33 @@ function entrypointBuildTask(options) {
324
272
} ) ;
325
273
326
274
/**
327
- * Writes a CJS module that reexports another CJS file. E.g. given
275
+ * Writes a module that reexports another file. E.g. given
328
276
* `options.builtEntrypoint = "./built/local/tsc/tsc.js"` and
329
277
* `options.output = "./built/local/tsc.js"`, this will create a file
330
278
* named "./built/local/tsc.js" containing:
331
279
*
332
280
* ```
333
- * module.exports = require( "./tsc/tsc.js")
281
+ * export * from "./tsc/tsc.js";
334
282
* ```
335
283
*/
336
284
const shim = task ( {
337
285
name : `shim-${ options . name } ` ,
338
286
run : async ( ) => {
339
287
const outDir = path . dirname ( options . output ) ;
340
288
await fs . promises . mkdir ( outDir , { recursive : true } ) ;
341
- const moduleSpecifier = path . relative ( outDir , options . builtEntrypoint ) ;
342
- await fs . promises . writeFile ( options . output , `module.exports = require("./${ moduleSpecifier . replace ( / [ \\ / ] / g, "/" ) } ")` ) ;
289
+ const moduleSpecifier = path . relative ( outDir , options . builtEntrypoint ) . replace ( / [ \\ / ] / g, "/" ) ;
290
+ const lines = [
291
+ `export * from "./${ moduleSpecifier } ";` ,
292
+ ] ;
293
+
294
+ if ( options . reexportDefault ) {
295
+ lines . push (
296
+ `import _default from "./${ moduleSpecifier } ";` ,
297
+ `export default _default;` ,
298
+ ) ;
299
+ }
300
+
301
+ await fs . promises . writeFile ( options . output , lines . join ( "\n" ) + "\n" ) ;
343
302
} ,
344
303
} ) ;
345
304
@@ -404,7 +363,7 @@ const { main: services, build: buildServices, watch: watchServices } = entrypoin
404
363
builtEntrypoint : "./built/local/typescript/typescript.js" ,
405
364
output : "./built/local/typescript.js" ,
406
365
mainDeps : [ generateLibs ] ,
407
- bundlerOptions : { exportIsTsObject : true } ,
366
+ reexportDefault : true ,
408
367
} ) ;
409
368
export { services , watchServices } ;
410
369
@@ -445,25 +404,22 @@ export const watchMin = task({
445
404
dependencies : [ watchTsc , watchTsserver ] ,
446
405
} ) ;
447
406
448
- // This is technically not enough to make tsserverlibrary loadable in the
449
- // browser, but it's unlikely that anyone has actually been doing that.
450
407
const lsslJs = `
451
- if (typeof module !== "undefined" && module.exports) {
452
- module.exports = require("./typescript.js");
453
- }
454
- else {
455
- throw new Error("tsserverlibrary requires CommonJS; use typescript.js instead");
456
- }
408
+ import ts from "./typescript.js";
409
+ export * from "./typescript.js";
410
+ export default ts;
457
411
` ;
458
412
459
413
const lsslDts = `
460
- import ts = require("./typescript.js");
461
- export = ts;
414
+ import ts from "./typescript.js";
415
+ export * from "./typescript.js";
416
+ export default ts;
462
417
` ;
463
418
464
419
const lsslDtsInternal = `
465
- import ts = require("./typescript.internal.js");
466
- export = ts;
420
+ import ts from "./typescript.internal.js";
421
+ export * from "./typescript.internal.js";
422
+ export default ts;
467
423
` ;
468
424
469
425
/**
@@ -504,7 +460,7 @@ const { main: tests, watch: watchTests } = entrypointBuildTask({
504
460
description : "Builds the test infrastructure" ,
505
461
buildDeps : [ generateDiagnostics ] ,
506
462
project : "src/testRunner" ,
507
- srcEntrypoint : "./src/testRunner/_namespaces/Harness .ts" ,
463
+ srcEntrypoint : "./src/testRunner/runner .ts" ,
508
464
builtEntrypoint : "./built/local/testRunner/runner.js" ,
509
465
output : testRunner ,
510
466
mainDeps : [ generateLibs ] ,
0 commit comments