From 0f949fcd2614acbee50d362e2a6d26cbde9df778 Mon Sep 17 00:00:00 2001 From: Olivier Combe Date: Thu, 18 Jan 2024 16:56:47 +0100 Subject: [PATCH] feat: add tsconfigPath option for ng-packagr --- .../multi-compiler/ng-multi-compiler.ts | 4 ++- .../ng-packagr/ng-packagr.compiler.ts | 36 +++++++++++++++---- .../envs/base-env/angular-base-env.bit-env.ts | 10 +++--- .../my-angular-env/my-angular-env.bit-env.ts | 18 ++++++++++ .../my-angular-v13-env.bit-env.ts | 18 ++++++++++ .../my-angular-v14-env.bit-env.ts | 18 ++++++++++ .../my-angular-v15-env.bit-env.ts | 18 ++++++++++ .../my-angular-v16-env.bit-env.ts | 18 ++++++++++ .../my-angular-v17-env.bit-env.ts | 18 ++++++++++ .../templates/generators/ng-env/files/env.ts | 18 ++++++++++ 10 files changed, 164 insertions(+), 12 deletions(-) diff --git a/angular/devkit/compiler/multi-compiler/ng-multi-compiler.ts b/angular/devkit/compiler/multi-compiler/ng-multi-compiler.ts index 25338d61..829ca906 100644 --- a/angular/devkit/compiler/multi-compiler/ng-multi-compiler.ts +++ b/angular/devkit/compiler/multi-compiler/ng-multi-compiler.ts @@ -38,6 +38,7 @@ export interface NgMultiCompilerOptions { name?: string; ngEnvOptions: AngularEnvOptions; tsCompilerOptions?: AngularCompilerOptions; + tsconfigPath?: string; } export class NgMultiCompiler implements Compiler { @@ -208,7 +209,8 @@ export class NgMultiCompiler implements Compiler { ngEnvOptions: options.ngEnvOptions, ngPackagrModulePath, shouldCopyNonSupportedFiles, - tsCompilerOptions: options.tsCompilerOptions + tsCompilerOptions: options.tsCompilerOptions, + tsconfigPath: options.tsconfigPath })(context); let angularElementsCompiler: AngularElementsCompiler | undefined; diff --git a/angular/devkit/compiler/ng-packagr/ng-packagr.compiler.ts b/angular/devkit/compiler/ng-packagr/ng-packagr.compiler.ts index 44b1be9d..b0b736ea 100644 --- a/angular/devkit/compiler/ng-packagr/ng-packagr.compiler.ts +++ b/angular/devkit/compiler/ng-packagr/ng-packagr.compiler.ts @@ -1,4 +1,4 @@ -import { type AngularCompilerOptions, type ParsedConfiguration } from '@angular/compiler-cli'; +import type { AngularCompilerOptions, ParsedConfiguration, CompilerOptions } from '@angular/compiler-cli'; import { AngularEnvOptions, componentIsApp, @@ -24,10 +24,10 @@ import PackageJsonFile from '@teambit/legacy/dist/consumer/component/package-jso import { Logger } from '@teambit/logger'; import { Workspace } from '@teambit/workspace'; import chalk from 'chalk'; -import { mkdirsSync, outputFileSync, removeSync, readdirSync } from 'fs-extra'; +import { mkdirsSync, outputFileSync, removeSync } from 'fs-extra'; import type { NgPackageConfig } from 'ng-packagr/ng-package.schema'; import { join, posix, resolve } from 'path'; -import { Diagnostic, DiagnosticCategory, DiagnosticWithLocation } from 'typescript'; +import { Diagnostic, DiagnosticCategory, DiagnosticWithLocation, ScriptTarget } from 'typescript'; const ViewEngineTemplateError = `Cannot read property 'type' of null`; const NG_PACKAGE_JSON = 'ng-package.json'; @@ -96,6 +96,7 @@ interface NgPackagrCompilerOptions { ngPackagrModulePath?: string; ngEnvOptions: AngularEnvOptions; tsCompilerOptions?: AngularCompilerOptions; + tsconfigPath?: string; name?: string; distDir: string; distGlobPatterns: string[]; @@ -123,8 +124,8 @@ export class NgPackagrCompiler implements Compiler { public shouldCopyNonSupportedFiles: boolean, public artifactName: string, private tsCompilerOptions: AngularCompilerOptions = {}, + private tsconfigPath?: string, private nodeModulesPaths: string[] = [], - private ngEnvOptions: AngularEnvOptions ) { // eslint-disable-next-line global-require,import/no-dynamic-require this.ngPackagr = require(ngPackagrPath).ngPackagr(); @@ -315,6 +316,29 @@ export class NgPackagrCompiler implements Compiler { const componentCapsules = capsules.filter(capsule => componentIds.includes(capsule.component.id.toString())); const componentsResults: ComponentResult[] = []; + let tsCompilerOptions = this.tsCompilerOptions || {}; + if (this.tsconfigPath) { + // these options are mandatory for ngPackagr to work + const extraOptions: CompilerOptions = { + target: ScriptTarget.ES2022, + + // sourcemaps + sourceMap: false, + inlineSources: true, + inlineSourceMap: true, + + outDir: '', + declaration: true, + + // ng compiler + enableResourceInlining: true, + }; + + const { readConfiguration } = await loadEsmModule('@angular/compiler-cli'); + const tsconfigJSON = readConfiguration(this.tsconfigPath, extraOptions); + tsCompilerOptions = { ...tsCompilerOptions, ...tsconfigJSON.options }; + } + // eslint-disable-next-line no-restricted-syntax for (const capsule of componentCapsules) { const { component } = capsule; @@ -327,7 +351,7 @@ export class NgPackagrCompiler implements Compiler { // disable logger temporarily so that it doesn't mess up with ngPackagr logs this.logger.off(); // eslint-disable-next-line no-await-in-loop - await this.ngPackagrCompilation(capsule.path, capsule.path, this.tsCompilerOptions, diagnosticsReporter, componentIds, true); + await this.ngPackagrCompilation(capsule.path, capsule.path, tsCompilerOptions, diagnosticsReporter, componentIds, true); this.logger.on(); // @ts-ignore } catch (e: any) { @@ -406,8 +430,8 @@ export class NgPackagrCompiler implements Compiler { options.shouldCopyNonSupportedFiles, options.artifactName, options.tsCompilerOptions, + options.tsconfigPath, nodeModulesPaths, - options.ngEnvOptions ); }; } diff --git a/angular/envs/base-env/angular-base-env.bit-env.ts b/angular/envs/base-env/angular-base-env.bit-env.ts index a070c3cd..1cef6682 100644 --- a/angular/envs/base-env/angular-base-env.bit-env.ts +++ b/angular/envs/base-env/angular-base-env.bit-env.ts @@ -51,14 +51,14 @@ import { merge } from 'lodash'; import { AngularEnvInterface } from './angular-env.interface'; import hostDependencies from './preview/host-dependencies'; +let ngMultiCompiler: EnvHandler | undefined; + /** * a component environment built for [Angular](https://angular.io). */ export abstract class AngularBaseEnv implements AngularEnvInterface { icon = 'https://static.bit.dev/extensions-icons/angular.svg'; - private ngMultiCompiler: EnvHandler | undefined; - /** Abstract functions & properties specific to the adapter * */ abstract ngEnvOptions: AngularEnvOptions; @@ -100,12 +100,12 @@ export abstract class AngularBaseEnv implements AngularEnvInterface { * Required for making and reading dists, especially for `bit compile` */ compiler(): EnvHandler { - if (!this.ngMultiCompiler) { - this.ngMultiCompiler = NgMultiCompiler.from({ + if (!ngMultiCompiler) { + ngMultiCompiler = NgMultiCompiler.from({ ngEnvOptions: this.getNgEnvOptions() }); } - return this.ngMultiCompiler; + return ngMultiCompiler; } formatter(): EnvHandler { diff --git a/angular/examples/my-angular-env/my-angular-env.bit-env.ts b/angular/examples/my-angular-env/my-angular-env.bit-env.ts index 83d7adf5..ae706b77 100644 --- a/angular/examples/my-angular-env/my-angular-env.bit-env.ts +++ b/angular/examples/my-angular-env/my-angular-env.bit-env.ts @@ -1,5 +1,6 @@ import { AngularEnv } from '@bitdev/angular.angular-env'; import { ApplicationOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; +import { NgMultiCompiler } from '@bitdev/angular.dev-services.compiler.multi-compiler'; import { AngularPreview, BundlerProvider, @@ -13,6 +14,7 @@ import { } from '@bitdev/angular.templates.generators'; import { AngularStarter } from '@bitdev/angular.templates.starters'; import { BundlerContext, DevServerContext } from '@teambit/bundler'; +import { Compiler } from '@teambit/compiler'; import { EslintConfigWriter, ESLintLinter, EslintTask } from '@teambit/defender.eslint-linter'; import { JestTask, JestTester } from '@teambit/defender.jest-tester'; import { PrettierConfigWriter, PrettierFormatter } from '@teambit/defender.prettier-formatter'; @@ -29,6 +31,8 @@ import { ConfigWriterList } from '@teambit/workspace-config-files'; import { ESLint as ESLintLib } from 'eslint'; import hostDependencies from './preview/host-dependencies'; +let ngMultiCompiler: EnvHandler | undefined; + export class MyAngularEnv extends AngularEnv { // Name of the environment, used for friendly mentions across bit name = 'my-angular-env'; @@ -62,6 +66,20 @@ export class MyAngularEnv extends AngularEnv { }; } + /** + * Returns an instance of the compiler + * Required for making and reading dists, especially for `bit compile` + */ + compiler(): EnvHandler { + if (!ngMultiCompiler) { + ngMultiCompiler = NgMultiCompiler.from({ + ngEnvOptions: this.getNgEnvOptions(), + tsconfigPath: require.resolve('./config/tsconfig.json'), + }); + } + return ngMultiCompiler; + } + /** * The linter to use during development. * Config files would be used to validate coding standards in components. diff --git a/angular/examples/my-angular-v13-env/my-angular-v13-env.bit-env.ts b/angular/examples/my-angular-v13-env/my-angular-v13-env.bit-env.ts index f3436da0..4dade029 100644 --- a/angular/examples/my-angular-v13-env/my-angular-v13-env.bit-env.ts +++ b/angular/examples/my-angular-v13-env/my-angular-v13-env.bit-env.ts @@ -1,4 +1,5 @@ import { ApplicationOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; +import { NgMultiCompiler } from '@bitdev/angular.dev-services.compiler.multi-compiler'; import { AngularPreview, BundlerProvider, @@ -12,6 +13,7 @@ import { } from '@bitdev/angular.templates.generators'; import { AngularStarter } from '@bitdev/angular.templates.starters'; import { BundlerContext, DevServerContext } from '@teambit/bundler'; +import { Compiler } from '@teambit/compiler'; import { EslintConfigWriter, ESLintLinter, EslintTask } from '@teambit/defender.eslint-linter'; import { JestTask, JestTester } from '@teambit/defender.jest-tester'; import { PrettierConfigWriter, PrettierFormatter } from '@teambit/defender.prettier-formatter'; @@ -28,6 +30,8 @@ import { ConfigWriterList } from '@teambit/workspace-config-files'; import { ESLint as ESLintLib } from 'eslint'; import hostDependencies from './preview/host-dependencies'; +let ngMultiCompiler: EnvHandler | undefined; + export class MyAngularV13Env extends AngularV13Env { // Name of the environment, used for friendly mentions across bit name = 'my-angular-v13-env'; @@ -61,6 +65,20 @@ export class MyAngularV13Env extends AngularV13Env { }; } + /** + * Returns an instance of the compiler + * Required for making and reading dists, especially for `bit compile` + */ + compiler(): EnvHandler { + if (!ngMultiCompiler) { + ngMultiCompiler = NgMultiCompiler.from({ + ngEnvOptions: this.getNgEnvOptions(), + tsconfigPath: require.resolve('./config/tsconfig.json'), + }); + } + return ngMultiCompiler; + } + /** * The linter to use during development. * Config files would be used to validate coding standards in components. diff --git a/angular/examples/my-angular-v14-env/my-angular-v14-env.bit-env.ts b/angular/examples/my-angular-v14-env/my-angular-v14-env.bit-env.ts index 8b8a2692..49191a0c 100644 --- a/angular/examples/my-angular-v14-env/my-angular-v14-env.bit-env.ts +++ b/angular/examples/my-angular-v14-env/my-angular-v14-env.bit-env.ts @@ -1,4 +1,5 @@ import { ApplicationOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; +import { NgMultiCompiler } from '@bitdev/angular.dev-services.compiler.multi-compiler'; import { AngularPreview, BundlerProvider, @@ -13,6 +14,7 @@ import { } from '@bitdev/angular.templates.generators'; import { AngularStarter } from '@bitdev/angular.templates.starters'; import { BundlerContext, DevServerContext } from '@teambit/bundler'; +import { Compiler } from '@teambit/compiler'; import { EslintConfigWriter, ESLintLinter, EslintTask } from '@teambit/defender.eslint-linter'; import { JestTask, JestTester } from '@teambit/defender.jest-tester'; import { PrettierConfigWriter, PrettierFormatter } from '@teambit/defender.prettier-formatter'; @@ -29,6 +31,8 @@ import { ConfigWriterList } from '@teambit/workspace-config-files'; import { ESLint as ESLintLib } from 'eslint'; import hostDependencies from './preview/host-dependencies'; +let ngMultiCompiler: EnvHandler | undefined; + export class MyAngularV14Env extends AngularV14Env { // Name of the environment, used for friendly mentions across bit name = 'my-angular-v14-env'; @@ -62,6 +66,20 @@ export class MyAngularV14Env extends AngularV14Env { }; } + /** + * Returns an instance of the compiler + * Required for making and reading dists, especially for `bit compile` + */ + compiler(): EnvHandler { + if (!ngMultiCompiler) { + ngMultiCompiler = NgMultiCompiler.from({ + ngEnvOptions: this.getNgEnvOptions(), + tsconfigPath: require.resolve('./config/tsconfig.json'), + }); + } + return ngMultiCompiler; + } + /** * The linter to use during development. * Config files would be used to validate coding standards in components. diff --git a/angular/examples/my-angular-v15-env/my-angular-v15-env.bit-env.ts b/angular/examples/my-angular-v15-env/my-angular-v15-env.bit-env.ts index 62591d8d..781b8f18 100644 --- a/angular/examples/my-angular-v15-env/my-angular-v15-env.bit-env.ts +++ b/angular/examples/my-angular-v15-env/my-angular-v15-env.bit-env.ts @@ -1,4 +1,5 @@ import { ApplicationOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; +import { NgMultiCompiler } from '@bitdev/angular.dev-services.compiler.multi-compiler'; import { AngularPreview, BundlerProvider, @@ -13,6 +14,7 @@ import { } from '@bitdev/angular.templates.generators'; import { AngularStarter } from '@bitdev/angular.templates.starters'; import { BundlerContext, DevServerContext } from '@teambit/bundler'; +import { Compiler } from '@teambit/compiler'; import { EslintConfigWriter, ESLintLinter, EslintTask } from '@teambit/defender.eslint-linter'; import { JestTask, JestTester } from '@teambit/defender.jest-tester'; import { PrettierConfigWriter, PrettierFormatter } from '@teambit/defender.prettier-formatter'; @@ -29,6 +31,8 @@ import { ConfigWriterList } from '@teambit/workspace-config-files'; import { ESLint as ESLintLib } from 'eslint'; import hostDependencies from './preview/host-dependencies'; +let ngMultiCompiler: EnvHandler | undefined; + export class MyAngularV15Env extends AngularV15Env { // Name of the environment, used for friendly mentions across bit name = 'my-angular-v15-env'; @@ -62,6 +66,20 @@ export class MyAngularV15Env extends AngularV15Env { }; } + /** + * Returns an instance of the compiler + * Required for making and reading dists, especially for `bit compile` + */ + compiler(): EnvHandler { + if (!ngMultiCompiler) { + ngMultiCompiler = NgMultiCompiler.from({ + ngEnvOptions: this.getNgEnvOptions(), + tsconfigPath: require.resolve('./config/tsconfig.json'), + }); + } + return ngMultiCompiler; + } + /** * The linter to use during development. * Config files would be used to validate coding standards in components. diff --git a/angular/examples/my-angular-v16-env/my-angular-v16-env.bit-env.ts b/angular/examples/my-angular-v16-env/my-angular-v16-env.bit-env.ts index b222067c..27671a77 100644 --- a/angular/examples/my-angular-v16-env/my-angular-v16-env.bit-env.ts +++ b/angular/examples/my-angular-v16-env/my-angular-v16-env.bit-env.ts @@ -1,4 +1,5 @@ import { ApplicationOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; +import { NgMultiCompiler } from '@bitdev/angular.dev-services.compiler.multi-compiler'; import { AngularPreview, BundlerProvider, @@ -13,6 +14,7 @@ import { } from '@bitdev/angular.templates.generators'; import { AngularStarter } from '@bitdev/angular.templates.starters'; import { BundlerContext, DevServerContext } from '@teambit/bundler'; +import { Compiler } from '@teambit/compiler'; import { EslintConfigWriter, ESLintLinter, EslintTask } from '@teambit/defender.eslint-linter'; import { JestTask, JestTester } from '@teambit/defender.jest-tester'; import { PrettierConfigWriter, PrettierFormatter } from '@teambit/defender.prettier-formatter'; @@ -29,6 +31,8 @@ import { ConfigWriterList } from '@teambit/workspace-config-files'; import { ESLint as ESLintLib } from 'eslint'; import hostDependencies from './preview/host-dependencies'; +let ngMultiCompiler: EnvHandler | undefined; + export class MyAngularV16Env extends AngularV16Env { // Name of the environment, used for friendly mentions across bit name = 'my-angular-v16-env'; @@ -62,6 +66,20 @@ export class MyAngularV16Env extends AngularV16Env { }; } + /** + * Returns an instance of the compiler + * Required for making and reading dists, especially for `bit compile` + */ + compiler(): EnvHandler { + if (!ngMultiCompiler) { + ngMultiCompiler = NgMultiCompiler.from({ + ngEnvOptions: this.getNgEnvOptions(), + tsconfigPath: require.resolve('./config/tsconfig.json'), + }); + } + return ngMultiCompiler; + } + /** * The linter to use during development. * Config files would be used to validate coding standards in components. diff --git a/angular/examples/my-angular-v17-env/my-angular-v17-env.bit-env.ts b/angular/examples/my-angular-v17-env/my-angular-v17-env.bit-env.ts index d1c99bf6..fe52bca2 100644 --- a/angular/examples/my-angular-v17-env/my-angular-v17-env.bit-env.ts +++ b/angular/examples/my-angular-v17-env/my-angular-v17-env.bit-env.ts @@ -1,4 +1,5 @@ import { ApplicationOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; +import { NgMultiCompiler } from '@bitdev/angular.dev-services.compiler.multi-compiler'; import { AngularPreview, BundlerProvider, @@ -13,6 +14,7 @@ import { } from '@bitdev/angular.templates.generators'; import { AngularStarter } from '@bitdev/angular.templates.starters'; import { BundlerContext, DevServerContext } from '@teambit/bundler'; +import { Compiler } from '@teambit/compiler'; import { EslintConfigWriter, ESLintLinter, EslintTask } from '@teambit/defender.eslint-linter'; import { JestTask, JestTester } from '@teambit/defender.jest-tester'; import { PrettierConfigWriter, PrettierFormatter } from '@teambit/defender.prettier-formatter'; @@ -29,6 +31,8 @@ import { ConfigWriterList } from '@teambit/workspace-config-files'; import { ESLint as ESLintLib } from 'eslint'; import hostDependencies from './preview/host-dependencies'; +let ngMultiCompiler: EnvHandler | undefined; + export class MyAngularV17Env extends AngularV17Env { // Name of the environment, used for friendly mentions across bit name = 'my-angular-v17-env'; @@ -62,6 +66,20 @@ export class MyAngularV17Env extends AngularV17Env { }; } + /** + * Returns an instance of the compiler + * Required for making and reading dists, especially for `bit compile` + */ + compiler(): EnvHandler { + if (!ngMultiCompiler) { + ngMultiCompiler = NgMultiCompiler.from({ + ngEnvOptions: this.getNgEnvOptions(), + tsconfigPath: require.resolve('./config/tsconfig.json'), + }); + } + return ngMultiCompiler; + } + /** * The linter to use during development. * Config files would be used to validate coding standards in components. diff --git a/angular/templates/generators/ng-env/files/env.ts b/angular/templates/generators/ng-env/files/env.ts index d3ddf6f6..ee0391ed 100644 --- a/angular/templates/generators/ng-env/files/env.ts +++ b/angular/templates/generators/ng-env/files/env.ts @@ -3,11 +3,13 @@ import { ComponentContext } from '@teambit/generator'; export function envFile({ namePascalCase: Name, name }: ComponentContext, envName: string, angularVersion: number, envPkgName: string) { // language=TypeScript return `import { ApplicationOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; +import { NgMultiCompiler } from '@bitdev/angular.dev-services.compiler.multi-compiler'; import { AngularPreview, BundlerProvider, DevServerProvider } from '@bitdev/angular.dev-services.preview.preview'; import { ${envName} } from '${envPkgName}'; import { NgAppTemplate, NgEnvTemplate, NgModuleTemplate, NgStandaloneTemplate } from '@bitdev/angular.templates.generators'; import { AngularStarter, DesignSystemStarter, MaterialDesignSystemStarter } from '@bitdev/angular.templates.starters'; import { BundlerContext, DevServerContext } from '@teambit/bundler'; +import { Compiler } from '@teambit/compiler'; import { EslintConfigWriter, ESLintLinter, EslintTask } from '@teambit/defender.eslint-linter'; import { JestTask, JestTester } from '@teambit/defender.jest-tester'; import { PrettierConfigWriter, PrettierFormatter } from '@teambit/defender.prettier-formatter'; @@ -24,6 +26,8 @@ import { ConfigWriterList } from '@teambit/workspace-config-files'; import { ESLint as ESLintLib } from 'eslint'; import hostDependencies from './preview/host-dependencies'; +let ngMultiCompiler: EnvHandler | undefined; + export class ${Name} extends ${envName} { // Name of the environment, used for friendly mentions across bit name = '${name}'; @@ -57,6 +61,20 @@ export class ${Name} extends ${envName} { }; } + /** + * Returns an instance of the compiler + * Required for making and reading dists, especially for \`bit compile\` + */ + compiler(): EnvHandler { + if (!ngMultiCompiler) { + ngMultiCompiler = NgMultiCompiler.from({ + ngEnvOptions: this.getNgEnvOptions(), + tsconfigPath: require.resolve('./config/tsconfig.json'), + }); + } + return ngMultiCompiler; + } + /** * The linter to use during development. * Config files would be used to validate coding standards in components.