From 60ccbac427ea202c9034f70bee52d5db0c9bbcc6 Mon Sep 17 00:00:00 2001 From: Spencer Date: Fri, 10 Aug 2018 13:55:41 -0700 Subject: [PATCH] [build/ts] transpile public code with webpack-specific ts config (#21865) Right now the build process is running TypeScript code through a single transpilation process which produces the JS code that ships with the distributable. This process causes problems because when running the optimizer from source we use a slightly different config https://github.com/elastic/kibana/blob/33c6ade75631fb3f56816bc134dff83d08f4f387/src/optimize/base_optimizer.js#L312-L313, which instructs typescript to build modules using ESM, which webpack understands, but in the build we transpile this TypeScript to commonjs, which does not support features that are important to the strategy we are using to maintain BWC with the legacy platform as we migrate to the new platform. This implements a `tsconfig.browser.json` file at the root of the repository that extends the default `tsconfig.json` file and includes a `src/**/public/**/*` code, which the root `tsconfig.json` file now excludes. This new config file is added to the list of projects that we lint, is shared with webpack, and is built along with the default project in the build process to create JS code that uses esm for webpack to consume. --- src/dev/build/tasks/clean_tasks.js | 2 +- src/dev/build/tasks/copy_source_task.js | 2 +- .../build/tasks/transpile_typescript_task.js | 29 ++++++++++++------- src/dev/jest/ts_transform.ts | 12 +++++++- src/dev/typescript/project.ts | 4 +-- src/dev/typescript/projects.ts | 12 +++++--- src/optimize/base_optimizer.js | 3 +- tsconfig.browser.json | 13 +++++++++ tsconfig.json | 3 +- 9 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 tsconfig.browser.json diff --git a/src/dev/build/tasks/clean_tasks.js b/src/dev/build/tasks/clean_tasks.js index e2c861545e7fa..861cac63000e3 100644 --- a/src/dev/build/tasks/clean_tasks.js +++ b/src/dev/build/tasks/clean_tasks.js @@ -50,7 +50,7 @@ export const CleanTypescriptTask = { async run(config, log, build) { await deleteAll(log, [ build.resolvePath('**/*.{ts,tsx,d.ts}'), - build.resolvePath('**/tsconfig.json'), + build.resolvePath('**/tsconfig*.json'), ]); }, }; diff --git a/src/dev/build/tasks/copy_source_task.js b/src/dev/build/tasks/copy_source_task.js index b7e04a79df61c..04bf144b5652b 100644 --- a/src/dev/build/tasks/copy_source_task.js +++ b/src/dev/build/tasks/copy_source_task.js @@ -42,7 +42,7 @@ export const CopySourceTask = { 'bin/**', 'webpackShims/**', 'config/kibana.yml', - 'tsconfig.json', + 'tsconfig*.json', ], }); }, diff --git a/src/dev/build/tasks/transpile_typescript_task.js b/src/dev/build/tasks/transpile_typescript_task.js index 1ab545d422bfa..43d554dc98ed4 100644 --- a/src/dev/build/tasks/transpile_typescript_task.js +++ b/src/dev/build/tasks/transpile_typescript_task.js @@ -23,15 +23,24 @@ export const TranspileTypescriptTask = { description: 'Transpiling sources with typescript compiler', async run(config, log, build) { - await exec( - log, - require.resolve('typescript/bin/tsc'), - [ - '--pretty', 'true' - ], - { - cwd: build.resolvePath(), - } - ); + const tsConfigPaths = [ + build.resolvePath('tsconfig.json'), + build.resolvePath('tsconfig.browser.json') + ]; + + for (const tsConfigPath of tsConfigPaths) { + log.info(`Compiling`, tsConfigPath, 'project'); + await exec( + log, + require.resolve('typescript/bin/tsc'), + [ + '--pretty', 'true', + '--project', tsConfigPath, + ], + { + cwd: build.resolvePath(), + } + ); + } }, }; diff --git a/src/dev/jest/ts_transform.ts b/src/dev/jest/ts_transform.ts index 62bf957f3f4fd..60f0b11ec94a4 100644 --- a/src/dev/jest/ts_transform.ts +++ b/src/dev/jest/ts_transform.ts @@ -22,19 +22,29 @@ import { JestConfig, TransformOptions } from 'ts-jest/dist/jest-types'; import { getTsProjectForAbsolutePath } from '../typescript'; +const DEFAULT_TS_CONFIG_PATH = require.resolve('../../../tsconfig.json'); +const DEFAULT_BROWSER_TS_CONFIG_PATH = require.resolve('../../../tsconfig.browser.json'); + function extendJestConfigJSON(jestConfigJSON: string, filePath: string) { const jestConfig = JSON.parse(jestConfigJSON) as JestConfig; return JSON.stringify(extendJestConfig(jestConfig, filePath)); } function extendJestConfig(jestConfig: JestConfig, filePath: string) { + let tsConfigFile = getTsProjectForAbsolutePath(filePath).tsConfigPath; + + // swap ts config file for jest tests + if (tsConfigFile === DEFAULT_BROWSER_TS_CONFIG_PATH) { + tsConfigFile = DEFAULT_TS_CONFIG_PATH; + } + return { ...jestConfig, globals: { ...(jestConfig.globals || {}), 'ts-jest': { skipBabel: true, - tsConfigFile: getTsProjectForAbsolutePath(filePath).tsConfigPath, + tsConfigFile, }, }, }; diff --git a/src/dev/typescript/project.ts b/src/dev/typescript/project.ts index 4e24e01484f9c..7f7d12fe246f0 100644 --- a/src/dev/typescript/project.ts +++ b/src/dev/typescript/project.ts @@ -57,7 +57,7 @@ export class Project { private include: IMinimatch[]; private exclude: IMinimatch[]; - constructor(public tsConfigPath: string) { + constructor(public tsConfigPath: string, name?: string) { const { files, include, exclude = [] } = parseTsConfig(tsConfigPath); if (files || !include) { @@ -67,7 +67,7 @@ export class Project { } this.directory = dirname(this.tsConfigPath); - this.name = relative(REPO_ROOT, this.directory) || basename(this.directory); + this.name = name || relative(REPO_ROOT, this.directory) || basename(this.directory); this.include = makeMatchers(this.directory, include); this.exclude = makeMatchers(this.directory, exclude); } diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts index 712f0dc82b62f..f8fc78d2b67e7 100644 --- a/src/dev/typescript/projects.ts +++ b/src/dev/typescript/projects.ts @@ -24,13 +24,17 @@ import { REPO_ROOT } from '../constants'; import { Project } from './project'; export const PROJECTS = [ - 'tsconfig.json', - 'x-pack/tsconfig.json', + new Project(resolve(REPO_ROOT, 'tsconfig.json')), + new Project(resolve(REPO_ROOT, 'tsconfig.browser.json'), 'kibana (browser)'), + new Project(resolve(REPO_ROOT, 'x-pack/tsconfig.json')), + // NOTE: using glob.sync rather than glob-all or globby // because it takes less than 10 ms, while the other modules // both took closer to 1000ms. - ...glob.sync('packages/*/tsconfig.json', { cwd: REPO_ROOT }), -].map(path => new Project(resolve(REPO_ROOT, path))); + ...glob + .sync('packages/*/tsconfig.json', { cwd: REPO_ROOT }) + .map(path => new Project(resolve(REPO_ROOT, path))), +]; export function filterProjectsByFlag(projectFlag?: string) { if (!projectFlag) { diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js index b82b50f6ff5b1..3956b951f3d6d 100644 --- a/src/optimize/base_optimizer.js +++ b/src/optimize/base_optimizer.js @@ -307,10 +307,9 @@ export default class BaseOptimizer { transpileOnly: true, experimentalWatchApi: true, onlyCompileBundledFiles: true, + configFile: fromRoot('tsconfig.browser.json'), compilerOptions: { sourceMap: Boolean(this.sourceMaps), - target: 'es5', - module: 'esnext', } } } diff --git a/tsconfig.browser.json b/tsconfig.browser.json new file mode 100644 index 0000000000000..d5cf1d99df90c --- /dev/null +++ b/tsconfig.browser.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "target": "es5", + "module": "esnext", + }, + "include": [ + "src/**/public/**/*" + ], + "exclude": [ + "src/**/__fixtures__/**/*" + ] +} diff --git a/tsconfig.json b/tsconfig.json index 663fd48239dd0..892b22e13dddf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -48,6 +48,7 @@ "src/**/*" ], "exclude": [ - "src/**/__fixtures__/**/*" + "src/**/__fixtures__/**/*", + "src/**/public/**/*" ] }