11// @ts -check
22import { CancelToken } from "@esfx/canceltoken" ;
3- import assert from "assert" ;
43import chalk from "chalk" ;
54import chokidar from "chokidar" ;
65import esbuild from "esbuild" ;
@@ -172,25 +171,22 @@ async function runDtsBundler(entrypoint, output) {
172171 * @param {BundlerTaskOptions } [taskOptions]
173172 *
174173 * @typedef BundlerTaskOptions
175- * @property {boolean } [exportIsTsObject]
176174 * @property {boolean } [treeShaking]
177175 * @property {boolean } [usePublicAPI]
178176 * @property {() => void } [onWatchRebuild]
179177 */
180178function createBundler ( entrypoint , outfile , taskOptions = { } ) {
181179 const getOptions = memoize ( async ( ) => {
182180 const copyright = await getCopyrightHeader ( ) ;
183- const banner = taskOptions . exportIsTsObject ? "var ts = {}; ((module) => {" : "" ;
184-
185181 /** @type {esbuild.BuildOptions } */
186182 const options = {
187183 entryPoints : [ entrypoint ] ,
188- banner : { js : copyright + banner } ,
184+ banner : { js : copyright } ,
189185 bundle : true ,
190186 outfile,
191187 platform : "node" ,
192188 target : [ "es2020" , "node14.17" ] ,
193- format : "cjs " ,
189+ format : "esm " ,
194190 sourcemap : "linked" ,
195191 sourcesContent : false ,
196192 treeShaking : taskOptions . treeShaking ,
@@ -200,66 +196,17 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
200196 } ;
201197
202198 if ( taskOptions . usePublicAPI ) {
203- options . external = [ "./typescript.js" ] ;
204199 options . plugins = options . plugins || [ ] ;
205200 options . plugins . push ( {
206- name : "remap-typescript-to-require " ,
201+ name : "remap-typescript-to-public-api " ,
207202 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 } ;
210205 } ) ;
211206 } ,
212207 } ) ;
213208 }
214209
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 : `})({ get exports() { return ts; }, set exports(v) { ts = v; if (typeof module !== "undefined" && module.exports) { module.exports = v; } } })` } ;
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-
263210 return options ;
264211 } ) ;
265212
@@ -304,6 +251,7 @@ let printedWatchWarning = false;
304251 * @param {string } options.builtEntrypoint
305252 * @param {string } options.output
306253 * @param {Task[] } [options.mainDeps]
254+ * @param {boolean } [options.reexportDefault]
307255 * @param {BundlerTaskOptions } [options.bundlerOptions]
308256 */
309257function entrypointBuildTask ( options ) {
@@ -324,22 +272,33 @@ function entrypointBuildTask(options) {
324272 } ) ;
325273
326274 /**
327- * Writes a CJS module that reexports another CJS file. E.g. given
275+ * Writes a module that reexports another file. E.g. given
328276 * `options.builtEntrypoint = "./built/local/tsc/tsc.js"` and
329277 * `options.output = "./built/local/tsc.js"`, this will create a file
330278 * named "./built/local/tsc.js" containing:
331279 *
332280 * ```
333- * module.exports = require( "./tsc/tsc.js")
281+ * export * from "./tsc/tsc.js";
334282 * ```
335283 */
336284 const shim = task ( {
337285 name : `shim-${ options . name } ` ,
338286 run : async ( ) => {
339287 const outDir = path . dirname ( options . output ) ;
340288 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" ) ;
343302 } ,
344303 } ) ;
345304
@@ -404,7 +363,7 @@ const { main: services, build: buildServices, watch: watchServices } = entrypoin
404363 builtEntrypoint : "./built/local/typescript/typescript.js" ,
405364 output : "./built/local/typescript.js" ,
406365 mainDeps : [ generateLibs ] ,
407- bundlerOptions : { exportIsTsObject : true } ,
366+ reexportDefault : true ,
408367} ) ;
409368export { services , watchServices } ;
410369
@@ -445,25 +404,22 @@ export const watchMin = task({
445404 dependencies : [ watchTsc , watchTsserver ] ,
446405} ) ;
447406
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.
450407const 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;
457411` ;
458412
459413const 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;
462417` ;
463418
464419const 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;
467423` ;
468424
469425/**
@@ -504,7 +460,7 @@ const { main: tests, watch: watchTests } = entrypointBuildTask({
504460 description : "Builds the test infrastructure" ,
505461 buildDeps : [ generateDiagnostics ] ,
506462 project : "src/testRunner" ,
507- srcEntrypoint : "./src/testRunner/_namespaces/Harness .ts" ,
463+ srcEntrypoint : "./src/testRunner/runner .ts" ,
508464 builtEntrypoint : "./built/local/testRunner/runner.js" ,
509465 output : testRunner ,
510466 mainDeps : [ generateLibs ] ,
0 commit comments