1
- import { ICompilerOptions , ICompilerInfo , IFile } from './host' ;
1
+ import { ICompilerOptions , ICompilerInfo , IFile , SyncResolver } from './host' ;
2
+ import makeResolver from './resolver' ;
2
3
import * as colors from 'colors' ;
4
+ import * as path from 'path' ;
3
5
4
6
require ( 'babel-polyfill' ) ;
5
7
@@ -16,6 +18,7 @@ export interface IMessage {
16
18
export interface IInitPayload {
17
19
compilerOptions : ICompilerOptions ;
18
20
compilerInfo : ICompilerInfo ;
21
+ webpackOptions : any ;
19
22
}
20
23
21
24
export interface ICompilePayload {
@@ -25,6 +28,7 @@ export interface ICompilePayload {
25
28
26
29
export interface IEnv {
27
30
options ?: ICompilerOptions ;
31
+ webpackOptions ?: any ;
28
32
compiler ?: typeof ts ;
29
33
compilerInfo ?: ICompilerInfo ;
30
34
host ?: Host ;
@@ -36,7 +40,35 @@ export interface IEnv {
36
40
37
41
let env : IEnv = { } ;
38
42
43
+ export class ModuleResolutionHost implements ts . ModuleResolutionHost {
44
+ servicesHost : Host ;
45
+
46
+ constructor ( servicesHost : Host ) {
47
+ this . servicesHost = servicesHost ;
48
+ }
49
+
50
+ fileExists ( fileName : string ) {
51
+ return this . servicesHost . getScriptSnapshot ( fileName ) !== undefined ;
52
+ }
53
+
54
+ readFile ( fileName : string ) : string {
55
+ let snapshot = this . servicesHost . getScriptSnapshot ( fileName ) ;
56
+ return snapshot && snapshot . getText ( 0 , snapshot . getLength ( ) ) ;
57
+ }
58
+ }
59
+
39
60
export class Host implements ts . LanguageServiceHost {
61
+ moduleResolutionHost : ModuleResolutionHost
62
+ resolver : SyncResolver
63
+
64
+ constructor ( ) {
65
+ this . moduleResolutionHost = new ModuleResolutionHost ( this ) ;
66
+ this . resolver = makeResolver ( env . webpackOptions ) ;
67
+ }
68
+
69
+ normalizePath ( filePath : string ) : string {
70
+ return path . normalize ( filePath ) ;
71
+ }
40
72
41
73
getScriptFileNames ( ) {
42
74
return Object . keys ( env . files ) ;
@@ -71,9 +103,44 @@ export class Host implements ts.LanguageServiceHost {
71
103
let resolvedModules : ts . ResolvedModule [ ] = [ ] ;
72
104
73
105
for ( let moduleName of moduleNames ) {
74
- resolvedModules . push (
75
- env . resolutionCache [ `${ containingFile } ::${ moduleName } ` ]
76
- ) ;
106
+ let cached = env . resolutionCache [ `${ containingFile } ::${ moduleName } ` ] ;
107
+ if ( cached ) {
108
+ resolvedModules . push ( cached ) ;
109
+ } else {
110
+ let resolvedFileName : string ;
111
+ let resolvedModule : ts . ResolvedModule ;
112
+
113
+ try {
114
+ resolvedFileName = this . resolver . resolveSync (
115
+ this . normalizePath ( path . dirname ( containingFile ) ) ,
116
+ moduleName
117
+ ) ;
118
+
119
+ if ( ! resolvedFileName . match ( / \. t s x ? $ / ) ) {
120
+ resolvedFileName = null ;
121
+ }
122
+ }
123
+ catch ( e ) {
124
+ resolvedFileName = null
125
+ }
126
+
127
+ let tsResolved = env . compiler . resolveModuleName (
128
+ resolvedFileName || moduleName ,
129
+ containingFile ,
130
+ env . options ,
131
+ this . moduleResolutionHost
132
+ ) ;
133
+
134
+ if ( tsResolved . resolvedModule ) {
135
+ resolvedModule = tsResolved . resolvedModule ;
136
+ } else {
137
+ resolvedModule = {
138
+ resolvedFileName : resolvedFileName || ''
139
+ }
140
+ }
141
+
142
+ resolvedModules . push ( resolvedModule ) ;
143
+ }
77
144
}
78
145
79
146
return resolvedModules ;
@@ -92,9 +159,10 @@ export class Host implements ts.LanguageServiceHost {
92
159
93
160
function processInit ( payload : IInitPayload ) {
94
161
env . compiler = require ( payload . compilerInfo . compilerName ) ;
95
- env . host = new Host ( ) ;
96
162
env . compilerInfo = payload . compilerInfo ;
97
163
env . options = payload . compilerOptions ;
164
+ env . webpackOptions = payload . webpackOptions ;
165
+ env . host = new Host ( ) ;
98
166
env . service = env . compiler . createLanguageService ( env . host , env . compiler . createDocumentRegistry ( ) ) ;
99
167
}
100
168
0 commit comments