@@ -8,10 +8,10 @@ import "./ts_global.d.ts";
8
8
9
9
import { emitBundle , setRootExports } from "./bundler.ts" ;
10
10
import { bold , cyan , yellow } from "./colors.ts" ;
11
- import { CompilerOptions } from "./compiler_api.ts" ;
11
+ import { CompilerOptions , TranspileOnlyResult } from "./compiler_api.ts" ;
12
12
import { Console } from "./console.ts" ;
13
13
import { core } from "./core.ts" ;
14
- import { Diagnostic , DiagnosticItem } from "./diagnostics.ts" ;
14
+ import { Diagnostic } from "./diagnostics.ts" ;
15
15
import { fromTypeScriptDiagnostic } from "./diagnostics_util.ts" ;
16
16
import { cwd } from "./dir.ts" ;
17
17
import * as dispatch from "./dispatch.ts" ;
@@ -68,14 +68,21 @@ interface CompilerRequestRuntimeCompile {
68
68
rootName : string ;
69
69
sources ?: Record < string , string > ;
70
70
bundle : boolean ;
71
- options ?: CompilerOptions ;
71
+ options ?: string ;
72
+ }
73
+
74
+ interface CompilerRequestRuntimeTranspile {
75
+ type : CompilerRequestType . RuntimeTranspile ;
76
+ sources : Record < string , string > ;
77
+ options ?: string ;
72
78
}
73
79
74
80
/** The format of the work message payload coming from the privileged side */
75
81
type CompilerRequest =
76
82
| CompilerRequestCompile
77
83
| CompilerRequestBundle
78
- | CompilerRequestRuntimeCompile ;
84
+ | CompilerRequestRuntimeCompile
85
+ | CompilerRequestRuntimeTranspile ;
79
86
80
87
interface ConfigureResponse {
81
88
ignoredOptions ?: string [ ] ;
@@ -87,8 +94,6 @@ interface EmitResult {
87
94
diagnostics ?: Diagnostic ;
88
95
}
89
96
90
- type CompilationResult = [ DiagnosticItem [ ] | undefined , Record < string , string > ] ;
91
-
92
97
// Startup boilerplate. This is necessary because the compiler has its own
93
98
// snapshot. (It would be great if we could remove these things or centralize
94
99
// them somewhere else.)
@@ -167,6 +172,116 @@ const ignoredCompilerOptions: readonly string[] = [
167
172
"watch"
168
173
] ;
169
174
175
+ /** Default options used by the compiler Host when compiling. */
176
+ const defaultCompileOptions : ts . CompilerOptions = {
177
+ allowJs : true ,
178
+ allowNonTsExtensions : true ,
179
+ // TODO(#3324) Enable strict mode for user code.
180
+ // strict: true,
181
+ checkJs : false ,
182
+ esModuleInterop : true ,
183
+ module : ts . ModuleKind . ESNext ,
184
+ outDir : OUT_DIR ,
185
+ resolveJsonModule : true ,
186
+ sourceMap : true ,
187
+ stripComments : true ,
188
+ target : ts . ScriptTarget . ESNext ,
189
+ jsx : ts . JsxEmit . React
190
+ } ;
191
+
192
+ /** Default options used when doing a transpile only. */
193
+ const defaultTranspileOptions : ts . CompilerOptions = {
194
+ esModuleInterop : true ,
195
+ module : ts . ModuleKind . ESNext ,
196
+ sourceMap : true ,
197
+ scriptComments : true ,
198
+ target : ts . ScriptTarget . ESNext
199
+ } ;
200
+
201
+ function convertCompilerOptions ( str : string ) : ts . CompilerOptions {
202
+ const options : CompilerOptions = JSON . parse ( str ) ;
203
+ const out : Record < string , unknown > = { } ;
204
+ const keys = Object . keys ( options ) as Array < keyof CompilerOptions > ;
205
+ for ( const key of keys ) {
206
+ switch ( key ) {
207
+ case "jsx" :
208
+ const value = options [ key ] ;
209
+ if ( value === "preserve" ) {
210
+ out [ key ] = ts . JsxEmit . Preserve ;
211
+ } else if ( value === "react" ) {
212
+ out [ key ] = ts . JsxEmit . React ;
213
+ } else {
214
+ out [ key ] = ts . JsxEmit . ReactNative ;
215
+ }
216
+ break ;
217
+ case "module" :
218
+ switch ( options [ key ] ) {
219
+ case "amd" :
220
+ out [ key ] = ts . ModuleKind . AMD ;
221
+ break ;
222
+ case "commonjs" :
223
+ out [ key ] = ts . ModuleKind . CommonJS ;
224
+ break ;
225
+ case "es2015" :
226
+ case "es6" :
227
+ out [ key ] = ts . ModuleKind . ES2015 ;
228
+ break ;
229
+ case "esnext" :
230
+ out [ key ] = ts . ModuleKind . ESNext ;
231
+ break ;
232
+ case "none" :
233
+ out [ key ] = ts . ModuleKind . None ;
234
+ break ;
235
+ case "system" :
236
+ out [ key ] = ts . ModuleKind . System ;
237
+ break ;
238
+ case "umd" :
239
+ out [ key ] = ts . ModuleKind . UMD ;
240
+ break ;
241
+ default :
242
+ throw new TypeError ( "Unexpected module type" ) ;
243
+ }
244
+ break ;
245
+ case "target" :
246
+ switch ( options [ key ] ) {
247
+ case "es3" :
248
+ out [ key ] = ts . ScriptTarget . ES3 ;
249
+ break ;
250
+ case "es5" :
251
+ out [ key ] = ts . ScriptTarget . ES5 ;
252
+ break ;
253
+ case "es6" :
254
+ case "es2015" :
255
+ out [ key ] = ts . ScriptTarget . ES2015 ;
256
+ break ;
257
+ case "es2016" :
258
+ out [ key ] = ts . ScriptTarget . ES2016 ;
259
+ break ;
260
+ case "es2017" :
261
+ out [ key ] = ts . ScriptTarget . ES2017 ;
262
+ break ;
263
+ case "es2018" :
264
+ out [ key ] = ts . ScriptTarget . ES2018 ;
265
+ break ;
266
+ case "es2019" :
267
+ out [ key ] = ts . ScriptTarget . ES2019 ;
268
+ break ;
269
+ case "es2020" :
270
+ out [ key ] = ts . ScriptTarget . ES2020 ;
271
+ break ;
272
+ case "esnext" :
273
+ out [ key ] = ts . ScriptTarget . ESNext ;
274
+ break ;
275
+ default :
276
+ throw new TypeError ( "Unexpected emit target." ) ;
277
+ }
278
+ default :
279
+ out [ key ] = options [ key ] ;
280
+ }
281
+ }
282
+ return out as ts . CompilerOptions ;
283
+ }
284
+
170
285
/** An array of TypeScript diagnostic types we ignore. */
171
286
const ignoredDiagnostics = [
172
287
// TS1103: 'for-await-of' statement is only allowed within an async function
@@ -312,6 +427,11 @@ class SourceFile {
312
427
}
313
428
}
314
429
430
+ function resolveModules ( specifiers : string [ ] , referrer ?: string ) : string [ ] {
431
+ util . log ( "compiler::resolveModules" , { specifiers, referrer } ) ;
432
+ return sendSync ( dispatch . OP_RESOLVE_MODULES , { specifiers, referrer } ) ;
433
+ }
434
+
315
435
/** Ops to Rust to resolve special static assets. */
316
436
function fetchAsset ( name : string ) : string {
317
437
return sendSync ( dispatch . OP_FETCH_ASSET , { name } ) ;
@@ -400,7 +520,8 @@ async function processImports(
400
520
return [ ] ;
401
521
}
402
522
const sources = specifiers . map ( ( [ , moduleSpecifier ] ) => moduleSpecifier ) ;
403
- const sourceFiles = await fetchSourceFiles ( sources , referrer ) ;
523
+ const resolveSources = resolveModules ( sources , referrer ) ;
524
+ const sourceFiles = await fetchSourceFiles ( resolveSources , referrer ) ;
404
525
assert ( sourceFiles . length === specifiers . length ) ;
405
526
for ( let i = 0 ; i < sourceFiles . length ; i ++ ) {
406
527
const sourceFileJson = sourceFiles [ i ] ;
@@ -457,21 +578,7 @@ class Host implements ts.CompilerHost {
457
578
private _requestType : CompilerRequestType ;
458
579
private _rootNames : string [ ] ;
459
580
460
- private readonly _options : ts . CompilerOptions = {
461
- allowJs : true ,
462
- allowNonTsExtensions : true ,
463
- // TODO(#3324) Enable strict mode for user code.
464
- // strict: true,
465
- checkJs : false ,
466
- esModuleInterop : true ,
467
- module : ts . ModuleKind . ESNext ,
468
- outDir : OUT_DIR ,
469
- resolveJsonModule : true ,
470
- sourceMap : true ,
471
- stripComments : true ,
472
- target : ts . ScriptTarget . ESNext ,
473
- jsx : ts . JsxEmit . React
474
- } ;
581
+ private readonly _options = defaultCompileOptions ;
475
582
476
583
private _getAsset ( filename : string ) : SourceFile {
477
584
const sourceFile = SourceFile . get ( filename ) ;
@@ -804,16 +911,20 @@ self.compilerMain = function compilerMain(): void {
804
911
break ;
805
912
}
806
913
case CompilerRequestType . RuntimeCompile : {
807
- const { rootName, sources } = request ;
914
+ const { rootName, sources, options } = request ;
808
915
809
916
util . log ( ">>> runtime compile start" , {
810
917
rootName,
811
918
sources : sources ? Object . keys ( sources ) : undefined
812
919
} ) ;
813
920
921
+ const resolvedRootName = sources
922
+ ? rootName
923
+ : resolveModules ( [ rootName ] ) [ 0 ] ;
924
+
814
925
const rootNames = sources
815
- ? processLocalImports ( sources , [ [ rootName , rootName ] ] )
816
- : await processImports ( [ [ rootName , rootName ] ] ) ;
926
+ ? processLocalImports ( sources , [ [ resolvedRootName , resolvedRootName ] ] )
927
+ : await processImports ( [ [ resolvedRootName , resolvedRootName ] ] ) ;
817
928
818
929
const emitMap : Record < string , string > = { } ;
819
930
@@ -826,10 +937,20 @@ self.compilerMain = function compilerMain(): void {
826
937
cache : sources ? false : true
827
938
} ) ;
828
939
829
- host . configure ( { outDir : undefined } ) ;
940
+ const compilerOptions = options
941
+ ? Object . assign (
942
+ { } ,
943
+ { outDir : undefined } ,
944
+ convertCompilerOptions ( options )
945
+ )
946
+ : { outDir : undefined } ;
947
+ host . configure ( compilerOptions ) ;
830
948
831
- const options = host . getCompilationSettings ( ) ;
832
- const program = ts . createProgram ( rootNames , options , host ) ;
949
+ const program = ts . createProgram (
950
+ rootNames ,
951
+ host . getCompilationSettings ( ) ,
952
+ host
953
+ ) ;
833
954
834
955
const diagnostics = ts
835
956
. getPreEmitDiagnostics ( program )
@@ -852,6 +973,30 @@ self.compilerMain = function compilerMain(): void {
852
973
853
974
break ;
854
975
}
976
+ case CompilerRequestType . RuntimeTranspile : {
977
+ const result : Record < string , TranspileOnlyResult > = { } ;
978
+ const { sources, options } = request ;
979
+ const compilerOptions = options
980
+ ? Object . assign (
981
+ { } ,
982
+ defaultTranspileOptions ,
983
+ convertCompilerOptions ( options )
984
+ )
985
+ : defaultTranspileOptions ;
986
+ for ( const [ fileName , inputText ] of Object . entries ( sources ) ) {
987
+ const { outputText : source , sourceMapText : map } = ts . transpileModule (
988
+ inputText ,
989
+ {
990
+ fileName,
991
+ compilerOptions
992
+ }
993
+ ) ;
994
+ result [ fileName ] = { source, map } ;
995
+ postMessage ( result ) ;
996
+ }
997
+
998
+ break ;
999
+ }
855
1000
default :
856
1001
util . log (
857
1002
`!!! unhandled CompilerRequestType: ${
0 commit comments