fuse-box
Version:
Fuse-Box a bundler that does it right
117 lines (102 loc) • 4.44 kB
text/typescript
import { WorkFlowContext } from "./WorkflowContext";
import * as path from "path";
import { ensureUserPath, findFileBackwards } from "../Utils";
import { ScriptTarget } from "./File";
import * as fs from "fs";
import { Config } from "../Config";
const CACHED: { [path: string]: any } = {};
export class TypescriptConfig {
// the actual typescript config
private config: any;
private customTsConfig: string;
constructor(public context: WorkFlowContext) { }
public getConfig() {
this.read();
return this.config;
}
private defaultSetup() {
const compilerOptions = this.config.compilerOptions = this.config.compilerOptions || {};
if (this.context.useSourceMaps) {
compilerOptions.sourceMap = true;
compilerOptions.inlineSources = true;
}
if (this.context.forcedLanguageLevel) {
this.forceCompilerTarget(this.context.forcedLanguageLevel);
}
}
public forceCompilerTarget(level: ScriptTarget) {
this.context.log.echoInfo(`Typescript forced script target: ${ScriptTarget[level]}`)
const compilerOptions = this.config.compilerOptions = this.config.compilerOptions || {};
compilerOptions.target = ScriptTarget[level];
}
public setConfigFile(customTsConfig: string) {
this.customTsConfig = customTsConfig;
}
private initializeConfig() {
const compilerOptions = this.config.compilerOptions;
compilerOptions.jsx = "react";
compilerOptions.importHelpers = true;
compilerOptions.emitDecoratorMetadata = true;
compilerOptions.experimentalDecorators = true;
const targetFile = path.join(this.context.homeDir, "tsconfig.json");
this.context.log.echoInfo(`Generating recommended tsconfig.json: ${targetFile}`);
fs.writeFileSync(targetFile, JSON.stringify(this.config, null, 2));
}
private verifyTsLib() {
if (this.config.compilerOptions.importHelpers === true) {
const tslibPath = path.join(Config.NODE_MODULES_DIR, "tslib");
if (!fs.existsSync(tslibPath)) {
this.context.log.echoWarning(`You have enabled importHelpers. Please install tslib - https://github.com/Microsoft/tslib`)
}
}
}
public read() {
const cacheKey = (typeof this.customTsConfig === "string" ? this.customTsConfig : this.context.homeDir)
+ this.context.target + this.context.languageLevel;
if (CACHED[cacheKey]) {
this.config = CACHED[cacheKey];
} else {
let url, configFile;
let config: any = {
compilerOptions: {},
};;
let configFileFound = false;
let tsConfigOverride: any;
if (typeof this.customTsConfig === "string") {
configFile = ensureUserPath(this.customTsConfig);
} else {
url = path.join(this.context.homeDir, "tsconfig.json");
let tsconfig = findFileBackwards(url, this.context.appRoot);
if (tsconfig) {
configFileFound = true;
configFile = tsconfig;
}
}
if (configFile) {
this.context.log.echoInfo(`Typescript config file: ${configFile.replace(this.context.appRoot, "")}`);
configFileFound = true;
config = require(configFile);
}
if (Array.isArray(this.customTsConfig)) {
tsConfigOverride = this.customTsConfig[0];
}
config.compilerOptions.module = "commonjs";
if (!('target' in config.compilerOptions)) {
config.compilerOptions.target = ScriptTarget[this.context.languageLevel];
}
if (tsConfigOverride) {
config.compilerOptions = Object.assign(config.compilerOptions, tsConfigOverride);
}
this.config = config;
this.defaultSetup();
if (!configFileFound && this.context.ensureTsConfig === true) {
this.initializeConfig();
}
if (this.context.ensureTsConfig === true) {
this.verifyTsLib();
}
this.context.log.echoInfo(`Typescript script target: ${config.compilerOptions.target}`)
CACHED[cacheKey] = this.config;
}
}
}