@@ -5,9 +5,11 @@ import * as webpack from 'webpack';
5
5
6
6
import * as constants from './constants' ;
7
7
import {
8
+ buildSolutionReferences ,
8
9
getEmitOutput ,
9
10
getInputFileNameFromOutput ,
10
11
getTypeScriptInstance ,
12
+ initializeInstance ,
11
13
isReferencedFile
12
14
} from './instances' ;
13
15
import {
@@ -44,36 +46,38 @@ function loader(this: webpack.loader.LoaderContext, contents: string) {
44
46
return ;
45
47
}
46
48
47
- return successLoader (
48
- this ,
49
- contents ,
50
- callback ,
51
- options ,
52
- instanceOrError . instance !
53
- ) ;
49
+ const instance = instanceOrError . instance ! ;
50
+ buildSolutionReferences ( instance , this , instance . log ) ;
51
+ successLoader ( this , contents , callback , instance ) ;
54
52
}
55
53
56
54
function successLoader (
57
55
loaderContext : webpack . loader . LoaderContext ,
58
56
contents : string ,
59
57
callback : webpack . loader . loaderCallback ,
60
- options : LoaderOptions ,
61
58
instance : TSInstance
62
59
) {
60
+ initializeInstance ( loaderContext , instance ) ;
63
61
const rawFilePath = path . normalize ( loaderContext . resourcePath ) ;
64
62
65
63
const filePath =
66
- options . appendTsSuffixTo . length > 0 || options . appendTsxSuffixTo . length > 0
64
+ instance . loaderOptions . appendTsSuffixTo . length > 0 ||
65
+ instance . loaderOptions . appendTsxSuffixTo . length > 0
67
66
? appendSuffixesIfMatch (
68
67
{
69
- '.ts' : options . appendTsSuffixTo ,
70
- '.tsx' : options . appendTsxSuffixTo
68
+ '.ts' : instance . loaderOptions . appendTsSuffixTo ,
69
+ '.tsx' : instance . loaderOptions . appendTsxSuffixTo
71
70
} ,
72
71
rawFilePath
73
72
)
74
73
: rawFilePath ;
75
74
76
- const fileVersion = updateFileInCache ( options , filePath , contents , instance ) ;
75
+ const fileVersion = updateFileInCache (
76
+ instance . loaderOptions ,
77
+ filePath ,
78
+ contents ,
79
+ instance
80
+ ) ;
77
81
const referencedProject = getAndCacheProjectReference ( filePath , instance ) ;
78
82
if ( referencedProject !== undefined ) {
79
83
const [ relativeProjectConfigPath , relativeFilePath ] = [
@@ -133,13 +137,12 @@ function successLoader(
133
137
filePath ,
134
138
contents ,
135
139
loaderContext ,
136
- options ,
137
140
fileVersion ,
138
141
callback ,
139
142
instance
140
143
) ;
141
144
} else {
142
- const { outputText, sourceMapText } = options . transpileOnly
145
+ const { outputText, sourceMapText } = instance . loaderOptions . transpileOnly
143
146
? getTranspilationEmit ( filePath , contents , instance , loaderContext )
144
147
: getEmit ( rawFilePath , filePath , instance , loaderContext ) ;
145
148
@@ -149,7 +152,6 @@ function successLoader(
149
152
filePath ,
150
153
contents ,
151
154
loaderContext ,
152
- options ,
153
155
fileVersion ,
154
156
callback ,
155
157
instance
@@ -163,23 +165,29 @@ function makeSourceMapAndFinish(
163
165
filePath : string ,
164
166
contents : string ,
165
167
loaderContext : webpack . loader . LoaderContext ,
166
- options : LoaderOptions ,
167
168
fileVersion : number ,
168
169
callback : webpack . loader . loaderCallback ,
169
170
instance : TSInstance
170
171
) {
171
172
if ( outputText === null || outputText === undefined ) {
173
+ setModuleMeta ( loaderContext , instance , fileVersion ) ;
172
174
const additionalGuidance = isReferencedFile ( instance , filePath )
173
175
? ' The most common cause for this is having errors when building referenced projects.'
174
- : ! options . allowTsInNodeModules && filePath . indexOf ( 'node_modules' ) !== - 1
176
+ : ! instance . loaderOptions . allowTsInNodeModules &&
177
+ filePath . indexOf ( 'node_modules' ) !== - 1
175
178
? ' By default, ts-loader will not compile .ts files in node_modules.\n' +
176
179
'You should not need to recompile .ts files there, but if you really want to, use the allowTsInNodeModules option.\n' +
177
180
'See: https://github.com/Microsoft/TypeScript/issues/12358'
178
181
: '' ;
179
182
180
- throw new Error (
181
- `TypeScript emitted no output for ${ filePath } .${ additionalGuidance } `
183
+ callback (
184
+ new Error (
185
+ `TypeScript emitted no output for ${ filePath } .${ additionalGuidance } `
186
+ ) ,
187
+ outputText ,
188
+ undefined
182
189
) ;
190
+ return ;
183
191
}
184
192
185
193
const { sourceMap, output } = makeSourceMap (
@@ -190,15 +198,25 @@ function makeSourceMapAndFinish(
190
198
loaderContext
191
199
) ;
192
200
201
+ setModuleMeta ( loaderContext , instance , fileVersion ) ;
202
+ callback ( null , output , sourceMap ) ;
203
+ }
204
+
205
+ function setModuleMeta (
206
+ loaderContext : webpack . loader . LoaderContext ,
207
+ instance : TSInstance ,
208
+ fileVersion : number
209
+ ) {
193
210
// _module.meta is not available inside happypack
194
- if ( ! options . happyPackMode && loaderContext . _module . buildMeta !== undefined ) {
211
+ if (
212
+ ! instance . loaderOptions . happyPackMode &&
213
+ loaderContext . _module . buildMeta !== undefined
214
+ ) {
195
215
// Make sure webpack is aware that even though the emitted JavaScript may be the same as
196
216
// a previously cached version the TypeScript may be different and therefore should be
197
217
// treated as new
198
218
loaderContext . _module . buildMeta . tsLoaderFileVersion = fileVersion ;
199
219
}
200
-
201
- callback ( null , output , sourceMap ) ;
202
220
}
203
221
204
222
/**
@@ -395,14 +413,15 @@ function updateFileInCache(
395
413
// it is allowed by the options.
396
414
( options . allowTsInNodeModules || filePath . indexOf ( 'node_modules' ) === - 1 )
397
415
) {
398
- instance . version ! ++ ;
416
+ instance . version ++ ;
399
417
instance . rootFileNames . add ( filePath ) ;
400
418
}
401
419
402
420
if ( file . text !== contents ) {
403
421
file . version ++ ;
404
422
file . text = contents ;
405
- instance . version ! ++ ;
423
+ file . modifiedTime = new Date ( ) ;
424
+ instance . version ++ ;
406
425
if (
407
426
( instance . watchHost !== undefined ||
408
427
instance . solutionBuilderHost !== undefined ) &&
@@ -447,73 +466,70 @@ function getEmit(
447
466
instance : TSInstance ,
448
467
loaderContext : webpack . loader . LoaderContext
449
468
) {
450
- const outputFiles = getEmitOutput (
451
- instance ,
452
- filePath ,
453
- /*skipActualOutputReadOfReferencedFile*/ false
454
- ) ;
455
-
456
- if ( ! isReferencedFile ( instance , filePath ) ) {
457
- loaderContext . clearDependencies ( ) ;
458
- loaderContext . addDependency ( rawFilePath ) ;
469
+ const outputFiles = getEmitOutput ( instance , filePath ) ;
470
+ loaderContext . clearDependencies ( ) ;
471
+ loaderContext . addDependency ( rawFilePath ) ;
459
472
460
- const allDefinitionFiles = [ ...instance . files . keys ( ) ] . filter (
461
- defFilePath =>
462
- defFilePath . match ( constants . dtsDtsxOrDtsDtsxMapRegex ) &&
463
- // Remove the project reference d.ts as we are adding dependency for .ts later
464
- // This removed extra build pass (resulting in new stats object in initial build)
465
- ( ! instance . solutionBuilderHost ||
466
- ! getInputFileNameFromOutput ( instance , defFilePath ) )
467
- ) ;
473
+ const allDefinitionFiles = isReferencedFile ( instance , filePath )
474
+ ? [ ]
475
+ : [ ...instance . files . keys ( ) ] . filter (
476
+ defFilePath =>
477
+ defFilePath . match ( constants . dtsDtsxOrDtsDtsxMapRegex ) &&
478
+ // Remove the project reference d.ts as we are adding dependency for .ts later
479
+ // This removed extra build pass (resulting in new stats object in initial build)
480
+ ( ! instance . solutionBuilderHost ||
481
+ instance . solutionBuilderHost . getOutputFileFromReferencedProject (
482
+ defFilePath
483
+ ) !== undefined )
484
+ ) ;
468
485
469
- // Make this file dependent on *all* definition files in the program
470
- const addDependency = loaderContext . addDependency . bind ( loaderContext ) ;
471
- allDefinitionFiles . forEach ( addDependency ) ;
472
-
473
- // Additionally make this file dependent on all imported files
474
- const fileDependencies = instance . dependencyGraph [ filePath ] ;
475
- const additionalDependencies =
476
- fileDependencies === undefined
477
- ? [ ]
478
- : fileDependencies . map ( ( { resolvedFileName, originalFileName } ) => {
479
- const projectReference = getAndCacheProjectReference (
486
+ // Make this file dependent on *all* definition files in the program
487
+ const addDependency = loaderContext . addDependency . bind ( loaderContext ) ;
488
+ allDefinitionFiles . forEach ( addDependency ) ;
489
+
490
+ // Additionally make this file dependent on all imported files
491
+ const fileDependencies = instance . dependencyGraph [ filePath ] ;
492
+ const additionalDependencies =
493
+ fileDependencies === undefined
494
+ ? [ ]
495
+ : fileDependencies . map ( ( { resolvedFileName, originalFileName } ) => {
496
+ const projectReference = getAndCacheProjectReference (
497
+ resolvedFileName ,
498
+ instance
499
+ ) ;
500
+ // In the case of dependencies that are part of a project reference,
501
+ // the real dependency that webpack should watch is the JS output file.
502
+ if ( projectReference !== undefined ) {
503
+ return getAndCacheOutputJSFileName (
480
504
resolvedFileName ,
505
+ projectReference ,
481
506
instance
482
507
) ;
483
- // In the case of dependencies that are part of a project reference,
484
- // the real dependency that webpack should watch is the JS output file.
485
- if ( projectReference !== undefined ) {
486
- return getAndCacheOutputJSFileName (
487
- resolvedFileName ,
488
- projectReference ,
489
- instance
490
- ) ;
491
- }
492
- return (
493
- getInputFileNameFromOutput (
494
- instance ,
495
- path . resolve ( resolvedFileName )
496
- ) || originalFileName
497
- ) ;
498
- } ) ;
499
-
500
- if ( additionalDependencies . length > 0 ) {
501
- additionalDependencies . forEach ( addDependency ) ;
502
- }
503
-
504
- loaderContext . _module . buildMeta . tsLoaderDefinitionFileVersions = allDefinitionFiles
505
- . concat ( additionalDependencies )
506
- . map (
507
- defFilePath =>
508
- defFilePath +
509
- '@' +
510
- (
511
- instance . files . get ( defFilePath ) ||
512
- instance . otherFiles . get ( defFilePath ) || { version : '?' }
513
- ) . version
514
- ) ;
508
+ }
509
+ return (
510
+ getInputFileNameFromOutput (
511
+ instance ,
512
+ path . resolve ( resolvedFileName )
513
+ ) || originalFileName
514
+ ) ;
515
+ } ) ;
516
+
517
+ if ( additionalDependencies . length > 0 ) {
518
+ additionalDependencies . forEach ( addDependency ) ;
515
519
}
516
520
521
+ loaderContext . _module . buildMeta . tsLoaderDefinitionFileVersions = allDefinitionFiles
522
+ . concat ( additionalDependencies )
523
+ . map (
524
+ defFilePath =>
525
+ defFilePath +
526
+ '@' +
527
+ (
528
+ instance . files . get ( defFilePath ) ||
529
+ instance . otherFiles . get ( defFilePath ) || { version : '?' }
530
+ ) . version
531
+ ) ;
532
+
517
533
const outputFile = outputFiles
518
534
. filter ( file => file . name . match ( constants . jsJsx ) )
519
535
. pop ( ) ;
0 commit comments