1
1
// @ts -check
2
- import path from "path" ;
3
- import fs from "fs" ;
2
+ import { CancelToken } from "@esfx/canceltoken" ;
3
+ import chalk from "chalk" ;
4
+ import chokidar from "chokidar" ;
4
5
import del from "del" ;
5
- import { task } from "hereby" ;
6
+ import esbuild from "esbuild" ;
7
+ import { EventEmitter } from "events" ;
8
+ import fs from "fs" ;
9
+ import fsExtra from "fs-extra" ;
6
10
import _glob from "glob" ;
11
+ import { task } from "hereby" ;
12
+ import path from "path" ;
7
13
import util from "util" ;
8
- import chalk from "chalk" ;
9
- import { Debouncer , Deferred , exec , getDiffTool , getDirSize , memoize , needsUpdate , readJson } from "./scripts/build/utils.mjs" ;
10
- import { localBaseline , localRwcBaseline , refBaseline , refRwcBaseline , runConsoleTests } from "./scripts/build/tests.mjs" ;
11
- import { buildProject , cleanProject , watchProject } from "./scripts/build/projects.mjs" ;
14
+
12
15
import { localizationDirectories } from "./scripts/build/localization.mjs" ;
13
16
import cmdLineOptions from "./scripts/build/options.mjs" ;
14
- import esbuild from "esbuild" ;
15
- import chokidar from "chokidar" ;
16
- import { EventEmitter } from "events" ;
17
- import { CancelToken } from "@esfx/canceltoken" ;
17
+ import { buildProject , cleanProject , watchProject } from "./scripts/build/projects.mjs" ;
18
+ import { localBaseline , localRwcBaseline , refBaseline , refRwcBaseline , runConsoleTests } from "./scripts/build/tests.mjs" ;
19
+ import { Debouncer , Deferred , exec , getDiffTool , getDirSize , memoize , needsUpdate , readJson } from "./scripts/build/utils.mjs" ;
18
20
19
21
const glob = util . promisify ( _glob ) ;
20
22
@@ -58,10 +60,7 @@ export const generateLibs = task({
58
60
59
61
for ( const source of lib . sources ) {
60
62
const contents = await fs . promises . readFile ( source , "utf-8" ) ;
61
- // TODO(jakebailey): "\n\n" is for compatibility with our current tests; our test baselines
62
- // are sensitive to the positions of things in the lib files. Eventually remove this,
63
- // or remove lib.d.ts line numbers from our baselines.
64
- output += "\n\n" + contents . replace ( / \r \n / g, "\n" ) ;
63
+ output += "\n" + contents . replace ( / \r \n / g, "\n" ) ;
65
64
}
66
65
67
66
await fs . promises . writeFile ( lib . target , output ) ;
@@ -160,10 +159,9 @@ async function runDtsBundler(entrypoint, output) {
160
159
* @param {BundlerTaskOptions } [taskOptions]
161
160
*
162
161
* @typedef BundlerTaskOptions
163
- * @property {string[] } [external]
164
162
* @property {boolean } [exportIsTsObject]
165
163
* @property {boolean } [treeShaking]
166
- * @property {esbuild.WatchMode } [watchMode ]
164
+ * @property {() => void } [onWatchRebuild ]
167
165
*/
168
166
function createBundler ( entrypoint , outfile , taskOptions = { } ) {
169
167
const getOptions = memoize ( async ( ) => {
@@ -179,53 +177,9 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
179
177
sourcemap : "linked" ,
180
178
sourcesContent : false ,
181
179
treeShaking : taskOptions . treeShaking ,
182
- external : [
183
- ...( taskOptions . external ?? [ ] ) ,
184
- "source-map-support" ,
185
- ] ,
180
+ packages : "external" ,
186
181
logLevel : "warning" ,
187
182
// legalComments: "none", // If we add copyright headers to the source files, uncomment.
188
- plugins : [
189
- {
190
- name : "no-node-modules" ,
191
- setup : ( build ) => {
192
- build . onLoad ( { filter : / [ \\ / ] n o d e _ m o d u l e s [ \\ / ] / } , ( ) => {
193
- // Ideally, we'd use "--external:./node_modules/*" here, but that doesn't work; we
194
- // will instead end up with paths to node_modules rather than the package names.
195
- // Instead, we'll return a load error when we see that we're trying to bundle from
196
- // node_modules, then explicitly declare which external dependencies we rely on, which
197
- // ensures that the correct module specifier is kept in the output (the non-wildcard
198
- // form works properly). It also helps us keep tabs on what external dependencies we
199
- // may be importing, which is handy.
200
- //
201
- // See: https://github.com/evanw/esbuild/issues/1958
202
- return {
203
- errors : [ { text : 'Attempted to bundle from node_modules; ensure "external" is set correctly.' } ]
204
- } ;
205
- } ) ;
206
- }
207
- } ,
208
- {
209
- name : "fix-require" ,
210
- setup : ( build ) => {
211
- build . onEnd ( async ( ) => {
212
- // esbuild converts calls to "require" to "__require"; this function
213
- // calls the real require if it exists, or throws if it does not (rather than
214
- // throwing an error like "require not defined"). But, since we want typescript
215
- // to be consumable by other bundlers, we need to convert these calls back to
216
- // require so our imports are visible again.
217
- //
218
- // The leading spaces are to keep the offsets the same within the files to keep
219
- // source maps working (though this only really matters for the line the require is on).
220
- //
221
- // See: https://github.com/evanw/esbuild/issues/1905
222
- let contents = await fs . promises . readFile ( outfile , "utf-8" ) ;
223
- contents = contents . replace ( / _ _ r e q u i r e \( / g, " require(" ) ;
224
- await fs . promises . writeFile ( outfile , contents ) ;
225
- } ) ;
226
- } ,
227
- }
228
- ]
229
183
} ;
230
184
231
185
if ( taskOptions . exportIsTsObject ) {
@@ -235,14 +189,61 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
235
189
options . globalName = "ts" ;
236
190
// If we are in a CJS context, export the ts namespace.
237
191
options . footer = { js : `\nif (typeof module !== "undefined" && module.exports) { module.exports = ts; }` } ;
192
+
193
+ // esbuild converts calls to "require" to "__require"; this function
194
+ // calls the real require if it exists, or throws if it does not (rather than
195
+ // throwing an error like "require not defined"). But, since we want typescript
196
+ // to be consumable by other bundlers, we need to convert these calls back to
197
+ // require so our imports are visible again.
198
+ //
199
+ // The leading spaces are to keep the offsets the same within the files to keep
200
+ // source maps working (though this only really matters for the line the require is on).
201
+ //
202
+ // See: https://github.com/evanw/esbuild/issues/1905
203
+ options . define = { require : "$$require" } ;
204
+ options . plugins = [
205
+ {
206
+ name : "fix-require" ,
207
+ setup : ( build ) => {
208
+ build . onEnd ( async ( ) => {
209
+ let contents = await fs . promises . readFile ( outfile , "utf-8" ) ;
210
+ contents = contents . replace ( / \$ \$ r e q u i r e / g, " require" ) ;
211
+ await fs . promises . writeFile ( outfile , contents ) ;
212
+ } ) ;
213
+ } ,
214
+ }
215
+ ] ;
238
216
}
239
217
240
218
return options ;
241
219
} ) ;
242
220
243
221
return {
244
222
build : async ( ) => esbuild . build ( await getOptions ( ) ) ,
245
- watch : async ( ) => esbuild . build ( { ...await getOptions ( ) , watch : taskOptions . watchMode ?? true , logLevel : "info" } ) ,
223
+ watch : async ( ) => {
224
+ /** @type {esbuild.BuildOptions } */
225
+ const options = { ...await getOptions ( ) , logLevel : "info" } ;
226
+ if ( taskOptions . onWatchRebuild ) {
227
+ const onRebuild = taskOptions . onWatchRebuild ;
228
+ options . plugins = ( options . plugins ?. slice ( 0 ) ?? [ ] ) . concat ( [ {
229
+ name : "watch" ,
230
+ setup : ( build ) => {
231
+ let firstBuild = true ;
232
+ build . onEnd ( ( ) => {
233
+ if ( firstBuild ) {
234
+ firstBuild = false ;
235
+ }
236
+ else {
237
+ onRebuild ( ) ;
238
+ }
239
+ } ) ;
240
+ }
241
+ } ] ) ;
242
+ }
243
+
244
+ const ctx = await esbuild . context ( options ) ;
245
+ ctx . watch ( ) ;
246
+ } ,
246
247
} ;
247
248
}
248
249
@@ -448,18 +449,8 @@ const { main: tests, watch: watchTests } = entrypointBuildTask({
448
449
bundlerOptions : {
449
450
// Ensure we never drop any dead code, which might be helpful while debugging.
450
451
treeShaking : false ,
451
- // These are directly imported via import statements and should not be bundled.
452
- external : [
453
- "chai" ,
454
- "del" ,
455
- "diff" ,
456
- "mocha" ,
457
- "ms" ,
458
- ] ,
459
- watchMode : {
460
- onRebuild ( ) {
461
- watchTestsEmitter . emit ( "rebuild" ) ;
462
- }
452
+ onWatchRebuild ( ) {
453
+ watchTestsEmitter . emit ( "rebuild" ) ;
463
454
}
464
455
} ,
465
456
} ) ;
@@ -524,6 +515,7 @@ const { main: watchGuard, watch: watchWatchGuard } = entrypointBuildTask({
524
515
export const generateTypesMap = task ( {
525
516
name : "generate-types-map" ,
526
517
run : async ( ) => {
518
+ await fs . promises . mkdir ( "./built/local" , { recursive : true } ) ;
527
519
const source = "src/server/typesMap.json" ;
528
520
const target = "built/local/typesMap.json" ;
529
521
const contents = await fs . promises . readFile ( source , "utf-8" ) ;
@@ -849,13 +841,6 @@ export const lkg = task({
849
841
dependencies : [ produceLKG ] ,
850
842
} ) ;
851
843
852
- export const generateSpec = task ( {
853
- name : "generate-spec" ,
854
- description : "Generates a Markdown version of the Language Specification" ,
855
- hiddenFromTaskList : true ,
856
- run : ( ) => exec ( "cscript" , [ "//nologo" , "scripts/word2md.mjs" , path . resolve ( "doc/TypeScript Language Specification - ARCHIVED.docx" ) , path . resolve ( "doc/spec-ARCHIVED.md" ) ] ) ,
857
- } ) ;
858
-
859
844
export const cleanBuilt = task ( {
860
845
name : "clean-built" ,
861
846
hiddenFromTaskList : true ,
@@ -892,3 +877,14 @@ export const help = task({
892
877
hiddenFromTaskList : true ,
893
878
run : ( ) => exec ( "hereby" , [ "--tasks" ] , { hidePrompt : true } ) ,
894
879
} ) ;
880
+
881
+ export const bumpLkgToNightly = task ( {
882
+ name : "bump-lkg-to-nightly" ,
883
+ description : "Bumps typescript in package.json to the latest nightly and copies it to LKG." ,
884
+ run : async ( ) => {
885
+ await exec ( "npm" , [ "install" , "--save-dev" , "--save-exact" , "typescript@next" ] ) ;
886
+ await fs . promises . rm ( "lib" , { recursive : true , force : true } ) ;
887
+ await fsExtra . copy ( "node_modules/typescript/lib" , "lib" ) ;
888
+ await fs . promises . writeFile ( "lib/.gitattributes" , "* text eol=lf" ) ;
889
+ }
890
+ } ) ;
0 commit comments