/
build.ts
123 lines (105 loc) · 3.42 KB
/
build.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env node
import * as fs from "fs";
import * as path from "path";
import * as ts from "typescript";
import * as tsickle from "tsickle";
let projectDir = "./";
function loadConfig() {
let configFile = ts.findConfigFile(projectDir, fs.existsSync);
if (configFile) {
let { config, error: readError } = ts.readConfigFile(configFile, (path) =>
fs.readFileSync(path, "utf-8")
);
if (readError) {
throw new Error("An error occurred");
}
return ts.parseJsonConfigFileContent(config, ts.sys, projectDir);
}
}
function toClosureJS(
options: ts.CompilerOptions,
fileNames: string[],
writeFile: ts.WriteFileCallback
): tsickle.EmitResult {
let absoluteFileNames = fileNames.map((i) => path.resolve(i));
let compilerHost = ts.createCompilerHost(options);
let program = ts.createProgram(absoluteFileNames, options, compilerHost);
let filesToProcess = new Set(absoluteFileNames);
let rootModulePath = projectDir;
let transformerHost: tsickle.TsickleHost = {
shouldSkipTsickleProcessing: (fileName: string) => {
return !filesToProcess.has(path.resolve(fileName));
},
// hardcode ignore warnings to false for now
shouldIgnoreWarningsForPath: (fileName: string) => false,
pathToModuleName: (context, fileName) => {
// hacky way of renaming stuff in our project to pretty namespaces
if (fileName.endsWith("src/index.ts")) {
return "lilactown.harmony";
}
return tsickle.pathToModuleName(rootModulePath, context, fileName);
},
fileNameToModuleId: (fileName) => path.relative(rootModulePath, fileName),
es5Mode: true,
googmodule: true,
transformDecorators: true,
transformTypesToClosure: true,
typeBlackListPaths: new Set(),
untyped: false,
logWarning: (warning) =>
console.error(ts.formatDiagnostics([warning], compilerHost)),
options,
moduleResolutionHost: compilerHost,
};
const diagnostics = ts.getPreEmitDiagnostics(program);
if (diagnostics.length > 0) {
return {
diagnostics,
modulesManifest: new tsickle.ModulesManifest(),
externs: {},
emitSkipped: true,
emittedFiles: [],
};
}
return tsickle.emit(program, transformerHost, writeFile);
}
function main(): number {
const config = loadConfig();
if (config.errors.length) {
console.error(
ts.formatDiagnostics(config.errors, ts.createCompilerHost(config.options))
);
return 1;
}
if (config.options.module !== ts.ModuleKind.CommonJS) {
// This is not an upstream TypeScript diagnostic, therefore it does not go
// through the diagnostics array mechanism.
console.error(
"tsickle converts TypeScript modules to Closure modules via CommonJS internally. " +
'Set tsconfig.js "module": "commonjs"'
);
return 1;
}
// outDir needs to be an absolute path for tsickle
config.options.outDir = path.resolve(config.options.outDir);
// Run tsickle+TSC to convert inputs to Closure JS files.
const result = toClosureJS(
config.options,
config.fileNames,
(filePath: string, contents: string) => {
fs.mkdirSync(path.dirname(filePath), { recursive: true });
fs.writeFileSync(filePath, contents, { encoding: "utf-8" });
}
);
if (result.diagnostics.length) {
console.error(
ts.formatDiagnostics(
result.diagnostics,
ts.createCompilerHost(config.options)
)
);
return 1;
}
return 0;
}
process.exit(main());