Skip to content
This repository was archived by the owner on Dec 1, 2019. It is now read-only.

Commit b2f414f

Browse files
committed
feat(*): refactor tsconfig parser
1 parent 0ce6c79 commit b2f414f

File tree

7 files changed

+170
-152
lines changed

7 files changed

+170
-152
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"deasync": "^0.1.1",
3131
"loader-utils": "^0.2.6",
3232
"lodash": "^3.10.0",
33-
"object-assign": "^2.0.0"
33+
"object-assign": "^2.0.0",
34+
"tsconfig": "^2.1.1"
3435
},
3536
"devDependencies": {
3637
"babel-preset-es2015": "^6.1.2",

src/host.ts

+2-10
Original file line numberDiff line numberDiff line change
@@ -193,28 +193,20 @@ export class State {
193193
this.fileAnalyzer = new FileAnalyzer(this);
194194

195195
this.options = {};
196-
197-
objectAssign(this.options, {
198-
target: this.ts.ScriptTarget.ES5,
199-
sourceMap: true,
200-
verbose: false
201-
});
202-
196+
203197
objectAssign(this.options, options);
204198

205199
if (this.options.emitRequireType) {
206200
this.addFile(RUNTIME.fileName, RUNTIME.text);
207201
}
208-
202+
209203
if (!this.options.noLib) {
210204
if (this.options.target === this.ts.ScriptTarget.ES6 || this.options.library === 'es6') {
211205
this.addFile(this.compilerInfo.lib6.fileName, this.compilerInfo.lib6.text);
212206
} else {
213207
this.addFile(this.compilerInfo.lib5.fileName, this.compilerInfo.lib5.text);
214208
}
215209
}
216-
217-
this.updateProgram();
218210
}
219211

220212
updateProgram() {

src/index.ts

-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { ICompilerOptions, TypeScriptCompilationError, State, ICompilerInfo } fr
1111
import { IResolver, ResolutionError, createResolver } from './deps';
1212
import { findCompiledModule, cache } from './cache';
1313
import * as helpers from './helpers';
14-
import { loadLib } from './helpers';
1514
import { createChecker } from './checker';
1615
import { ICompilerInstance, IWebPack, ensureInstance } from './instance';
1716

@@ -79,7 +78,6 @@ async function compiler(webpack: IWebPack, text: string): Promise<void> {
7978

8079
try {
8180
let wasChanged = await state.fileAnalyzer.checkDependencies(resolver, fileName)
82-
8381
if (wasChanged || doUpdate) {
8482
state.updateProgram();
8583
}
@@ -164,7 +162,6 @@ async function compiler(webpack: IWebPack, text: string): Promise<void> {
164162
process.exit(1);
165163
}
166164
} catch (err) {
167-
console.log(err);
168165
callback(err, helpers.codegenErrorReport([err]));
169166
}
170167
}

src/instance.ts

+88-137
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ import * as colors from 'colors';
33
import * as fs from 'fs';
44
import * as path from 'path';
55
import * as _ from 'lodash';
6+
import * as tsconfig from 'tsconfig';
67
import { loadLib, parseOptionTarget, formatErrors } from './helpers';
78
import { ICompilerInfo } from './host';
89
import { createResolver } from './deps';
910
import { createChecker } from './checker';
11+
import { rawToTsCompilerOptions } from './tsconfig-utils';
1012

1113
let deasync = require('deasync');
1214

@@ -127,94 +129,35 @@ export function ensureInstance(webpack: IWebPack, options: ICompilerOptions, ins
127129
lib6: loadLib(lib6Path)
128130
};
129131

130-
let configFileName = tsImpl.findConfigFile(options.tsconfig || process.cwd());
131-
let configFile = null;
132-
133-
let tsConfigFiles = [];
134-
if (configFileName) {
135-
configFile = tsImpl.readConfigFile(configFileName, (path) => fs.readFileSync(path).toString());
136-
if (configFile.error) {
137-
throw configFile.error;
138-
}
139-
if (configFile.config) {
140-
_.extend(options, configFile.config.compilerOptions);
141-
_.extend(options, configFile.config.awesomeTypescriptLoaderOptions);
142-
tsConfigFiles = configFile.config.files || tsConfigFiles;
143-
}
144-
}
145-
if (typeof options.moduleResolution === "string") {
146-
var moduleTypes = {
147-
"node": tsImpl.ModuleResolutionKind.NodeJs,
148-
"classic": tsImpl.ModuleResolutionKind.Classic
149-
};
150-
options.moduleResolution = moduleTypes[options.moduleResolution];
151-
152-
}
153-
154-
if (typeof options.emitRequireType === 'undefined') {
155-
options.emitRequireType = true;
156-
} else {
157-
if (typeof options.emitRequireType === 'string') {
158-
options.emitRequireType = (<any>options.emitRequireType) === 'true'
159-
}
160-
}
161-
162-
if (typeof options.reEmitDependentFiles === 'undefined') {
163-
options.reEmitDependentFiles = false;
164-
} else {
165-
if (typeof options.reEmitDependentFiles === 'string') {
166-
options.reEmitDependentFiles = (<any>options.reEmitDependentFiles) === 'true'
167-
}
168-
}
169-
170-
if (typeof options.doTypeCheck === 'undefined') {
171-
options.doTypeCheck = true;
172-
} else {
173-
if (typeof options.doTypeCheck === 'string') {
174-
options.doTypeCheck = (<any>options.doTypeCheck) === 'true'
175-
}
132+
let configFilePath: string;
133+
let configFile: tsconfig.TSConfig;
134+
let folder = options.tsconfig || process.cwd();
135+
configFilePath = tsconfig.resolveSync(folder);
136+
if (configFilePath) {
137+
configFile = tsconfig.readFileSync(configFilePath);
176138
}
177-
178-
if (typeof options.forkChecker === 'undefined') {
179-
options.forkChecker = false;
180-
} else {
181-
if (typeof options.forkChecker === 'string') {
182-
options.forkChecker = (<any>options.forkChecker) === 'true'
139+
140+
let tsFiles: string[] = [];
141+
if (configFile) {
142+
if (configFile.compilerOptions) {
143+
_.extend(options, configFile.compilerOptions);
144+
_.extend(options, (configFile as any).awesomeTypescriptLoaderOptions);
145+
tsFiles = configFile.files;
183146
}
184147
}
185-
186-
if (typeof options.useWebpackText === 'undefined') {
187-
options.useWebpackText = false;
188-
} else {
189-
if (typeof options.useWebpackText === 'string') {
190-
options.useWebpackText = (<any>options.useWebpackText) === 'true'
191-
}
192-
}
193-
194-
if (typeof options.jsx !== 'undefined') {
195-
switch(options.jsx as any) {
196-
case 'react': options.jsx = tsImpl.JsxEmit.React; break;
197-
case 'preserve': options.jsx = tsImpl.JsxEmit.Preserve; break;
198-
}
199-
}
200-
201-
if (typeof options.externals == 'undefined') {
202-
options.externals = [];
203-
}
204-
205-
if (configFileName) {
206-
let configFilePath = path.dirname(configFileName);
207-
options.externals = options.externals.concat(
208-
tsConfigFiles
209-
.filter(file => /\.d\.ts$/.test(file))
210-
.map(file => path.resolve(configFilePath, file))
211-
)
212-
}
213-
214-
if (options.target) {
215-
options.target = parseOptionTarget(<any>options.target, tsImpl);
216-
}
217-
148+
149+
options = rawToTsCompilerOptions(options, path.dirname(configFilePath), tsImpl);
150+
151+
_.defaults(options, {
152+
externals: [],
153+
doTypeCheck: true,
154+
sourceMap: true,
155+
verbose: false,
156+
noLib: false
157+
});
158+
159+
options.externals.push.apply(options.externals, tsFiles)
160+
218161
let babelImpl: any;
219162
if (options.useBabel) {
220163
try {
@@ -251,10 +194,31 @@ export function ensureInstance(webpack: IWebPack, options: ICompilerOptions, ins
251194
let tsState = new State(options, webpack._compiler.inputFileSystem, compilerInfo, syncResolver);
252195
let compiler = (<any>webpack._compiler);
253196

197+
setupWatchRun(compiler, instanceName);
198+
199+
if (options.doTypeCheck) {
200+
setupAfterCompile(compiler, instanceName, forkChecker);
201+
}
202+
203+
return getInstanceStore(webpack._compiler)[instanceName] = {
204+
tsFlow,
205+
tsState,
206+
babelImpl,
207+
compiledFiles: {},
208+
options,
209+
externalsInvoked: false,
210+
checker: forkChecker
211+
? createChecker(compilerInfo, options)
212+
: null,
213+
cacheIdentifier
214+
}
215+
}
216+
217+
function setupWatchRun(compiler, instanceName: string) {
254218
compiler.plugin('watch-run', async function (watching, callback) {
255219
let compiler: ICompiler = watching.compiler;
256220
let resolver = createResolver(compiler.options.externals, watching.compiler.resolvers.normal.resolve);
257-
let instance: ICompilerInstance = resolveInstance(watching.compiler, instanceName);
221+
let instance = resolveInstance(watching.compiler, instanceName);
258222
let state = instance.tsState;
259223
let mtimes = watching.compiler.watchFileSystem.watcher.mtimes;
260224
let changedFiles = Object.keys(mtimes);
@@ -275,64 +239,51 @@ export function ensureInstance(webpack: IWebPack, options: ICompilerOptions, ins
275239
state.updateProgram();
276240
callback();
277241
} catch (err) {
278-
console.error(err);
242+
console.error(err.toString());
279243
callback();
280244
}
281245
});
246+
}
282247

283-
if (options.doTypeCheck) {
284-
compiler.plugin('after-compile', function(compilation, callback) {
285-
let instance: ICompilerInstance = resolveInstance(compilation.compiler, instanceName);
286-
let state = instance.tsState;
287-
288-
if (forkChecker) {
289-
let payload = {
290-
files: state.allFiles(),
291-
resolutionCache: state.host.moduleResolutionHost.resolutionCache
292-
};
293-
294-
instance.checker.send({
295-
messageType: 'compile',
296-
payload
297-
});
298-
} else {
299-
let diagnostics = state.ts.getPreEmitDiagnostics(state.program);
300-
let emitError = (err) => {
301-
if (compilation.bail) {
302-
console.error('Error in bail mode:', err);
303-
process.exit(1);
304-
}
305-
compilation.errors.push(new Error(err))
306-
};
307-
308-
let errors = formatErrors(instanceName, diagnostics);
309-
errors.forEach(emitError);
310-
}
248+
function setupAfterCompile(compiler, instanceName, forkChecker = false) {
249+
compiler.plugin('after-compile', function(compilation, callback) {
250+
let instance: ICompilerInstance = resolveInstance(compilation.compiler, instanceName);
251+
let state = instance.tsState;
311252

312-
let phantomImports = [];
313-
state.allFileNames().forEach((fileName) => {
314-
if (!instance.compiledFiles[fileName]) {
315-
phantomImports.push(fileName)
316-
}
253+
if (forkChecker) {
254+
let payload = {
255+
files: state.allFiles(),
256+
resolutionCache: state.host.moduleResolutionHost.resolutionCache
257+
};
258+
259+
instance.checker.send({
260+
messageType: 'compile',
261+
payload
317262
});
263+
} else {
264+
let diagnostics = state.ts.getPreEmitDiagnostics(state.program);
265+
let emitError = (err) => {
266+
if (compilation.bail) {
267+
console.error('Error in bail mode:', err);
268+
process.exit(1);
269+
}
270+
compilation.errors.push(new Error(err))
271+
};
318272

319-
instance.compiledFiles = {};
320-
compilation.fileDependencies.push.apply(compilation.fileDependencies, phantomImports);
321-
compilation.fileDependencies = _.uniq(compilation.fileDependencies);
322-
callback();
273+
let errors = formatErrors(instanceName, diagnostics);
274+
errors.forEach(emitError);
275+
}
276+
277+
let phantomImports = [];
278+
state.allFileNames().forEach((fileName) => {
279+
if (!instance.compiledFiles[fileName]) {
280+
phantomImports.push(fileName)
281+
}
323282
});
324-
}
325283

326-
return getInstanceStore(webpack._compiler)[instanceName] = {
327-
tsFlow,
328-
tsState,
329-
babelImpl,
330-
compiledFiles: {},
331-
options,
332-
externalsInvoked: false,
333-
checker: forkChecker
334-
? createChecker(compilerInfo, options)
335-
: null,
336-
cacheIdentifier
337-
}
284+
instance.compiledFiles = {};
285+
compilation.fileDependencies.push.apply(compilation.fileDependencies, phantomImports);
286+
compilation.fileDependencies = _.uniq(compilation.fileDependencies);
287+
callback();
288+
});
338289
}

0 commit comments

Comments
 (0)