Skip to content

Commit ee5bff0

Browse files
committed
Run typescript compiler programmatically. (Do not rely on global 'tsc'.)
1 parent 27583ef commit ee5bff0

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

Gruntfile.js

+51-5
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ const fs = require('fs');
9696
const os = require('os');
9797
const { execSync, spawnSync } = require('child_process');
9898

99+
const ts = require('typescript');
99100
const webpack = require('webpack');
100101
const TerserPlugin = require('terser-webpack-plugin');
101102
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
@@ -125,7 +126,6 @@ const BASE_DIR = __dirname;
125126
const BUILD_DIR = path.join(BASE_DIR, 'build');
126127
const BUILD_CJS_DIR = path.join(BUILD_DIR, 'cjs');
127128
const BUILD_ESM_DIR = path.join(BUILD_DIR, 'esm');
128-
const BUILD_ESM_SRC_DIR = path.join(BUILD_ESM_DIR, 'src');
129129
const BUILD_IMAGES_CURRENT_DIR = path.join(BUILD_DIR, 'images', 'current');
130130
const BUILD_IMAGES_REFERENCE_DIR = path.join(BUILD_DIR, 'images', 'reference');
131131
const REFERENCE_DIR = path.join(BASE_DIR, 'reference');
@@ -478,8 +478,9 @@ module.exports = (grunt) => {
478478
versionInfo.saveESMVersionFile();
479479
}
480480

481+
let configFile = 'tsconfig.esm.json';
482+
481483
log('ESM: Building to ./build/esm/');
482-
fs.mkdirSync(BUILD_ESM_SRC_DIR, { recursive: true });
483484
// The build/esm/ folder needs a package.json that specifies { "type": "module" }.
484485
// This indicates that all *.js files in `vexflow/build/esm/` are ES modules.
485486
fs.writeFileSync(BUILD_ESM_PACKAGE_JSON_FILE, '{\n "type": "module"\n}\n');
@@ -494,9 +495,9 @@ module.exports = (grunt) => {
494495
versionInfo.update();
495496
fixESM();
496497
});
497-
watch.start('-p', 'tsconfig.esm.json', '--noClear');
498+
watch.start('-p', configFile, '--noClear');
498499
} else {
499-
runCommand('tsc', '-p', 'tsconfig.esm.json');
500+
TypeScript.compile(configFile);
500501
fixESM();
501502
}
502503
});
@@ -505,7 +506,7 @@ module.exports = (grunt) => {
505506
// Output *.d.ts files to build/types/.
506507
grunt.registerTask('build:types', 'Use tsc to create *.d.ts files in build/types/', () => {
507508
log('Types: Building *.d.ts files in build/types/');
508-
runCommand('tsc', '-p', 'tsconfig.types.json');
509+
TypeScript.compile('tsconfig.types.json');
509510
});
510511

511512
// grunt build:docs
@@ -810,3 +811,48 @@ module.exports = (grunt) => {
810811
});
811812
});
812813
};
814+
815+
// Call tsc programmatically.
816+
class TypeScript {
817+
static reportDiagnostics(diagnostics) {
818+
diagnostics.forEach((diagnostic) => {
819+
let message = 'Error';
820+
if (diagnostic.file) {
821+
const where = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
822+
message += ' ' + diagnostic.file.fileName + ' ' + where.line + ', ' + where.character + 1;
823+
}
824+
message += ': ' + ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
825+
console.log(message);
826+
});
827+
}
828+
829+
static readConfigFile(configFileName) {
830+
const configFileText = fs.readFileSync(configFileName).toString();
831+
832+
const result = ts.parseConfigFileTextToJson(configFileName, configFileText);
833+
const configObject = result.config;
834+
if (!configObject) {
835+
TypeScript.reportDiagnostics([result.error]);
836+
process.exit(1);
837+
}
838+
839+
const configParseResult = ts.parseJsonConfigFileContent(configObject, ts.sys, path.dirname(configFileName));
840+
if (configParseResult.errors.length > 0) {
841+
TypeScript.reportDiagnostics(configParseResult.errors);
842+
process.exit(1);
843+
}
844+
return configParseResult;
845+
}
846+
847+
static compile(configFileName) {
848+
const config = TypeScript.readConfigFile(configFileName);
849+
850+
const program = ts.createProgram(config.fileNames, config.options);
851+
const emitResult = program.emit();
852+
853+
TypeScript.reportDiagnostics(ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics));
854+
855+
const exitCode = emitResult.emitSkipped ? 1 : 0;
856+
process.exit(exitCode);
857+
}
858+
}

tools/version_info.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ module.exports = {
2525

2626
// Save the build information to build/esm/src/version.js
2727
saveESMVersionFile() {
28-
const outputFile = path.join(__dirname, '..', 'build', 'esm', 'src', 'version.js');
28+
const parentDir = path.join(__dirname, '..', 'build', 'esm', 'src');
29+
const outputFile = path.join(parentDir, 'version.js');
30+
2931
const V = `export const VERSION = '${VEXFLOW_VERSION}';`;
3032
const I = `export const ID = '${GIT_COMMIT_ID}';`;
3133
const D = `export const DATE = '${DATE}';`;
3234

3335
console.log(`Writing ESM version data to ${outputFile}`);
36+
fs.mkdirSync(parentDir, { recursive: true });
3437
fs.writeFileSync(outputFile, `${V}\n${I}\n${D}`);
3538
},
3639

0 commit comments

Comments
 (0)