diff --git a/extensions/package.json b/extensions/package.json index a8e81d5a82..3d46e23372 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -39,5 +39,8 @@ "prettier": "2.0.5", "typescript": "^4.0.5", "validate-npm-package-name": "4.0.0" + }, + "devDependencies": { + "cross-env": "7.0.3" } } diff --git a/extensions/scripts/build.js b/extensions/scripts/build.js index 55fe6ef653..fba609b284 100644 --- a/extensions/scripts/build.js +++ b/extensions/scripts/build.js @@ -6,6 +6,41 @@ const path = require('path'); const fs = require('fs-extra'); const esbuild = require('esbuild'); const GlobalsPlugin = require('esbuild-plugin-globals'); +const ts = require('typescript'); + +const formatHost = { + getCanonicalFileName: (path) => path, + getCurrentDirectory: ts.sys.getCurrentDirectory, + getNewLine: () => ts.sys.newLine, +}; + +function typecheck(extPath) { + return new Promise((resolve, reject) => { + const tsConfigPath = ts.findConfigFile(extPath, ts.sys.fileExists, 'tsconfig.json'); + + if (tsConfigPath) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const configFile = ts.readJsonConfigFile(tsConfigPath, ts.sys.readFile); + + const { fileNames, options } = ts.parseJsonSourceFileConfigFileContent(configFile, ts.sys, extPath); + + const program = ts.createProgram(fileNames, { ...options, noEmit: true }); + const emitResult = program.emit(); + + const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); + const hasTsErrors = allDiagnostics.some((d) => d.category === ts.DiagnosticCategory.Error); + + if (hasTsErrors) { + const tsOutput = ts.formatDiagnosticsWithColorAndContext(allDiagnostics, formatHost); + + reject(new Error(`TypeScript errors:\n${tsOutput}}`)); + return; + } + } + + resolve(); + }); +} const getBundleConfigs = (extPath, packageJSON, watch = false) => { const buildConfigs = []; @@ -111,6 +146,7 @@ const compile = async (name, extPath, watch = false) => { try { await cleanDist(name, extPath); + work.push(typecheck(extPath)); for (const config of getBundleConfigs(extPath, packageJSON, watch)) { work.push(service.build(config)); } diff --git a/extensions/yarn-berry.lock b/extensions/yarn-berry.lock index 280095eb7b..2e08db61bd 100644 --- a/extensions/yarn-berry.lock +++ b/extensions/yarn-berry.lock @@ -534,6 +534,7 @@ __metadata: "@types/fs-extra": 9.0.13 "@typescript-eslint/eslint-plugin": 2.34.0 "@typescript-eslint/parser": 2.34.0 + cross-env: 7.0.3 esbuild: ^0.8.44 esbuild-plugin-globals: 0.1.1 eslint: 7.0.0 @@ -580,7 +581,19 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.2": +"cross-env@npm:7.0.3": + version: 7.0.3 + resolution: "cross-env@npm:7.0.3" + dependencies: + cross-spawn: ^7.0.1 + bin: + cross-env: src/bin/cross-env.js + cross-env-shell: src/bin/cross-env-shell.js + checksum: 26f2f3ea2ab32617f57effb70d329c2070d2f5630adc800985d8b30b56e8bf7f5f439dd3a0358b79cee6f930afc23cf8e23515f17ccfb30092c6b62c6b630a79 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: