diff --git a/.bitmap b/.bitmap index 07a08e7f..a72a7930 100644 --- a/.bitmap +++ b/.bitmap @@ -12,371 +12,385 @@ "angular-env": { "name": "angular-env", "scope": "bitdev.angular", - "version": "7.1.0", + "version": "8.0.1", "mainFile": "index.ts", "rootDir": "angular/envs/angular-env" }, "app-types/angular-app-type": { "name": "app-types/angular-app-type", "scope": "bitdev.angular", - "version": "7.0.0", + "version": "8.0.1", "mainFile": "index.ts", "rootDir": "angular/app-types/angular-app-type" }, "dev-services/common": { "name": "dev-services/common", "scope": "bitdev.angular", - "version": "7.0.0", + "version": "8.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/common" }, "dev-services/compiler/elements": { "name": "dev-services/compiler/elements", "scope": "bitdev.angular", - "version": "7.0.0", + "version": "8.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/compiler/elements" }, "dev-services/compiler/multi-compiler": { "name": "dev-services/compiler/multi-compiler", "scope": "bitdev.angular", - "version": "7.0.0", + "version": "8.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/compiler/multi-compiler" }, "dev-services/compiler/ng-packagr": { "name": "dev-services/compiler/ng-packagr", "scope": "bitdev.angular", - "version": "7.0.0", + "version": "8.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/compiler/ng-packagr" }, "dev-services/linter/eslint": { "name": "dev-services/linter/eslint", "scope": "bitdev.angular", - "version": "4.0.0", + "version": "5.0.0", "mainFile": "index.js", "rootDir": "angular/devkit/linter/eslint" }, "dev-services/ng-compat": { "name": "dev-services/ng-compat", "scope": "bitdev.angular", - "version": "4.0.0", + "version": "5.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/ng-compat" }, "dev-services/preview/mounter": { "name": "dev-services/preview/mounter", "scope": "bitdev.angular", - "version": "4.0.0", + "version": "5.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/preview/mounter" }, "dev-services/preview/preview": { "name": "dev-services/preview/preview", "scope": "bitdev.angular", - "version": "7.0.0", + "version": "8.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/preview/preview" }, "dev-services/preview/preview-app": { "name": "dev-services/preview/preview-app", "scope": "bitdev.angular", - "version": "2.0.0", + "version": "3.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/preview/preview-app" }, "dev-services/preview/runtime": { "name": "dev-services/preview/runtime", "scope": "bitdev.angular", - "version": "4.0.0", + "version": "5.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/preview/runtime" }, + "dev-services/preview/vite-preview": { + "name": "dev-services/preview/vite-preview", + "scope": "bitdev.angular", + "version": "1.0.1", + "mainFile": "index.ts", + "rootDir": "angular/devkit/preview/vite-preview" + }, + "dev-services/vite": { + "name": "dev-services/vite", + "scope": "bitdev.angular", + "version": "2.0.1", + "mainFile": "index.ts", + "rootDir": "angular/devkit/vite" + }, "dev-services/webpack": { "name": "dev-services/webpack", "scope": "bitdev.angular", - "version": "7.0.0", + "version": "8.0.0", "mainFile": "index.ts", "rootDir": "angular/devkit/webpack" }, "docs/angular-docs-routes": { "name": "docs/angular-docs-routes", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/angular-docs-routes" }, "docs/angular-env-docs-data": { "name": "docs/angular-env-docs-data", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/angular-env-docs-data" }, "docs/angular-versions": { "name": "docs/angular-versions", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/angular-versions" }, "docs/bit-angular-introduction": { "name": "docs/bit-angular-introduction", "scope": "bitdev.angular", - "version": "0.0.4", + "version": "1.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/bit-angular-introduction" }, "docs/build-pipelines": { "name": "docs/build-pipelines", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/build-pipelines" }, "docs/component-generators": { "name": "docs/component-generators", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/component-generators" }, "docs/component-libs": { "name": "docs/component-libs", "scope": "bitdev.angular", - "version": "0.0.3", + "version": "1.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/component-libs" }, "docs/components-documentation": { "name": "docs/components-documentation", "scope": "bitdev.angular", - "version": "0.0.3", + "version": "1.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/components-documentation" }, "docs/components-overview": { "name": "docs/components-overview", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/components-overview" }, "docs/components-preview": { "name": "docs/components-preview", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/components-preview" }, "docs/create-custom-env": { "name": "docs/create-custom-env", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/create-custom-env" }, "docs/create-ng-app": { "name": "docs/create-ng-app", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/create-ng-app" }, "docs/dependency-policy": { "name": "docs/dependency-policy", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/dependency-policy" }, "docs/development-tools": { "name": "docs/development-tools", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/development-tools" }, "docs/ng-app-build": { "name": "docs/ng-app-build", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/ng-app-build" }, "docs/ng-app-deploy": { "name": "docs/ng-app-deploy", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/ng-app-deploy" }, "docs/ng-base-components": { "name": "docs/ng-base-components", "scope": "bitdev.angular", - "version": "0.0.3", + "version": "1.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/ng-base-components" }, "docs/ng-component-libraries": { "name": "docs/ng-component-libraries", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/ng-component-libraries" }, "docs/ng-design-overview": { "name": "docs/ng-design-overview", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/ng-design-overview" }, "docs/ng-theming": { "name": "docs/ng-theming", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/ng-theming" }, "docs/workspace-starters": { "name": "docs/workspace-starters", "scope": "bitdev.angular", - "version": "1.0.0", + "version": "2.0.0", "mainFile": "index.ts", "rootDir": "angular/docs/workspace-starters" }, "envs/angular-v16-env": { "name": "envs/angular-v16-env", "scope": "bitdev.angular", - "version": "7.1.0", + "version": "8.0.1", "mainFile": "index.ts", "rootDir": "angular/envs/angular-v16-env" }, "envs/angular-v17-env": { "name": "envs/angular-v17-env", "scope": "bitdev.angular", - "version": "6.1.0", + "version": "7.0.1", "mainFile": "index.ts", "rootDir": "angular/envs/angular-v17-env" }, "envs/angular-v18-env": { "name": "envs/angular-v18-env", "scope": "bitdev.angular", - "version": "2.1.0", + "version": "3.0.1", "mainFile": "index.ts", "rootDir": "angular/envs/angular-v18-env" }, "envs/angular-v19-env": { "name": "envs/angular-v19-env", "scope": "bitdev.angular", - "version": "1.1.0", + "version": "2.0.1", "mainFile": "index.ts", "rootDir": "angular/envs/angular-v19-env" }, "envs/base-env": { "name": "envs/base-env", "scope": "bitdev.angular", - "version": "7.1.0", + "version": "8.0.1", "mainFile": "index.ts", "rootDir": "angular/envs/base-env" }, "examples/my-angular-env": { "name": "examples/my-angular-env", "scope": "bitdev.angular", - "version": "7.1.0", + "version": "8.0.1", "mainFile": "index.ts", "rootDir": "angular/examples/my-angular-env" }, "examples/my-angular-v16-env": { "name": "examples/my-angular-v16-env", "scope": "bitdev.angular", - "version": "6.1.0", + "version": "7.0.1", "mainFile": "index.ts", "rootDir": "angular/examples/my-angular-v16-env" }, "examples/my-angular-v17-env": { "name": "examples/my-angular-v17-env", "scope": "bitdev.angular", - "version": "6.1.0", + "version": "7.0.1", "mainFile": "index.ts", "rootDir": "angular/examples/my-angular-v17-env" }, "examples/my-angular-v18-env": { "name": "examples/my-angular-v18-env", "scope": "bitdev.angular", - "version": "2.1.0", + "version": "3.0.1", "mainFile": "index.ts", "rootDir": "angular/examples/my-angular-v18-env" }, "examples/my-angular-v19-env": { "name": "examples/my-angular-v19-env", "scope": "bitdev.angular", - "version": "1.1.0", + "version": "2.0.1", "mainFile": "index.ts", "rootDir": "angular/examples/my-angular-v19-env" }, "integration/demo-app": { "name": "integration/demo-app", "scope": "bitdev.angular", - "version": "1.1.0", + "version": "2.0.1", "mainFile": "index.ts", "rootDir": "angular/integration/demo-app" }, "integration/demo-lib": { "name": "integration/demo-lib", "scope": "bitdev.angular", - "version": "1.1.0", + "version": "2.0.1", "mainFile": "public-api.ts", "rootDir": "angular/integration/demo-lib" }, "integration/demo-lib-v16": { "name": "integration/demo-lib-v16", "scope": "bitdev.angular", - "version": "1.1.0", + "version": "2.0.1", "mainFile": "public-api.ts", "rootDir": "angular/integration/demo-lib-v16" }, "integration/demo-lib-v17": { "name": "integration/demo-lib-v17", "scope": "bitdev.angular", - "version": "1.1.0", + "version": "2.0.1", "mainFile": "public-api.ts", "rootDir": "angular/integration/demo-lib-v17" }, "integration/demo-lib-v18": { "name": "integration/demo-lib-v18", "scope": "bitdev.angular", - "version": "1.1.0", + "version": "2.0.1", "mainFile": "public-api.ts", "rootDir": "angular/integration/demo-lib-v18" }, "integration/demo-lib-v19": { "name": "integration/demo-lib-v19", "scope": "bitdev.angular", - "version": "1.1.0", + "version": "2.0.1", "mainFile": "public-api.ts", "rootDir": "angular/integration/demo-lib-v19" }, "readme": { "name": "readme", "scope": "bitdev.angular", - "version": "2.0.3", + "version": "3.0.0", "mainFile": "index.ts", "rootDir": "angular/readme" }, "templates/generators": { "name": "templates/generators", "scope": "bitdev.angular", - "version": "7.1.0", + "version": "8.0.1", "mainFile": "index.ts", "rootDir": "angular/templates/generators" }, "templates/starters": { "name": "templates/starters", "scope": "bitdev.angular", - "version": "7.0.0", + "version": "8.0.0", "mainFile": "index.ts", "rootDir": "angular/templates/starters" }, diff --git a/angular/app-types/angular-app-type/angular-app-options.ts b/angular/app-types/angular-app-type/angular-app-options.ts index f4530373..1d7fc9e3 100644 --- a/angular/app-types/angular-app-type/angular-app-options.ts +++ b/angular/app-types/angular-app-type/angular-app-options.ts @@ -1,5 +1,4 @@ import { - AngularEnvOptions, ApplicationOptions, BrowserOptions, DevServerOptions @@ -53,9 +52,4 @@ export type AngularAppOptions = { * Angular options for `bit run` */ angularServeOptions: (BrowserOptions & DevServerOptions) | (ApplicationOptions & DevServerOptions); - - /** - * Env-specific options depending on the version of Angular used. - */ - ngEnvOptions: AngularEnvOptions; }; diff --git a/angular/app-types/angular-app-type/angular.application.ts b/angular/app-types/angular-app-type/angular.application.ts index 45a06154..21847bcf 100644 --- a/angular/app-types/angular-app-type/angular.application.ts +++ b/angular/app-types/angular-app-type/angular.application.ts @@ -1,7 +1,8 @@ import { VERSION } from '@angular/cli'; import { getWorkspace, NG_APP_NAME, normalizePath } from '@bitdev/angular.dev-services.common'; import { ApplicationBuilderOptions, SsrClass } from '@bitdev/angular.dev-services.ng-compat'; -import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; +import { AngularVitePreview } from '@bitdev/angular.dev-services.preview.vite-preview'; +import { buildApplication, generateAppTsConfig, getEnvFile, serveApplication } from '@bitdev/angular.dev-services.vite'; import { AppBuildContext, AppBuildResult, @@ -11,25 +12,17 @@ import { DeployFn } from '@teambit/application'; import { Bundler, BundlerContext, DevServerContext } from '@teambit/bundler'; -import { Component } from '@teambit/component'; import { DependencyResolverAspect, DependencyResolverMain } from '@teambit/dependency-resolver'; import { EnvContext, EnvHandler } from '@teambit/envs'; -import { CACHE_ROOT } from '@teambit/legacy/dist/constants.js'; +import { CACHE_ROOT } from '@teambit/legacy.constants'; import { Preview } from '@teambit/preview'; import { Port } from '@teambit/toolbox.network.get-port'; import { Workspace } from '@teambit/workspace'; import assert from 'assert'; import fs from 'fs-extra'; import { cloneDeep } from 'lodash-es'; -import objectHash from 'object-hash'; import { join } from 'path'; -import ts from 'typescript'; import { AngularAppOptions } from './angular-app-options.js'; -import { buildApplication } from './application.bundler.js'; -import { serveApplication } from './application.dev-server.js'; -import { expandIncludeExclude, JsonObject } from './utils.js'; - -const writeHash = new Map(); export class AngularApp implements Application { readonly name: string; @@ -63,10 +56,9 @@ export class AngularApp implements Application { } private getDevServerContext(context: AppContext): DevServerContext { - // const ngEnvOptions = this.angularEnv.getNgEnvOptions(); return Object.assign(cloneDeep(context), { entry: [], - rootPath: /*ngEnvOptions.devServer === 'vite' ? _appRootPath : */'', + rootPath: '', publicPath: `${this.publicDir}/${this.options.name}`, title: this.options.name }); @@ -93,48 +85,11 @@ export class AngularApp implements Application { const angularServeOptions: any = Object.assign(cloneDeep(this.options.angularServeOptions), { tsConfig: tsconfigPath }); const angularBuildOptions: any = Object.assign(cloneDeep(this.options.angularBuildOptions), { tsConfig: tsconfigPath }); - return AngularPreview.from({ - webpackServeTransformers: this.options.webpackServeTransformers, - webpackBuildTransformers: this.options.webpackBuildTransformers, + return AngularVitePreview.from({ angularServeOptions, angularBuildOptions, - ngEnvOptions: this.options.ngEnvOptions, sourceRoot: this.options.sourceRoot }); - - } - - private generateTsConfig(bitCmps: Component[], appRootPath: string, appTsconfigPath: string, tsconfigPath: string, depsResolver: DependencyResolverMain, workspace?: Workspace, serverEntry?: string): void { - const tsconfigJSON: JsonObject = ts.readConfigFile(appTsconfigPath, ts.sys.readFile).config; - - // Add the paths to tsconfig to remap bit components to local folders - tsconfigJSON.compilerOptions.paths = tsconfigJSON.compilerOptions.paths || {}; - bitCmps.forEach((dep: Component) => { - let componentDir = workspace?.componentDir(dep.id, { - ignoreVersion: true - }); - if (componentDir) { - componentDir = normalizePath(componentDir); - const pkgName = depsResolver.getPackageName(dep); - // TODO we should find a way to use the real entry file based on the component config because people can change it - if (fs.existsSync(join(componentDir, 'public-api.ts'))) { - tsconfigJSON.compilerOptions.paths[pkgName] = [`${componentDir}/public-api.ts`, `${componentDir}`]; - } - tsconfigJSON.compilerOptions.paths[`${pkgName}/*`] = [`${componentDir}/*`]; - } - }); - - if (serverEntry) { - tsconfigJSON.files.push(serverEntry); - } - - const tsconfigContent = expandIncludeExclude(tsconfigJSON, tsconfigPath, [appRootPath]); - const hash = objectHash(tsconfigContent); - // write only if link has changed (prevents triggering fs watches) - if (writeHash.get(tsconfigPath) !== hash) { - fs.outputJsonSync(tsconfigPath, tsconfigContent, { spaces: 2 }); - writeHash.set(tsconfigPath, hash); - } } /** @@ -145,16 +100,6 @@ export class AngularApp implements Application { return context as any as EnvContext; } - private async getEnvFile(mode: string, rootDir: string, overrides?: Record) { - // TODO: enable this one we have ESM envs, otherwise we get a warning message about loading the deprecated CJS build of Vite - // const vite = await import('vite'); - // const dotenv = vite.loadEnv(mode, rootDir); - return { - ...overrides - // ...dotenv - }; - } - // TODO: fix return type once bit has a new stable version async run(context: AppContext): Promise { const depsResolver = context.getAspect(DependencyResolverAspect.id); @@ -171,32 +116,23 @@ export class AngularApp implements Application { const bitCmps = await workspace.getMany(workspaceCmpsIDs); const tempFolder = this.getTempFolder(workspace); const tsconfigPath = this.getTsconfigPath(tempFolder); - this.generateTsConfig(bitCmps, appRootPath, appTsconfigPath, tsconfigPath, depsResolver, workspace); - - if (Number(VERSION.major) >= 16) { - const envVars = await this.getEnvFile('development', appRootPath, context.envVariables as any); - await serveApplication({ - angularOptions: { - ...this.options.angularBuildOptions as ApplicationBuilderOptions, - tsConfig: tsconfigPath - }, - sourceRoot: this.options.sourceRoot || 'src', - workspaceRoot: appRootPath, - port, - logger: logger, - tempFolder: tempFolder, - envVars: { - process: { env: envVars } - } - }); - } else { - const devServerContext = this.getDevServerContext(context); - const envContext = this.getEnvContext(context); - const preview = this.getPreview(tsconfigPath)(envContext); - - const devServer = await preview.getDevServer(devServerContext)(envContext); - await devServer.listen(port); - } + generateAppTsConfig(bitCmps, appRootPath, appTsconfigPath, tsconfigPath, depsResolver, workspace); + + const envVars = await getEnvFile('development', appRootPath, context.envVariables as any); + await serveApplication({ + angularOptions: { + ...this.options.angularBuildOptions as ApplicationBuilderOptions, + tsConfig: tsconfigPath + }, + sourceRoot: this.options.sourceRoot || 'src', + workspaceRoot: appRootPath, + port, + logger: logger, + tempFolder: tempFolder, + envVars: { + process: { env: envVars } + } + }); return { appName: this.name, @@ -221,11 +157,12 @@ export class AngularApp implements Application { } const tempFolder = this.getTempFolder(); const tsconfigPath = this.getTsconfigPath(tempFolder); - this.generateTsConfig([capsule.component], appRootPath, appTsconfigPath, tsconfigPath, depsResolver, undefined, entryServer); + generateAppTsConfig([capsule.component], appRootPath, appTsconfigPath, tsconfigPath, depsResolver, undefined, entryServer ? [entryServer] : undefined); - if (!this.options.bundler && Number(VERSION.major) >= 16) { - const envVars = await this.getEnvFile('production', appRootPath, context.envVariables as any); - await buildApplication({ + const errors: Error[] = []; + if (!this.options.bundler) { + const envVars = await getEnvFile('production', appRootPath, context.envVariables); + const results = await buildApplication({ angularOptions: { ...appOptions, tsConfig: tsconfigPath @@ -240,7 +177,11 @@ export class AngularApp implements Application { 'process.env': envVars } }); - console.log('build done'); + for (const result of results) { + if (result.error) { + errors.push(new Error(result.error)); + } + } } else { let bundler: Bundler; if (this.options.bundler) { @@ -252,9 +193,15 @@ export class AngularApp implements Application { bundler = await preview.getBundler(bundlerContext)(envContext); } - await bundler.run(); + const results = await bundler.run(); + for (const result of results) { + if (result.errors) { + errors.push(...result.errors); + } + } } return { + errors, artifacts: [{ name: this.name, globPatterns: [outputPath], diff --git a/angular/app-types/angular-app-type/component.json b/angular/app-types/angular-app-type/component.json index 2d867f2a..29c6cac3 100644 --- a/angular/app-types/angular-app-type/component.json +++ b/angular/app-types/angular-app-type/component.json @@ -2,36 +2,30 @@ "componentId": { "scope": "bitdev.angular", "name": "app-types/angular-app-type", - "version": "7.0.0" + "version": "8.0.1" }, "propagate": false, "extensions": { "teambit.dependencies/dependency-resolver": { "policy": { "dependencies": { - "h3": "^1.9.0", - "nitropack": "^2.8.0", - "@angular-devkit/build-angular": "-", - "@angular/cli": "-", - "typescript": "-", - "#alias": "-" + "@angular/cli": "-" }, "peerDependencies": { - "@angular-devkit/build-angular": ">= 0.0.1", - "@angular/cli": ">= 13.0.0", - "esbuild": ">= 0.14.0", - "typescript": ">= 3.5.3" + "@angular/cli": ">= 13.0.0" } } }, - "bitdev.node/node-env@2.0.2": {}, - "teambit.envs/envs": {}, "teambit.component/renaming": { "renamedFrom": { "scope": "bitdev.angular", "name": "dev-services/apps", "version": "02f8cd3d639894dea416cc38674a6887e11e939b" } + }, + "bitdev.node/node-env@2.0.40": {}, + "teambit.envs/envs": { + "env": "bitdev.node/node-env" } } } diff --git a/angular/app-types/angular-app-type/utils.ts b/angular/app-types/angular-app-type/utils.ts deleted file mode 100644 index 9ddbc71f..00000000 --- a/angular/app-types/angular-app-type/utils.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { ApplicationOptions, normalizePath } from '@bitdev/angular.dev-services.common'; -import assert from 'assert'; -import { flatten } from 'lodash-es'; -import { dirname, relative } from 'path'; - -export interface JsonObject { - [prop: string]: any; -} - -/** - * Takes a tsconfig.json file, a list of component directories, and returns a new tsconfig.json file with the include - * and exclude properties expanded to include all the component directories - * @param {any} tsconfigJSON - The path to the existing tsconfig.json file. - * @param {string} targetPath - The path to the new tsconfig.json file. - * @param {string[]} compDirs - An array of paths to the component directories. - * @returns the tsConfig object. - */ -export function expandIncludeExclude(tsconfigJSON: JsonObject, targetPath: string, compDirs: string[]): JsonObject { - // eslint-disable-next-line no-param-reassign - targetPath = dirname(targetPath); - - if (tsconfigJSON.include) { - // eslint-disable-next-line no-param-reassign - tsconfigJSON.include = flatten( - tsconfigJSON.include.map((includedPath: string) => { - return compDirs.map((compDir: string) => { - const compDirRelative = normalizePath(relative(targetPath, compDir)); - return `${compDirRelative}/${includedPath}`; - }); - }) - ); - } - if (tsconfigJSON.exclude) { - // eslint-disable-next-line no-param-reassign - tsconfigJSON.exclude = flatten( - tsconfigJSON.exclude.map((excludedPath: string) => { - return compDirs.map((compDir: string) => { - const compDirRelative = normalizePath(relative(targetPath, compDir)); - return `${compDirRelative}/${excludedPath}`; - }); - }) - ); - } - if (tsconfigJSON.files) { - // eslint-disable-next-line no-param-reassign - tsconfigJSON.files = flatten( - tsconfigJSON.files.map((filesPath: string) => { - return compDirs.map((compDir: string) => { - const compDirRelative = normalizePath(relative(targetPath, compDir)); - return `${compDirRelative}/${filesPath}`; - }); - }) - ); - } - - return tsconfigJSON; -} - -export function getIndexInputFile(index: ApplicationOptions['index']): string { - assert(index, 'No index file provided'); - if (typeof index === 'string') { - return index; - } - return (index as any).input; -} diff --git a/angular/devkit/common/component.json b/angular/devkit/common/component.json index ba1521f4..d0edf54b 100644 --- a/angular/devkit/common/component.json +++ b/angular/devkit/common/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/common", - "version": "7.0.0" + "version": "33b27185d4339685b5106095d560648a1e296ae7" }, "propagate": false, "extensions": { @@ -19,7 +19,6 @@ } } }, - "teambit.node/node@1.0.54": {}, "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, @@ -27,6 +26,7 @@ "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "teambit.node/node@1.0.103": {} } } diff --git a/angular/devkit/common/env-options.ts b/angular/devkit/common/env-options.ts index a3c5260f..aeb22196 100644 --- a/angular/devkit/common/env-options.ts +++ b/angular/devkit/common/env-options.ts @@ -3,13 +3,11 @@ import { WebpackConfigWithDevServer } from '@teambit/webpack'; export type WebpackConfigFactory = (opts: any) => Promise; export type AngularEnvOptions = { - /** * Use Rollup & Angular Elements to compile compositions instead of webpack. * This transforms compositions into Web Components and replaces the Angular bundler by the React bundler. */ useAngularElementsPreview?: boolean; - jestConfigPath: string; jestModulePath: string; ngPackagrModulePath: string; angularElementsModulePath?: string; diff --git a/angular/devkit/common/generic-angular-env.ts b/angular/devkit/common/generic-angular-env.ts index eff1a663..43d7ffec 100644 --- a/angular/devkit/common/generic-angular-env.ts +++ b/angular/devkit/common/generic-angular-env.ts @@ -10,9 +10,49 @@ import { CompilerEnv } from '@teambit/compiler'; import { PreviewEnv } from '@teambit/preview'; import { AngularEnvOptions } from './env-options'; -export type BrowserOptions = Omit & {inlineStyleLanguage?: "css" | "less" | "sass" | "scss"}; -export type DevServerOptions = Omit; -export type ApplicationOptions = Omit & {inlineStyleLanguage?: "css" | "less" | "sass" | "scss", outputMode?: "static" | "server" | OutputMode}; +export type BrowserOptions = + Omit + & { inlineStyleLanguage?: "css" | "less" | "sass" | "scss" }; +export type DevServerOptions = + Omit + & { buildTarget?: "development" | "production" }; +export type ApplicationOptions = + Omit + & { inlineStyleLanguage?: "css" | "less" | "sass" | "scss", outputMode?: "static" | "server" | OutputMode }; + +/** Internal options hidden from builder schema but available when invoked programmatically. */ +export interface InternalOptions { + /** + * Entry points to use for the compilation. Incompatible with `browser`, which must not be provided. May be relative or absolute paths. + * If given a relative path, it is resolved relative to the current workspace and will generate an output at the same relative location + * in the output directory. If given an absolute path, the output will be generated in the root of the output directory with the same base + * name. + */ + entryPoints?: Set; + + /** File extension to use for the generated output files. */ + outExtension?: 'js' | 'mjs'; + + /** + * Indicates whether all node packages should be marked as external. + * Currently used by the dev-server to support prebundling. + */ + externalPackages?: boolean | { exclude: string[] }; + + /** + * Forces the output from the localize post-processing to not create nested directories per locale output. + * This is only used by the development server which currently only supports a single locale per build. + */ + forceI18nFlatOutput?: boolean; +} + +export type ApplicationInternalOptions = Omit< + ApplicationOptions & InternalOptions, + 'browser' +> & { + // `browser` can be `undefined` if `entryPoints` is used. + browser?: string; +}; export interface GenericAngularEnv extends AppsEnv, diff --git a/angular/devkit/common/utils.ts b/angular/devkit/common/utils.ts index 4e9e7980..e5b8d87f 100644 --- a/angular/devkit/common/utils.ts +++ b/angular/devkit/common/utils.ts @@ -6,7 +6,7 @@ import { EnvContext } from '@teambit/envs'; import { IsolatorMain } from '@teambit/isolator'; import { Logger } from '@teambit/logger'; import { PkgMain } from '@teambit/pkg'; -import TesterAspect from '@teambit/tester'; +import { TesterAspect } from '@teambit/tester'; import WorkspaceAspect, { Workspace } from '@teambit/workspace'; import { ScopeMain } from '@teambit/scope'; import { getRootComponentDir } from '@teambit/workspace.root-components'; @@ -190,7 +190,8 @@ export function generateTsConfig( compilerOptions: { paths: tsPaths }, - files: ["./src/main.ts", "./src/polyfills.ts"].map((file: string) => posix.join(pAppPath, file)), + // eslint-disable-next-line + files: ["./src/main.ts" /*, "./src/polyfills.ts"*/ ].map((file: string) => posix.join(pAppPath, file)), include: [ ...["./src/app/**/*.ts"].map((file: string) => posix.join(pAppPath, file)), ...includePaths.map((path) => posix.join(path, '**/*.ts')) @@ -284,7 +285,7 @@ export async function writeTsconfig( return normalizePath(targetPath); } -export function dedupPaths(paths: (string | any)[]): string[] { +export function dedupePaths(paths: (string | any)[]): string[] { return Array.from(new Set(paths.map(p => typeof p === 'string' ? posix.normalize(p) : p))); } @@ -299,27 +300,28 @@ export function packagePath(packageName: string, path = ''): string { return join(dirname(require.resolve(`${packageName}/package.json`)), path); } -export function getLoggerApi(logger: Logger) { +export function getLoggerApi(logger: Logger, isPreview = false) { return { // eslint-disable-next-line no-console error: (m: string) => console.error(m), - log: (m: string) => logger.console(m), + log: (m: string) => !isPreview ? logger.console(m) : null, + // ignoring the warning about the server to use only for testing // eslint-disable-next-line no-console - warn: (m: string) => console.warn(m), - info: (m: string) => logger.console(m), + warn: (m: string) => !m.match('This is a simple server') ? console.warn(m) : null, + info: (m: string) => !isPreview ? logger.console(m) : null, // eslint-disable-next-line no-console colorMessage: (m: string) => console.log(m), createChild: () => logger } as any; } -export function addSafeResolve(path: string, nodeModulesPaths?: string[]): string | undefined { +export function getSafeResolve(path: string, nodeModulesPaths?: string[]): string | undefined { try { return require.resolve(path, { paths: nodeModulesPaths }); } catch (_e) { if (nodeModulesPaths) { try { - return addSafeResolve(path); + return getSafeResolve(path); } catch (_e2) { return undefined; } @@ -333,6 +335,7 @@ export function getWebpackAngularAliases(nodeModulesPaths?: string[]): { [key: s [ '@angular/build', + '@angular/cdk', '@angular/core/schematics', '@angular/core/rxjs-interop', '@angular/core/primitives/signals', @@ -364,7 +367,7 @@ export function getWebpackAngularAliases(nodeModulesPaths?: string[]): { [key: s '@angular/ssr/schematics', '@angular/ssr' ].forEach((pkg) => { - const resolved = addSafeResolve(pkg, nodeModulesPaths); + const resolved = getSafeResolve(pkg, nodeModulesPaths); if (resolved) { aliases[pkg] = resolved; } diff --git a/angular/devkit/compiler/elements/angular-elements.compiler.ts b/angular/devkit/compiler/elements/angular-elements.compiler.ts index 0d956dea..b6af6ffa 100644 --- a/angular/devkit/compiler/elements/angular-elements.compiler.ts +++ b/angular/devkit/compiler/elements/angular-elements.compiler.ts @@ -1,26 +1,16 @@ // @ts-ignore import type { AngularCompilerOptions } from '@angular/compiler-cli'; -import type { AngularEnvOptions } from '@bitdev/angular.dev-services.common'; -import { - componentIsApp, - getNodeModulesPaths, - getWorkspace -} from '@bitdev/angular.dev-services.common'; +import { componentIsApp, getNodeModulesPaths, getWorkspace } from '@bitdev/angular.dev-services.common'; import { ApplicationAspect, ApplicationMain } from '@teambit/application'; -import { - ArtifactDefinition, - BuildContext, - BuiltTaskResult, - ComponentResult -} from '@teambit/builder'; +import { ArtifactDefinition, BuildContext, BuiltTaskResult, ComponentResult } from '@teambit/builder'; import { Compiler, TranspileComponentParams } from '@teambit/compiler'; import { Component } from '@teambit/component'; import { CompositionsAspect, CompositionsMain } from '@teambit/compositions'; import { EnvContext, EnvHandler } from '@teambit/envs'; import { IsolatorAspect, IsolatorMain } from '@teambit/isolator'; -import { Timer } from '@teambit/legacy/dist/toolbox/timer'; import { Logger } from '@teambit/logger'; import { ScopeAspect, ScopeMain } from '@teambit/scope'; +import { Timer } from '@teambit/toolbox.time.timer'; import { Workspace } from '@teambit/workspace'; import chalk from 'chalk'; import { extname, join } from 'path'; @@ -28,7 +18,6 @@ import { RollupCompiler } from './rollup/rollup.compiler'; interface AngularElementsCompilerOptions { ngPackagrModulePath?: string; - ngEnvOptions: AngularEnvOptions; tsCompilerOptions?: AngularCompilerOptions; name?: string; distDir: string; @@ -55,7 +44,6 @@ export class AngularElementsCompiler implements Compiler { public artifactName: string, private tsCompilerOptions: AngularCompilerOptions = {}, private nodeModulesPaths: string[] = [], - private ngEnvOptions: AngularEnvOptions ) { this.rollupCompiler = new RollupCompiler(this.tsCompilerOptions, this.logger); } @@ -201,8 +189,7 @@ Built Angular Compositions options.shouldCopyNonSupportedFiles, options.artifactName, options.tsCompilerOptions, - nodeModulesPaths, - options.ngEnvOptions + nodeModulesPaths ); }; } diff --git a/angular/devkit/compiler/elements/component.json b/angular/devkit/compiler/elements/component.json index 5bc0edf8..aff63e96 100644 --- a/angular/devkit/compiler/elements/component.json +++ b/angular/devkit/compiler/elements/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/compiler/elements", - "version": "7.0.0" + "version": "ced8dc9e4b51671f124d90b0bde8541dce8d84bc" }, "propagate": false, "extensions": { @@ -48,7 +48,6 @@ } } }, - "teambit.node/node@1.0.54": {}, "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, @@ -56,6 +55,7 @@ "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "teambit.node/node@1.0.103": {} } } diff --git a/angular/devkit/compiler/elements/rollup/rollup.compiler.ts b/angular/devkit/compiler/elements/rollup/rollup.compiler.ts index ed5901ef..8bf96b7e 100644 --- a/angular/devkit/compiler/elements/rollup/rollup.compiler.ts +++ b/angular/devkit/compiler/elements/rollup/rollup.compiler.ts @@ -90,16 +90,38 @@ export class RollupCompiler { nodeResolve({ moduleDirectories: opts.nodeModulesPaths ?? ['node_modules'], dedupe: [ + '@angular/build', + '@angular/cdk', + '@angular/core/schematics', + '@angular/core/rxjs-interop', + '@angular/core/primitives/signals', + '@angular/core/primitives/event-dispatch', + '@angular/core/testing', + '@angular/core', + '@angular/common/http', + '@angular/common/locales', + '@angular/common/testing', + '@angular/common', + '@angular/animations/browser', '@angular/animations', '@angular/cli', - '@angular/common', '@angular/compiler', '@angular/compiler-cli', - '@angular/core', '@angular/forms', + '@angular/platform-browser/animations/async', + '@angular/platform-browser/animations', + '@angular/platform-browser/testing', '@angular/platform-browser', + '@angular/platform-browser-dynamic/testing', '@angular/platform-browser-dynamic', - '@angular/router' + '@angular/platform-server/init', + '@angular/platform-server/testing', + '@angular/platform-server', + '@angular/router/upgrade', + '@angular/router/testing', + '@angular/router', + '@angular/ssr/schematics', + '@angular/ssr' ] }), // sourcemaps({ diff --git a/angular/devkit/compiler/multi-compiler/component.json b/angular/devkit/compiler/multi-compiler/component.json index fa39597c..9002fad1 100644 --- a/angular/devkit/compiler/multi-compiler/component.json +++ b/angular/devkit/compiler/multi-compiler/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/compiler/multi-compiler", - "version": "7.0.0" + "version": "a1956f0864f870916641de83680136e322d0f63a" }, "propagate": false, "extensions": { @@ -24,14 +24,16 @@ } } }, - "bitdev.node/node-env@2.0.2": {}, - "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, "teambit.preview/preview": {}, "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "bitdev.node/node-env@2.0.40": {}, + "teambit.envs/envs": { + "env": "bitdev.node/node-env" + } } } diff --git a/angular/devkit/compiler/multi-compiler/ng-multi-compiler.ts b/angular/devkit/compiler/multi-compiler/ng-multi-compiler.ts index 4f8c19c0..6a4d679e 100644 --- a/angular/devkit/compiler/multi-compiler/ng-multi-compiler.ts +++ b/angular/devkit/compiler/multi-compiler/ng-multi-compiler.ts @@ -189,7 +189,6 @@ export class NgMultiCompiler implements Compiler { artifactName, distDir, distGlobPatterns, - ngEnvOptions: options.ngEnvOptions, ngPackagrModulePath, shouldCopyNonSupportedFiles, tsCompilerOptions: options.tsCompilerOptions, @@ -203,7 +202,6 @@ export class NgMultiCompiler implements Compiler { artifactName, distDir, distGlobPatterns, - ngEnvOptions: options.ngEnvOptions, shouldCopyNonSupportedFiles, tsCompilerOptions: options.tsCompilerOptions })(context); diff --git a/angular/devkit/compiler/ng-packagr/component.json b/angular/devkit/compiler/ng-packagr/component.json index 851d5988..7bcf0027 100644 --- a/angular/devkit/compiler/ng-packagr/component.json +++ b/angular/devkit/compiler/ng-packagr/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/compiler/ng-packagr", - "version": "7.0.0" + "version": "f2f08c62f796c69586c399178142c69fcdebd557" }, "propagate": false, "extensions": { @@ -19,14 +19,16 @@ } } }, - "bitdev.node/node-env@2.0.2": {}, - "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, "teambit.preview/preview": {}, "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "bitdev.node/node-env@2.0.40": {}, + "teambit.envs/envs": { + "env": "bitdev.node/node-env" + } } } diff --git a/angular/devkit/compiler/ng-packagr/ng-packagr.compiler.ts b/angular/devkit/compiler/ng-packagr/ng-packagr.compiler.ts index 98e4826f..4abb52b0 100644 --- a/angular/devkit/compiler/ng-packagr/ng-packagr.compiler.ts +++ b/angular/devkit/compiler/ng-packagr/ng-packagr.compiler.ts @@ -19,8 +19,8 @@ import { DependencyResolverAspect, DependencyResolverMain } from '@teambit/depen import { EnvContext, EnvHandler } from '@teambit/envs'; import { CyclicError } from '@teambit/graph.cleargraph'; import { IsolatorAspect, IsolatorMain } from '@teambit/isolator'; -import { PACKAGE_JSON } from '@teambit/legacy/dist/constants.js'; -import PackageJsonFile from '@teambit/legacy/dist/consumer/component/package-json-file.js'; +import { PACKAGE_JSON } from '@teambit/legacy.constants'; +import * as sources from '@teambit/component.sources'; import { Logger } from '@teambit/logger'; import { ScopeAspect, ScopeMain } from '@teambit/scope'; import { Workspace } from '@teambit/workspace'; @@ -30,6 +30,7 @@ import { mkdirsSync, outputFileSync, removeSync } from 'fs-extra/esm'; import type { NgPackageConfig } from 'ng-packagr/ng-package.schema.js'; import { createRequire } from 'node:module'; import { join, posix, resolve } from 'node:path'; +import { pathToFileURL } from "node:url"; import type { Diagnostic, DiagnosticWithLocation } from 'typescript'; import ts from 'typescript'; @@ -100,7 +101,6 @@ export interface NgPackagr { interface NgPackagrCompilerOptions { ngPackagrModulePath: string; - ngEnvOptions: AngularEnvOptions; tsCompilerOptions?: AngularCompilerOptions; tsconfigPath?: string; name?: string; @@ -184,7 +184,7 @@ export class NgPackagrCompiler implements Compiler { // check for dependencies other than tslib and move them to peer dependencies // see https://github.com/ng-packagr/ng-packagr/blob/master/docs/dependencies.md#general-recommendation-use-peerdependencies-whenever-possible // @ts-ignore - const packageJson = PackageJsonFile.default.loadFromPathSync(pathToOutputFolder, ''); + const packageJson = sources.default.PackageJsonFile.loadFromPathSync(pathToOutputFolder, ''); const { dependencies } = packageJson.packageJsonObject; // const peerDependencies = packageJson.packageJsonObject.peerDependencies; const allowedNonPeerDependencies: string[] = []; @@ -233,7 +233,7 @@ export class NgPackagrCompiler implements Compiler { const parsedTsConfig = await this.readDefaultTsConfig(); parsedTsConfig.options = { ...parsedTsConfig.options, ...tsCompilerOptions }; - const ngPackagr: NgPackagr = (await import(this.ngPackagrPath)).ngPackagr(); + const ngPackagr: NgPackagr = (await import(pathToFileURL(this.ngPackagrPath).href)).ngPackagr(); return ngPackagr .withTsConfig(parsedTsConfig) .forProject(ngPackageJsonPath) @@ -241,7 +241,7 @@ export class NgPackagrCompiler implements Compiler { .then(async() => { // copy over properties generated by ngPackagr // @ts-ignore - const tempPackageJson = PackageJsonFile.default.loadSync(pathToOutputFolder, this.distDir).packageJsonObject; + const tempPackageJson = sources.default.PackageJsonFile.loadSync(pathToOutputFolder, this.distDir).packageJsonObject; const jsonProps = this.updatePaths(tempPackageJson); packageJson.mergePackageJsonObject(jsonProps); await packageJson.write(); @@ -412,7 +412,6 @@ export class NgPackagrCompiler implements Compiler { version(): string { const require = createRequire(import.meta.url); - // eslint-disable-next-line global-require return require('ng-packagr/package.json').version; } diff --git a/angular/devkit/linter/eslint/component.json b/angular/devkit/linter/eslint/component.json index 1f1625fc..c712e7f9 100644 --- a/angular/devkit/linter/eslint/component.json +++ b/angular/devkit/linter/eslint/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/linter/eslint", - "version": "4.0.0" + "version": "ebdc47a8803c9e11a951e7f528004c1ea985f5f4" }, "propagate": false, "extensions": { @@ -22,7 +22,6 @@ } } }, - "teambit.node/node@1.0.54": {}, "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, @@ -30,6 +29,7 @@ "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "teambit.node/node@1.0.103": {} } } diff --git a/angular/devkit/ng-compat/build-angular/builders/application.ts b/angular/devkit/ng-compat/build-angular/builders/application.ts index 5f143959..8a590376 100644 --- a/angular/devkit/ng-compat/build-angular/builders/application.ts +++ b/angular/devkit/ng-compat/build-angular/builders/application.ts @@ -9,9 +9,9 @@ export let buildApplicationInternal = ( context: BuilderContext & { signal?: AbortSignal; }, - infrastructureSettings?: { - write?: boolean; - }, + // infrastructureSettings?: { + // write?: boolean; + // }, plugins?: Plugin[] | { codePlugins: Plugin[], indexHtmlTransformer: any } // @ts-ignore ) => AsyncIterable= 2) || Number(VERSION.maj export const getCommonConfig: configFn = configs.getCommonConfig; export const getDevServerConfig: configFn = configs.getDevServerConfig; export const getStylesConfig: configFn = configs.getStylesConfig; - -// Angular v12, undefined for other versions -export const getBrowserConfig: configFn = configs.getBrowserConfig; -export const getStatsConfig: (wco: any) => { stats: any } = configs.getStatsConfig; -export const getTypeScriptConfig: configFn = configs.getTypeScriptConfig; diff --git a/angular/devkit/ng-compat/component.json b/angular/devkit/ng-compat/component.json index b59015b9..201f3638 100644 --- a/angular/devkit/ng-compat/component.json +++ b/angular/devkit/ng-compat/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/ng-compat", - "version": "4.0.0" + "version": "85ce3b597c81384a3d96b07ce7a2c9b789155116" }, "propagate": false, "extensions": { @@ -22,7 +22,6 @@ } } }, - "teambit.node/node@1.0.54": {}, "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, @@ -30,6 +29,7 @@ "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "teambit.node/node@1.0.103": {} } } diff --git a/angular/devkit/preview/mounter/component.json b/angular/devkit/preview/mounter/component.json index ac223e0e..9491c908 100644 --- a/angular/devkit/preview/mounter/component.json +++ b/angular/devkit/preview/mounter/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/preview/mounter", - "version": "4.0.0" + "version": "1aec2c8c2f5de9f231eca1e3eda587b7973477b2" }, "propagate": false, "extensions": { @@ -21,14 +21,16 @@ } } }, - "bitdev.node/node-env@2.0.2": {}, - "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, "teambit.preview/preview": {}, "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "bitdev.node/node-env@2.0.40": {}, + "teambit.envs/envs": { + "env": "bitdev.node/node-env" + } } } diff --git a/angular/devkit/preview/preview-app/preview-app/favicon.ico b/angular/devkit/preview/preview-app/preview-app/favicon.ico new file mode 100644 index 00000000..57614f9c Binary files /dev/null and b/angular/devkit/preview/preview-app/preview-app/favicon.ico differ diff --git a/angular/devkit/preview/preview-app/preview-app/src/app/docs/docs.component.ts b/angular/devkit/preview/preview-app/preview-app/src/app/docs/docs.component.ts index 4ac6a467..6f723907 100644 --- a/angular/devkit/preview/preview-app/preview-app/src/app/docs/docs.component.ts +++ b/angular/devkit/preview/preview-app/preview-app/src/app/docs/docs.component.ts @@ -1,5 +1,32 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { Component, Input, ViewChild, ElementRef } from '@angular/core'; +import { isPlatformBrowser } from '@angular/common'; +import { AfterViewChecked, Component, ElementRef, Inject, Input, PLATFORM_ID, ViewChild } from '@angular/core'; + +// importing prismjs order is important! +import 'prismjs'; + +import 'prismjs/plugins/toolbar/prism-toolbar'; + +import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard'; +import 'prismjs/plugins/line-numbers/prism-line-numbers'; +import 'prismjs/plugins/show-language/prism-show-language'; + +import 'prismjs/components/prism-csharp'; +import 'prismjs/components/prism-css'; +import 'prismjs/components/prism-java'; +import 'prismjs/components/prism-javascript'; +import 'prismjs/components/prism-json'; +import 'prismjs/components/prism-markup'; +import 'prismjs/components/prism-python'; +import 'prismjs/components/prism-sass'; +import 'prismjs/components/prism-scss'; +import 'prismjs/components/prism-sql'; +import 'prismjs/components/prism-typescript'; +import 'prismjs/components/prism-visual-basic'; +import 'prismjs/components/prism-xml-doc'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +declare const Prism: any; @Component({ selector: 'app-docs', @@ -7,8 +34,29 @@ import { Component, Input, ViewChild, ElementRef } from '@angular/core'; template: `
`, styleUrls: ['./docs.style.scss'], }) -export class DocsComponent { +export class DocsComponent implements AfterViewChecked { @ViewChild('docsRoot', { static: true }) docsRoot!: ElementRef; @Input() template = ''; + + highlighted = false; + + constructor(@Inject(PLATFORM_ID) private platformId: object) {} + + ngAfterViewChecked() { + if (!this.highlighted && isPlatformBrowser(this.platformId)) { + this.highlightHtml(); + this.highlighted = true; + } + } + + highlightHtml() { + const codeElements = this.docsRoot.nativeElement.querySelectorAll('pre[data-language]'); + codeElements.forEach((el: HTMLElement) => { + const lang = el.getAttribute('data-language')?.replace('language-', '') || 'javascript'; + el.setAttribute('class', `language-${lang}`); + // eslint-disable-next-line no-param-reassign + el.innerHTML = Prism.highlight(el.textContent || '', Prism.languages[lang], lang); + }); + } } diff --git a/angular/devkit/preview/preview-app/preview-app/src/favicon.ico b/angular/devkit/preview/preview-app/preview-app/src/favicon.ico deleted file mode 100644 index 997406ad..00000000 Binary files a/angular/devkit/preview/preview-app/preview-app/src/favicon.ico and /dev/null differ diff --git a/angular/devkit/preview/preview-app/preview-app/src/index.html b/angular/devkit/preview/preview-app/preview-app/src/index.html index 1fe4b1a0..3770417b 100644 --- a/angular/devkit/preview/preview-app/preview-app/src/index.html +++ b/angular/devkit/preview/preview-app/preview-app/src/index.html @@ -1,13 +1,13 @@ - - - Angular preview - - - - - -
- + + + Angular preview + + + + + +
+ diff --git a/angular/devkit/preview/preview-app/preview-app/src/main.ts b/angular/devkit/preview/preview-app/preview-app/src/main.ts index d48879c2..bba8a4a0 100644 --- a/angular/devkit/preview/preview-app/preview-app/src/main.ts +++ b/angular/devkit/preview/preview-app/preview-app/src/main.ts @@ -1,3 +1,4 @@ +import 'zone.js'; import { NgModuleRef } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; diff --git a/angular/devkit/preview/preview-app/preview-app/src/polyfills.ts b/angular/devkit/preview/preview-app/preview-app/src/polyfills.ts deleted file mode 100644 index 8827b010..00000000 --- a/angular/devkit/preview/preview-app/preview-app/src/polyfills.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * This file includes polyfills needed by Angular and is loaded before the app. - * You can add your own extra polyfills to this file. - * - * This file is divided into 2 sections: - * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. - * 2. Application imports. Files imported after ZoneJS that should be loaded before your main - * file. - * - * The current setup is for so-called "evergreen" browsers; the last versions of browsers that - * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), - * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. - * - * Learn more in https://angular.io/guide/browser-support - */ - -/** ************************************************************************************************* - * BROWSER POLYFILLS - */ - -/** - * IE11 requires the following for NgClass support on SVG elements - */ -// import 'classlist.js'; // Run `npm install --save classlist.js`. - -/** - * Web Animations `@angular/platform-browser/animations` - * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. - * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). - */ -// import 'web-animations-js'; // Run `npm install --save web-animations-js`. - -/** - * By default, zone.js will patch all possible macroTask and DomEvents - * user can disable parts of macroTask/DomEvents patch by setting following flags - * because those flags need to be set before `zone.js` being loaded, and webpack - * will put import in the top of bundle, so user need to create a separate file - * in this directory (for example: zone-flags.ts), and put the following flags - * into that file, and then add the following code before importing zone.js. - * import './zone-flags'; - * - * The flags allowed in zone-flags.ts are listed here. - * - * The following flags will work for all browsers. - * - * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame - * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick - * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames - * - * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js - * with the following flag, it will bypass `zone.js` patch for IE/Edge - * - * (window as any).__Zone_enable_cross_context_check = true; - * - */ - -/** ************************************************************************************************* - * Zone JS is required by default for Angular itself. - */ -import 'zone.js'; // Included with Angular CLI. - -/** ************************************************************************************************* - * APPLICATION IMPORTS - */ diff --git a/angular/devkit/preview/preview-app/preview-app/src/styles.scss b/angular/devkit/preview/preview-app/preview-app/src/styles.scss index 6c8a96c1..beaabfe6 100644 --- a/angular/devkit/preview/preview-app/preview-app/src/styles.scss +++ b/angular/devkit/preview/preview-app/preview-app/src/styles.scss @@ -1,2 +1,2 @@ /* You can add global styles to this file, and also import other style files */ -@import './styles/prism-theme-vsc-dark-plus'; +@use './styles/prism-theme-vsc-dark-plus'; diff --git a/angular/devkit/preview/preview-app/preview-app/tsconfig.app.json b/angular/devkit/preview/preview-app/preview-app/tsconfig.app.json index 7263ce21..a83d63aa 100644 --- a/angular/devkit/preview/preview-app/preview-app/tsconfig.app.json +++ b/angular/devkit/preview/preview-app/preview-app/tsconfig.app.json @@ -12,10 +12,9 @@ "importHelpers": true, "lib": [ "es2018", - "dom", - "esnext.asynciterable" + "dom" ], - "module": "esnext", + "module": "ES2022", "moduleResolution": "node", "noFallthroughCasesInSwitch": true, "noImplicitReturns": true, @@ -24,7 +23,10 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, - "target": "es5" + "target": "ES2022", + "types": [], + "useDefineForClassFields": true, + "esModuleInterop": true }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, @@ -34,13 +36,12 @@ "enableIvy": true }, "files": [ - "./src/main.ts", - "./src/polyfills.ts" + "./src/main.ts" ], "include": [ - "./src/app/**/*.ts", + "./src/**/*.ts" ], "exclude": [ - "./src/app/**/*.spec.ts" + "./src/**/*.spec.ts" ] } diff --git a/angular/devkit/preview/preview/component.json b/angular/devkit/preview/preview/component.json index 2f69f3d4..887d31e1 100644 --- a/angular/devkit/preview/preview/component.json +++ b/angular/devkit/preview/preview/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/preview/preview", - "version": "7.0.0" + "version": "97b6d79f2438864e11a05f1a96173e97062e632b" }, "propagate": false, "extensions": { @@ -28,14 +28,16 @@ } } }, - "bitdev.node/node-env@2.0.2": {}, - "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, "teambit.preview/preview": {}, "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "bitdev.node/node-env@2.0.40": {}, + "teambit.envs/envs": { + "env": "bitdev.node/node-env" + } } } diff --git a/angular/devkit/preview/runtime/component.json b/angular/devkit/preview/runtime/component.json index 51a98bab..bd40a2f4 100644 --- a/angular/devkit/preview/runtime/component.json +++ b/angular/devkit/preview/runtime/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/preview/runtime", - "version": "4.0.0" + "version": "dea3ae30f4ba75f535e40a4931c416655909316c" }, "propagate": false, "extensions": { @@ -20,14 +20,16 @@ } } }, - "bitdev.node/node-env@2.0.2": {}, - "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, "teambit.preview/preview": {}, "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "bitdev.node/node-env@2.0.40": {}, + "teambit.envs/envs": { + "env": "bitdev.node/node-env" + } } } diff --git a/angular/devkit/preview/runtime/loader.ts b/angular/devkit/preview/runtime/loader.ts index a155383f..b5791d16 100644 --- a/angular/devkit/preview/runtime/loader.ts +++ b/angular/devkit/preview/runtime/loader.ts @@ -1,4 +1,5 @@ /* eslint-disable */ +// @ts-ignore import './native-shim.cjs'; import { Injector, NgModuleRef, Type } from '@angular/core'; import { createCustomElement } from '@angular/elements'; diff --git a/angular/devkit/preview/vite-preview/angular-vite-preview.ts b/angular/devkit/preview/vite-preview/angular-vite-preview.ts new file mode 100644 index 00000000..7160f3b9 --- /dev/null +++ b/angular/devkit/preview/vite-preview/angular-vite-preview.ts @@ -0,0 +1,164 @@ +import { + ApplicationOptions, + BrowserOptions, + DevServerOptions, + isAppBuildContext +} from '@bitdev/angular.dev-services.common'; +import { NgViteBundler, NgViteDevServer } from '@bitdev/angular.dev-services.vite'; +import { Bundler, BundlerContext, DevServer, DevServerContext } from '@teambit/bundler'; +import { AsyncEnvHandler, EnvContext, EnvHandler } from '@teambit/envs'; +import { EnvPreviewConfig, Preview } from '@teambit/preview'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import objectHash from 'object-hash'; +// Make sure bit recognizes the dependencies +import 'webpack-dev-server'; + +interface AngularVitePreviewOptions { + /** + * Override the default Angular docs template path + */ + docsTemplatePath?: string; + + /** + * Deps that will be bundled with the env template and will be configured as externals for the component bundle. + * These dependencies will be available in the preview as singletons. + */ + hostDependencies?: string[]; + + /** + * Override the default Angular mount path + */ + mounterPath?: string; + + /** + * Name of the angular preview. + */ + name?: string; + + /** + * Configuration for the preview. + */ + previewConfig?: EnvPreviewConfig; + + /** + * Angular options for `bit run` + */ + angularServeOptions?: Partial<(BrowserOptions | ApplicationOptions) & DevServerOptions>; + + /** + * Angular options for `bit build` + */ + angularBuildOptions?: Partial<(BrowserOptions | ApplicationOptions)>; + + /** + * The root of the source files, assets and index.html file structure. + */ + sourceRoot?: string; +} + +export function getPreviewRootPath(): string { + const appPath = dirname(fileURLToPath(import.meta.resolve('@bitdev/angular.dev-services.preview.preview-app'))); + // appPath is the path of the current file in dist + // but we want the preview app source code files (.ts) which are located in the parent directory + return resolve(join(appPath, '../preview-app/')); +} + + +export class AngularVitePreview implements Preview { + private constructor( + readonly name: string, + private angularServeOptions: Partial<(BrowserOptions | ApplicationOptions) & DevServerOptions> = {}, + private angularBuildOptions: Partial<(BrowserOptions | ApplicationOptions)> = {}, + private docsTemplatePath: string = fileURLToPath(import.meta.resolve('./docs.js')), + private mounterPath: string = fileURLToPath(import.meta.resolve('./mounter.js')), + private previewConfig: EnvPreviewConfig = {}, + private hostDependencies?: string[], + private sourceRoot?: string, + ) { + } + + getDevServer(context: DevServerContext): AsyncEnvHandler { + const appRootPath = getPreviewRootPath(); + return NgViteDevServer.from({ + angularOptions: this.angularServeOptions, + devServerContext: context, + sourceRoot: this.sourceRoot, + appRootPath + }); + } + + getDevEnvId() { + const objToHash = { + name: this.name, + docsTemplatePath: this.docsTemplatePath, + mounterPath: this.mounterPath, + previewConfig: this.previewConfig, + }; + return objectHash(objToHash); + } + + getBundler(context: BundlerContext): AsyncEnvHandler { + let appRootPath: string; + if (isAppBuildContext(context)) { // When you use `bit build` for an actual angular app + appRootPath = context.capsule.path; + } else { // When you use `bit build` for the preview app + appRootPath = getPreviewRootPath(); + } + return NgViteBundler.from({ + angularOptions: this.angularBuildOptions, + bundlerContext: context, + sourceRoot: this.sourceRoot, + appRootPath + }); + } + + /** + * Dependencies to be bundled only once, in the env preview template, and not in each component preview. + * most of your peer dependencies should be listed here to avoid duplications in the preview. + * React, ReactDOM, and MDX are included as they are part of the preview ui. + */ + getHostDependencies(): string[] { + return ( + this.hostDependencies || [ + '@teambit/mdx.ui.mdx-scope-context', + '@mdx-js/react', + 'react', + 'react-dom' + ] + ); + } + + getMounter(): string { + return this.mounterPath; + } + + getDocsTemplate(): string { + return this.docsTemplatePath; + } + + getPreviewConfig(): EnvPreviewConfig & { isScaling?: boolean } { + return { + strategyName: 'env', + // splitComponentBundle: true, + // isScaling: true, + ...this.previewConfig + }; + } + + static from(options: AngularVitePreviewOptions): EnvHandler { + const name = options.name || 'angular-preview'; + return (_context: EnvContext) => { + return new AngularVitePreview( + name, + options.angularServeOptions, + options.angularBuildOptions, + options.docsTemplatePath, + options.mounterPath, + options.previewConfig, + options.hostDependencies, + options.sourceRoot, + ); + }; + } +} diff --git a/angular/devkit/preview/vite-preview/component.json b/angular/devkit/preview/vite-preview/component.json new file mode 100644 index 00000000..ca349ec3 --- /dev/null +++ b/angular/devkit/preview/vite-preview/component.json @@ -0,0 +1,28 @@ +{ + "componentId": { + "scope": "bitdev.angular", + "name": "dev-services/preview/vite-preview", + "version": "1.0.1" + }, + "propagate": false, + "extensions": { + "teambit.dependencies/dependency-resolver": { + "policy": { + "peerDependencies": { + "@angular/core": ">= 16.0.0" + } + } + }, + "teambit.component/dev-files": {}, + "teambit.pkg/pkg": {}, + "teambit.preview/preview": {}, + "teambit.compositions/compositions": {}, + "teambit.docs/docs": {}, + "teambit.pipelines/builder": {}, + "teambit.semantics/schema": {}, + "bitdev.node/node-env@2.0.40": {}, + "teambit.envs/envs": { + "env": "bitdev.node/node-env" + } + } +} diff --git a/angular/devkit/preview/vite-preview/docs.ts b/angular/devkit/preview/vite-preview/docs.ts new file mode 100644 index 00000000..2a31e8d4 --- /dev/null +++ b/angular/devkit/preview/vite-preview/docs.ts @@ -0,0 +1,34 @@ +import type { RenderingContext } from '@teambit/preview'; +// @ts-ignore +import type { Type } from '@angular/core'; +import { ReplaySubject } from 'rxjs'; + +window.onDocsLoad$ = window.onDocsLoad$ || new ReplaySubject(); +const root = document.getElementById('root'); + +export type DocsFile = { + default: string; +}; + +export type DocsRootProps = { + Provider: Type | undefined, + componentId: string, + docs: DocsFile | string | undefined, + compositions: { [key: string]: any }, + context: RenderingContext +} + +async function docsRoot({docs}: DocsRootProps): Promise { + if (docs && root) { + const appRoot = document.createElement('app-root'); + root.replaceChildren(appRoot); + await window.ngMainStart(); + window.onDocsLoad$.next((docs as DocsFile).default ?? docs as string); + } +} + +// Add support for new api signature +// TODO: remove by the end of 2022 +docsRoot.apiObject = true; + +export default docsRoot; diff --git a/angular/devkit/preview/vite-preview/index.ts b/angular/devkit/preview/vite-preview/index.ts new file mode 100644 index 00000000..bd58b705 --- /dev/null +++ b/angular/devkit/preview/vite-preview/index.ts @@ -0,0 +1 @@ +export * from './angular-vite-preview.js'; diff --git a/angular/devkit/preview/vite-preview/mounter.ts b/angular/devkit/preview/vite-preview/mounter.ts new file mode 100644 index 00000000..60171057 --- /dev/null +++ b/angular/devkit/preview/vite-preview/mounter.ts @@ -0,0 +1,4 @@ +/* eslint-disable import/no-unresolved */ +import { createMounter } from '@bitdev/angular.dev-services.preview.mounter'; + +export default createMounter(); diff --git a/angular/devkit/preview/vite-preview/types.d.ts b/angular/devkit/preview/vite-preview/types.d.ts new file mode 100644 index 00000000..4962c903 --- /dev/null +++ b/angular/devkit/preview/vite-preview/types.d.ts @@ -0,0 +1,9 @@ +import type { NgModuleRef } from '@angular/core'; +import type { ReplaySubject } from 'rxjs'; + +declare global { + interface Window { + onDocsLoad$: ReplaySubject; + ngMainStart: () => Promise | void>; + } +} diff --git a/angular/app-types/angular-app-type/application.bundler.ts b/angular/devkit/vite/application.bundler.ts similarity index 73% rename from angular/app-types/angular-app-type/application.bundler.ts rename to angular/devkit/vite/application.bundler.ts index 7ae238c0..8862b196 100644 --- a/angular/app-types/angular-app-type/application.bundler.ts +++ b/angular/devkit/vite/application.bundler.ts @@ -1,34 +1,44 @@ /* eslint-disable no-param-reassign */ import { OutputHashing } from '@angular-devkit/build-angular'; import { VERSION } from '@angular/cli'; -import { dedupPaths, getLoggerApi, normalizePath } from '@bitdev/angular.dev-services.common'; +import { ApplicationOptions, dedupePaths, getLoggerApi, normalizePath } from '@bitdev/angular.dev-services.common'; import { type ApplicationBuilderOptions, buildApplicationInternal } from '@bitdev/angular.dev-services.ng-compat'; import { Logger } from '@teambit/logger'; import assert from 'assert'; +import { nodeModulesPolyfillPlugin } from 'esbuild-plugins-node-modules-polyfill'; import fs from 'fs-extra'; // @ts-ignore import type { NitroConfig } from 'nitropack'; import { fileURLToPath } from 'node:url'; import { basename, extname, join, posix, relative, resolve } from 'path'; +import dedupePlugin from "./plugins/dedupe.plugin.js"; import definePlugin from './plugins/define.plugin.js'; -import { getIndexInputFile } from './utils.js'; +import mdPlugin from "./plugins/md.plugin.js"; +import { getIndexInputFile } from './utils/utils.js'; export type BuildApplicationOptions = { - angularOptions: Partial; + angularOptions: Partial; outputPath: string; sourceRoot: string; workspaceRoot: string; logger: Logger; tempFolder: string; entryServer?: string; - envVars: any; + envVars?: any; + isPreview?: boolean; +} + +export type BuildOutput = { + success: boolean; + error?: string; } // TODO allow customizing this const BUILDER_NAME = '@angular-devkit/build-angular:application'; +const CACHE_PATH = 'angular/cache'; -export async function buildApplication(options: BuildApplicationOptions): Promise { - const { angularOptions: { tsConfig, server, define }, envVars } = options; +export async function buildApplication(options: BuildApplicationOptions): Promise { + const { angularOptions: { tsConfig, server, define }, envVars, isPreview } = options; assert(tsConfig, 'tsConfig option is required'); const isSsr = !!server && Number(VERSION.major) >= 17; if (isSsr && Number(VERSION.major) < 19) { @@ -36,17 +46,36 @@ export async function buildApplication(options: BuildApplicationOptions): Promis } const appOptions = getAppOptions(options, isSsr); const builderContext = getBuilderContext(options, appOptions); - const codePlugins = [definePlugin({ ...envVars, ...define || {} })]; - const extensions: any = (Number(VERSION.major) >= 17 && Number(VERSION.minor) >= 1) ? { codePlugins } : []; - - for await (const result of buildApplicationInternal( - appOptions as any, - builderContext, - { write: true }, - extensions - )) { - if (!result.success && result.errors) { - throw new Error(result.errors.map((err: any) => err.text).join('\n')); + const extensions: any = { codePlugins: [dedupePlugin()] }; + if (isPreview) { + extensions.codePlugins.push(mdPlugin(), nodeModulesPolyfillPlugin()); + } else if ((Number(VERSION.major) >= 17 && Number(VERSION.minor) >= 1)) { + extensions.codePlugins.push(definePlugin({ ...envVars, ...define || {} })); + } + + let results: AsyncGenerator; + // todo use buildApplication + if (Number(VERSION.major) >= 18) { + results = buildApplicationInternal( + appOptions, + builderContext, + extensions + ) + } else { + results = buildApplicationInternal( + appOptions, + builderContext, + { write: true }, + // @ts-ignore only v18+ has 3 arguments, previous versions had 4 + extensions + ) + } + + const res: BuildOutput[] = []; + for await (const result of results) { + res.push(result); + if (result.error) { + options.logger.error(result.error); } } @@ -54,6 +83,8 @@ export async function buildApplication(options: BuildApplicationOptions): Promis if (isSsr && Number(VERSION.major) < 19) { await buildNitro(options); } + + return res; } function addEntryServer(options: BuildApplicationOptions): void { @@ -96,8 +127,8 @@ function getAppOptions(options: BuildApplicationOptions, isSsr: boolean): Applic const normalizedBrowser = `./${join(sourceRoot, 'main.ts')}`; const serverPath = `./${join(sourceRoot, 'main.server.ts')}`; - const dedupedAssets = dedupPaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]); - const dedupedStyles = dedupPaths([posix.join(sourceRoot, `styles.${angularOptions.inlineStyleLanguage}`), ...(angularOptions.styles ?? [])]); + const dedupedAssets = dedupePaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]); + const dedupedStyles = dedupePaths([posix.join(sourceRoot, `styles.${angularOptions.inlineStyleLanguage}`), ...(angularOptions.styles ?? [])]); return { ...angularOptions, @@ -111,24 +142,31 @@ function getAppOptions(options: BuildApplicationOptions, isSsr: boolean): Applic styles: dedupedStyles, scripts: angularOptions.scripts, namedChunks: angularOptions.namedChunks ?? true, - optimization: false,//angularOptions.optimization ?? true, + optimization: angularOptions.optimization ?? true, aot: true, deleteOutputPath: true, sourceMap: angularOptions.sourceMap ?? true, - outputHashing: OutputHashing.None,//angularOptions.outputHashing ?? OutputHashing.All, + outputHashing: angularOptions.outputHashing ?? OutputHashing.All, watch: false, outputMode: angularOptions.outputMode ?? (isSsr ? 'server' : 'static'), server: isSsr ? angularOptions.server ?? serverPath : undefined, prerender: isSsr ? (angularOptions.prerender ?? !!angularOptions.server) : undefined, ssr: isSsr ? { entry: entryServer - } : undefined + } : undefined, + // @ts-ignore Angular 17-18 + browserTarget: BUILDER_NAME, + // @ts-ignore Angular 17+ + buildTarget: BUILDER_NAME, + // support for bit.cloud workspaces + host: "0.0.0.0" }; } function getBuilderContext(options: BuildApplicationOptions, appOptions: ApplicationBuilderOptions): any { - const { workspaceRoot, sourceRoot, tempFolder } = options; + const { workspaceRoot } = options; + const builderAbort = new AbortController(); return { id: 1, builder: { @@ -137,20 +175,16 @@ function getBuilderContext(options: BuildApplicationOptions, appOptions: Applica optionSchema: {} }, logger: getLoggerApi(options.logger), + signal: builderAbort.signal, workspaceRoot: workspaceRoot, currentDirectory: '', // doesn't matter, just needs to exist target: { project: 'bit-ng-app-builder', - target: 'build' - }, - getProjectMetadata: function (): Promise { - return Promise.resolve({ - root: '', - sourceRoot, - cli: { cache: { enabled: true, path: resolve(tempFolder, 'angular/cache') } } - }); + // target: 'build' + target: 'development' }, + getProjectMetadata: getProjectMetadata(options), addTeardown: () => { }, getBuilderNameForTarget: () => Promise.resolve(BUILDER_NAME), @@ -159,6 +193,22 @@ function getBuilderContext(options: BuildApplicationOptions, appOptions: Applica }; } +function getProjectMetadata(options: BuildApplicationOptions) { + const { sourceRoot, tempFolder } = options; + return function (): Promise { + return Promise.resolve({ + root: '', + sourceRoot, + cli: { + cache: { + enabled: true, + path: resolve(tempFolder, CACHE_PATH) + } + } + }); + }; +} + async function getNitroConfig(options: BuildApplicationOptions): Promise { const { workspaceRoot, @@ -173,7 +223,7 @@ async function getNitroConfig(options: BuildApplicationOptions): Promise; + angularOptions: Partial; sourceRoot: string; workspaceRoot: string; logger: Logger; port: number; tempFolder: string; envVars: any; + indexHtmlTransform?: (content: string) => Promise; + isPreview?: boolean; } // TODO allow customizing this @@ -39,31 +49,42 @@ export async function serveApplication(options: ServeApplicationOptions): Promis const appOptions = getAppOptions(options, isSsr); const builderContext = getBuilderContext(options, appOptions); const devServerOptions: any = { - buildPlugins: [], + buildPlugins: [dedupePlugin()], middleware: [] }; + if (options.isPreview) { + devServerOptions.buildPlugins.push(mdPlugin(), nodeModulesPolyfillPlugin()); + } if (isSsr) { - devServerOptions.buildPlugins = [definePlugin({ ...envVars, ...define })]; + devServerOptions.buildPlugins.push(definePlugin({ ...envVars, ...define })); // Versions of Angular <19 require a nitro middleware to support SSR API endpoints if (Number(VERSION.major) < 19) { devServerOptions.middleware = [await createNitroApiMiddleware(options)]; } } + const transforms = { + indexHtml: options.indexHtmlTransform + }; - // @ts-ignore only v17+ has 4 arguments, previous versions only have 3 - await executeDevServerBuilder(appOptions, builderContext as any, undefined, devServerOptions).toPromise(); + if (Number(VERSION.major) > 17 || (Number(VERSION.major) == 17 && Number(VERSION.minor) >= 1)) { + // @ts-ignore only v17.1.0+ has 4 arguments, previous versions only have 3 + await executeDevServerBuilder(appOptions, builderContext as any, transforms, devServerOptions).toPromise(); + } else { + // @ts-ignore only v17.1.0+ has 4 arguments, previous versions only have 3 + await executeDevServerBuilder(appOptions, builderContext as any, devServerOptions).toPromise(); + } } -function getAppOptions(options: ServeApplicationOptions, isSsr: boolean): ApplicationBuilderOptions & DevServerBuilderOptions { +function getAppOptions(options: ServeApplicationOptions, isSsr: boolean): /*ApplicationBuilderOptions & DevServerBuilderOptions*/ any { const { angularOptions, port, sourceRoot, workspaceRoot } = options; // declare constants for all reusable values here const normalizedIndex = `./${join(sourceRoot, 'index.html')}`; const normalizedBrowser = `./${join(sourceRoot, 'main.ts')}`; const serverPath = `./${join(sourceRoot, 'main.server.ts')}`; - const dedupedAssets = dedupPaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]); - const dedupedStyles = dedupPaths([posix.join(sourceRoot, `styles.${angularOptions.inlineStyleLanguage}`), ...(angularOptions.styles ?? [])]); + const dedupedAssets = dedupePaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]); + const dedupedStyles = dedupePaths([posix.join(sourceRoot, `styles.${angularOptions.inlineStyleLanguage}`), ...(angularOptions.styles ?? [])]); return { ...angularOptions, @@ -71,7 +92,7 @@ function getAppOptions(options: ServeApplicationOptions, isSsr: boolean): Applic preserveSymlinks: false, outputPath: OUTPUT_PATH, index: angularOptions.index ?? normalizedIndex, - browser: angularOptions.browser ?? normalizedBrowser, + browser: angularOptions.browser ?? (angularOptions.entryPoints ? undefined : normalizedBrowser), tsConfig: relative(workspaceRoot, angularOptions.tsConfig!), assets: dedupedAssets, styles: dedupedStyles, @@ -87,9 +108,10 @@ function getAppOptions(options: ServeApplicationOptions, isSsr: boolean): Applic hmr: angularOptions.hmr ?? false, outputMode: angularOptions.outputMode ?? (isSsr ? 'server' : 'static'), server: isSsr ? angularOptions.server ?? serverPath : undefined, - prerender: isSsr ? angularOptions.prerender ?? !!angularOptions.server : false, + prerender: isSsr && !angularOptions.outputMode ? angularOptions.prerender ?? !!angularOptions.server : undefined, ssr: isSsr ? (angularOptions.ssr ?? !!angularOptions.server) : false, port, + // @ts-ignore Angular 17-18 browserTarget: BUILDER_NAME, // @ts-ignore Angular 17+ buildTarget: BUILDER_NAME, @@ -108,7 +130,7 @@ function getBuilderContext(options: ServeApplicationOptions, appOptions: Applica description: 'Bit Angular Application Builder', optionSchema: {} }, - logger: getLoggerApi(options.logger), + logger: getLoggerApi(options.logger, options.isPreview), signal: builderAbort.signal, workspaceRoot: workspaceRoot, currentDirectory: '', diff --git a/angular/devkit/vite/component.json b/angular/devkit/vite/component.json index 0d1ad0e9..9a8cc2da 100644 --- a/angular/devkit/vite/component.json +++ b/angular/devkit/vite/component.json @@ -1,33 +1,32 @@ { "componentId": { "scope": "bitdev.angular", - "name": "dev-services/vite" + "name": "dev-services/vite", + "version": "2.0.1" }, - "propagate": true, + "propagate": false, "extensions": { "teambit.dependencies/dependency-resolver": { "policy": { "dependencies": { - "@analogjs/platform": "-", - "@teambit/node.deps-detectors.detective-es6": "0.0.5", - "@teambit/vite.vite-bundler": "*", - "@teambit/vite.vite-dev-server": "*", - "@types/express": "^4.17.17", - "@types/memoizee": "0.4.5", - "find-root": "1.1.0", - "memoizee": "0.4.15", - "parse5-html-rewriting-stream": "7.0.0" - }, - "devDependencies": { - "@types/find-root": "1.1.2", - "@types/node": "12.20.4" + "#alias": "-", + "h3": "^1.9.0", + "nitropack": "^2.8.0", + "@angular-devkit/build-angular": "-", + "@angular/cli": "-", + "typescript": "-" }, "peerDependencies": { - "@analogjs/platform": ">= 0.2.22", - "@angular/common": ">= 13.0.0", - "vite": "5.0.0" + "@angular-devkit/build-angular": ">= 0.0.1", + "@angular/cli": ">= 13.0.0", + "esbuild": ">= 0.14.0", + "typescript": ">= 3.5.3" } } + }, + "bitdev.node/node-env@2.0.40": {}, + "teambit.envs/envs": { + "env": "bitdev.node/node-env" } } } diff --git a/angular/devkit/vite/config.factory.ts b/angular/devkit/vite/config.factory.ts deleted file mode 100644 index 6ef6a3f4..00000000 --- a/angular/devkit/vite/config.factory.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { default as analog } from '@analogjs/platform'; -import { isAppBuildContext, normalizePath } from '@bitdev/angular.dev-services.common'; -import { BundlerContext, DevServerContext } from '@teambit/bundler'; -import { CACHE_ROOT } from '@teambit/legacy/dist/constants'; -import assert from 'assert'; -import { basename, extname, join, posix, resolve } from 'path'; -// @ts-ignore -import type { InlineConfig } from 'vite'; -import { getIndexInputFile, htmlPlugin } from './plugins/index-html.plugin'; -import { BuildMode, NgViteOptions, ViteAspectsContext } from './utils/types'; -import { joinPathFragments } from './utils/utils'; - -type ConfigFactoryOptions = NgViteOptions & { context: DevServerContext | BundlerContext }; - - -const SSR_DIR = 'ssr'; -const BROWSER_DIR = 'browser'; - -/** - * Generate Vite configuration object based on provided options. - * - * @param {ConfigFactoryOptions} options - The options for generating the configuration. - * @param {ViteAspectsContext} aspectContext - The context object for Vite aspects. - * @return {Promise} - The generated Vite configuration object. - */ -export async function configFactory( - options: ConfigFactoryOptions, - aspectContext: ViteAspectsContext -): Promise { - const { mergeConfig } = await import('vite'); - const { - angularOptions: { tsConfig, index }, - context: { rootPath, envRuntime }, - context, - name, - outputPath - } = options; - assert(rootPath, 'rootPath is required'); - assert(outputPath, 'outputPath is required'); - const { workspace } = aspectContext; - const idName = `${ envRuntime.id }/${ name }`; - const tempFolder = workspace ? workspace.getTempDir(idName) : join(CACHE_ROOT, idName); - const indexPath = getIndexInputFile(index!); - const browserDir = normalizePath(resolve(outputPath, BROWSER_DIR)); - const ssrDir = normalizePath(resolve(outputPath, SSR_DIR)); - - assert(isAppBuildContext(context), 'Angular vite only support apps for now'); - let appRootPath: string; - const capsule = (options.context as any).capsule; - if (capsule) { - appRootPath = capsule.path; - } else { - appRootPath = workspace?.componentDir(context.appComponent.id, { - ignoreVersion: true - }) || ''; - } - const tsconfigPath = tsConfig ?? posix.join(appRootPath, 'tsconfig.app.json'); - - const baseConfig = createBaseConfig(options, tsconfigPath, tempFolder, browserDir, ssrDir, appRootPath, indexPath); - const serverConfig = await createServerConfig(rootPath); - const buildConfig = createBuildConfig(browserDir, appRootPath, indexPath); - const testConfig = createTestConfig(); - - return mergeConfig( - baseConfig, - { - build: buildConfig - //server: serverConfig, - //test: testConfig - } - ); -} - -function createBaseConfig(options: ConfigFactoryOptions, tsconfigPath: string, tempFolder: string, browserDir: string, ssrDir: string, appRootPath: string, indexPath: string) { - const { - angularOptions: { baseHref, server, ssr }, - angularOptions, - context: { rootPath }, - buildMode, - outputPath, - sourceRoot - } = options; - - assert(rootPath, 'rootPath is required'); - assert(outputPath, 'outputPath is required'); - - // TODO: fix this - const entryServer = ''; //(ssr as SsrClass)?.entry as string; - - const baseConfig: InlineConfig = { - // publicDir: 'src/assets', // todo - root: join(appRootPath, sourceRoot || 'src'), - base: baseHref ?? './', - mode: buildMode, - resolve: { - mainFields: ['module'] - }, - define: { - 'import.meta.vitest': buildMode !== BuildMode.Production - }, - plugins: [ - analog({ - vite: { - tsconfig: tsconfigPath - }, - ssr: !!server, - ssrBuildDir: ssr ? ssrDir : undefined, - entryServer: resolve(appRootPath, entryServer), - nitro: { - alias: ssr ? { - '#analog/ssr': join(ssrDir, basename(entryServer, extname(entryServer))), - '#analog/index': join(browserDir, basename(indexPath)) - } : {}, - serverAssets: ssr ? [{ - baseName: 'public', - dir: browserDir - }] : [], - publicAssets: ssr ? [{ - dir: browserDir - }] : [], - output: ssr ? { - dir: normalizePath(resolve(outputPath, 'server')), - publicDir: normalizePath(resolve(outputPath, 'server/public')) - } : {}, - buildDir: normalizePath(resolve(tempFolder, 'nitro')), - prerender: { - concurrency: 4 - } - }, - index: indexPath, - workspaceRoot: appRootPath - }) - ] - }; - - if (server) { - // When running the ssr dev server, CTRL+C doesn't seem to work anymore (bug in nitro?) - // This is a workaround to make sure the process exits when CTRL+C is pressed - process.on('SIGINT', () => process.exit(1)); - } //else { - // When we are not using ssr, we need to add the html plugin to generate the index.html file - baseConfig.plugins!.push(htmlPlugin(angularOptions, rootPath!, indexPath, !!ssr)); - //} - return baseConfig; -} - -async function createServerConfig(rootPath: string) { - const { searchForWorkspaceRoot } = await import('vite'); - return { - fs: { - allow: [ - searchForWorkspaceRoot(joinPathFragments(rootPath)), - joinPathFragments('.', 'node_modules/vite') - ] - } - }; -} - -function createBuildConfig(browserDir: string, appRootPath: string, indexPath: string) { - return { - target: ['es2020'], - outDir: browserDir, - emptyOutDir: true, - reportCompressedSize: true, - commonjsOptions: { - transformMixedEsModules: true - } - }; -} - -function createTestConfig() { - return { - globals: true, - environment: 'jsdom', - setupFiles: ['src/test.ts'], - include: ['**/*.spec.ts'] - }; -} - - - - diff --git a/angular/devkit/vite/index.ts b/angular/devkit/vite/index.ts index ca5e622d..cfe21050 100644 --- a/angular/devkit/vite/index.ts +++ b/angular/devkit/vite/index.ts @@ -1,3 +1,5 @@ -export * from './ng-vite.dev-server'; -export * from './ng-vite.bundler'; -export * from './utils/types'; +export * from './ng-vite.dev-server.js'; +export * from './ng-vite.bundler.js'; +export * from './application.dev-server.js'; +export * from './application.bundler.js'; +export * from './utils/utils.js'; diff --git a/angular/devkit/vite/ng-vite.bundler.ts b/angular/devkit/vite/ng-vite.bundler.ts index 3586c0d8..926602e4 100644 --- a/angular/devkit/vite/ng-vite.bundler.ts +++ b/angular/devkit/vite/ng-vite.bundler.ts @@ -1,35 +1,151 @@ -import type { Bundler, BundlerContext } from '@teambit/bundler'; +import { OutputHashing } from '@angular-devkit/build-angular'; +import { ApplicationInternalOptions, getWorkspace, normalizePath } from "@bitdev/angular.dev-services.common"; +import type { Bundler, BundlerContext, BundlerResult, Target } from '@teambit/bundler'; +import type { Component } from '@teambit/component'; +import { DependencyResolverAspect, type DependencyResolverMain } from '@teambit/dependency-resolver'; +import { DevFilesAspect, type DevFilesMain } from "@teambit/dev-files"; import type { AsyncEnvHandler, EnvContext } from '@teambit/envs'; -import { Logger } from '@teambit/logger'; -import { ViteBundler, ViteBundlerOptions } from '@teambit/vite.vite-bundler'; +import type { Logger } from '@teambit/logger'; import type { Workspace } from '@teambit/workspace'; -// @ts-ignore -import type { InlineConfig } from 'vite'; -import { configFactory } from './config.factory'; -import { NgViteOptions } from './utils/types'; - -export class NgViteBundler { - - static from(options: NgViteOptions & { context: BundlerContext }): AsyncEnvHandler { - return async(context: EnvContext): Promise => { - options.name = options.name || 'ng-vite-bundler'; - const logger: Logger = context.createLogger(options.name); - const workspace: Workspace = context.getAspect('teambit.workspace/workspace'); - - const ngConfig = await configFactory(options, { logger, workspace }); - // @ts-ignore - const transformer: any = (config: InlineConfig, vite: typeof import('vite')): InlineConfig => { - return vite.mergeConfig(config, ngConfig); +import assert from "assert"; +import fs from "fs-extra"; +import { findScopePath } from '@teambit/scope.modules.find-scope-path'; +import { join, posix, resolve } from "path"; +import { buildApplication } from "./application.bundler.js"; +import { NgViteOptions } from "./utils/types.js"; +import { fixEntries, generateAppTsConfig, generateMainEntryFile } from "./utils/utils.js"; + +const DEFAULT_SERVER_NAME = 'ng-vite-dev-server'; + +export class NgViteBundler implements Bundler { + idName: string; + + constructor( + public id: string, + private options: NgViteOptions & { bundlerContext: BundlerContext }, + private logger: Logger, + private depsResolver: DependencyResolverMain, + private devFilesMain: DevFilesMain, + private workspace?: Workspace + ) { + this.idName = `bitdev.angular/${this.id}`; + } + + getComponents(targets: Target[], outputPath: string): Component[] { + const path = outputPath.substring(0, outputPath.lastIndexOf(posix.sep)); + const target = targets.find((targetCandidate) => path === targetCandidate.outputPath); + + assert(target, `Could not find target for path "${outputPath}"`); + + return target.components as any as Component[]; + } + + private getTempFolder(idName: string, path = process.cwd()): string { + const scopePath = findScopePath(path); + assert(scopePath, `Unable to find scope path`); + const tempFolder = join(scopePath, 'tmp', 'preview-entries', idName); + + if (!fs.existsSync(tempFolder)) { + fs.mkdirSync(tempFolder, { recursive: true }); + } + return tempFolder; + } + + async run(): Promise { + const componentsOutput: BundlerResult[] = []; + const targets = this.options.bundlerContext.targets; + const startTime = Date.now(); + const longProcessLogger = this.logger.createLongProcessLogger('Running Angular ESBuild bundler', targets.length); + // this.logger.console('bundling components'); + + for (const target of targets) { + const components = this.options.bundlerContext.components; + const ids = components.map(component => component.id.toString()).join(', '); + + const fullMessage = `on ${components.length} component${components.length > 1 ? 's' : ''}`; + longProcessLogger.logProgress(fullMessage); + // this.logger.console(fullMessage); + this.logger.debug(`${fullMessage}\ncomponents ids: ${ids}`); + + const output: Pick = { + assets: [], + assetsByChunkName: {}, + entriesAssetsMap: {}, }; - const viteConfig: ViteBundlerOptions = { - bundlerContext: options.context as BundlerContext, - name: options.name, - resolveHostAlias: true, - transformers: [transformer, ...options.transformers ?? []] + // const tempFolder = this.getTempFolder(this.idName); + const tempFolder = target.outputPath; + const entries = fixEntries(tempFolder, target.entries as string[]); + const mainEntryFile = generateMainEntryFile(this.options.appRootPath, tempFolder, [...entries, resolve(join(this.options.appRootPath, 'src', 'main'))]); + + const angularOptions: ApplicationInternalOptions = { + baseHref: `./`, + optimization: false, + outputHashing: OutputHashing.None, + browser: mainEntryFile, + index: './src/index.html', + tsConfig: 'tsconfig.app.json', + assets: ['./src/favicon.ico', './src/assets'], + styles: ['./src/styles.scss'], + inlineStyleLanguage: "scss", + ssr: false, + // Disable the progress reporting with a loading spinner from Angular + progress: false }; - return ViteBundler.from(viteConfig)(context); + const appTsconfigPath = join(this.options.appRootPath, angularOptions.tsConfig); + const tsconfigPath = normalizePath(join(tempFolder, `tsconfig/tsconfig-${Date.now()}.json`)); + generateAppTsConfig(components, this.options.appRootPath, appTsconfigPath, tsconfigPath, this.depsResolver, this.workspace, [mainEntryFile], this.devFilesMain); + + const publicPath = join(target.outputPath, 'public'); + const results = await buildApplication({ + angularOptions: { + ...angularOptions, + tsConfig: tsconfigPath + }, + outputPath: publicPath, + sourceRoot: this.options.sourceRoot || 'src', + workspaceRoot: this.options.appRootPath, + logger: this.logger, + tempFolder: tempFolder, + isPreview: true + }); + + // Angular outputs the files into the public/browser folder, we need to move them to the root of the public folder + for(const file of fs.readdirSync(join(publicPath, 'browser'))) { + fs.moveSync(join(publicPath, 'browser', file), join(publicPath, file)); + } + // remove the browser folder + fs.removeSync(join(publicPath, 'browser')); + + const endTime = Date.now(); + + componentsOutput.push({ + components, + outputPath: join(target.outputPath, 'public'), + ...output, + errors: results.filter(result => !!result.error).map(result => result.error), + warnings: [], + startTime, + endTime, + } as any as BundlerResult); + } + + longProcessLogger.end(); + + return componentsOutput; + } + + static from(options: NgViteOptions & { bundlerContext: BundlerContext }): AsyncEnvHandler { + return async (context: EnvContext): Promise => { + const name = options.name || DEFAULT_SERVER_NAME; + const logger = context.createLogger(name); + const depsResolver = context.getAspect(DependencyResolverAspect.id); + const devFilesMain = context.getAspect(DevFilesAspect.id); + const preview = context.getAspect(DevFilesAspect.id); + const workspace = getWorkspace(context); + + return new NgViteBundler(name, options, logger, depsResolver, devFilesMain, workspace); }; } } diff --git a/angular/devkit/vite/ng-vite.dev-server.ts b/angular/devkit/vite/ng-vite.dev-server.ts index 9c5725f2..85809179 100644 --- a/angular/devkit/vite/ng-vite.dev-server.ts +++ b/angular/devkit/vite/ng-vite.dev-server.ts @@ -1,40 +1,106 @@ +import { OutputHashing } from '@angular-devkit/build-angular'; +import { + ApplicationInternalOptions, + type DevServerOptions, + getWorkspace, + normalizePath +} from "@bitdev/angular.dev-services.common"; import type { DevServer, DevServerContext } from '@teambit/bundler'; +import { DependencyResolverAspect, DependencyResolverMain } from '@teambit/dependency-resolver'; +import { DevFilesAspect, DevFilesMain } from "@teambit/dev-files"; import type { AsyncEnvHandler, EnvContext } from '@teambit/envs'; -import { ViteDevServer, ViteDevServerOptions } from '@teambit/vite.vite-dev-server'; -import { configFactory } from './config.factory'; -import { NgViteOptions } from './utils/types'; +import { Logger } from '@teambit/logger'; +import { findScopePath } from '@teambit/scope.modules.find-scope-path'; +import { Port } from '@teambit/toolbox.network.get-port'; +import type { Workspace } from '@teambit/workspace'; +import fs from "fs-extra"; +import { Server } from 'http'; +import assert from "node:assert"; +import { join, resolve } from "path"; +import { serveApplication } from "./application.dev-server.js"; +import { NgViteOptions } from './utils/types.js'; +import { fixEntries, generateAppTsConfig, generateMainEntryFile, getEnvFile } from "./utils/utils.js"; -// Extracted constant const DEFAULT_SERVER_NAME = 'ng-vite-dev-server'; -export class NgViteDevServer { - static from(options: NgViteOptions & { context: DevServerContext }): AsyncEnvHandler { - return async(context: EnvContext): Promise => { - options.name = options.name || DEFAULT_SERVER_NAME; - const logger = context.createLogger(options.name); - const workspace = context.getAspect('teambit.workspace/workspace'); +export class NgViteDevServer implements DevServer { + idName: string; - const ngConfig = await configFactory(options, { logger, workspace }); + constructor( + public id: string, + private options: NgViteOptions & { devServerContext: DevServerContext }, + private logger: Logger, + private depsResolver: DependencyResolverMain, + private devFilesMain: DevFilesMain, + private workspace?: Workspace + ) { + this.idName = `bitdev.angular/${this.id}`; + } + + private getTempFolder(idName: string, path = process.cwd()): string { + const scopePath = findScopePath(path); + assert(scopePath, `Unable to find scope path`); + const tempFolder = join(scopePath, 'tmp', 'preview-entries', idName); + + if (!fs.existsSync(tempFolder)) { + fs.mkdirSync(tempFolder, { recursive: true }); + } + return tempFolder; + } + + async listen(port: number): Promise { + assert(this.workspace, 'Workspace is not defined'); + const tempFolder = this.getTempFolder(this.idName, this.workspace.path); + const entries = fixEntries(tempFolder, this.options.devServerContext.entry); + const mainEntryFile = generateMainEntryFile(this.options.appRootPath, tempFolder, [...entries, resolve(join(this.options.appRootPath, 'src', 'main'))]); - // @ts-ignore - function transformer(config: any, vite: typeof import('vite')): any { - return vite.mergeConfig(config, ngConfig); + const angularOptions: ApplicationInternalOptions & DevServerOptions = { + baseHref: `/${this.options.devServerContext.rootPath}/`, + optimization: false, + outputHashing: OutputHashing.None, + browser: mainEntryFile, + index: './src/index.html', + tsConfig: 'tsconfig.app.json', + assets: ['./src/favicon.ico', './src/assets'], + styles: ['./src/styles.scss'], + inlineStyleLanguage: "scss", + buildTarget: 'development', + progress: false + }; + const envVars = await getEnvFile('development', this.options.appRootPath); + const appTsconfigPath = join(this.options.appRootPath, angularOptions.tsConfig); + const tsconfigPath = normalizePath(join(tempFolder, `tsconfig/tsconfig-${Date.now()}.json`)); + const workspaceCmpsIDs = this.workspace.listIds(); + const components = await this.workspace.getMany(workspaceCmpsIDs); + generateAppTsConfig(components, this.options.appRootPath, appTsconfigPath, tsconfigPath, this.depsResolver, this.workspace, [mainEntryFile], this.devFilesMain); + + // The returned Server is never used, so we can safely ignore the return type + return await serveApplication({ + angularOptions: { + ...angularOptions, + tsConfig: tsconfigPath + }, + sourceRoot: 'src', + workspaceRoot: this.options.appRootPath, + port: port || (await Port.getPortFromRange([3000, 4000])), + logger: this.logger, + tempFolder: tempFolder, + isPreview: true, + envVars: { + process: { env: envVars } } + }) as any as Server; + } + + static from(options: NgViteOptions & { devServerContext: DevServerContext }): AsyncEnvHandler { + return async (context: EnvContext): Promise => { + const name = options.name || DEFAULT_SERVER_NAME; + const logger = context.createLogger(name); + const depsResolver = context.getAspect(DependencyResolverAspect.id); + const devFilesMain = context.getAspect(DevFilesAspect.id); + const workspace = getWorkspace(context); - const viteConfig: ViteDevServerOptions = { - define: ngConfig.define, - devServerContext: options.context as DevServerContext, - name: options.name, - optimizeEntries: options.optimizeEntries as any, - plugins: ngConfig.plugins as any, - resolveHostAlias: true, - // Improved readability for transformers array - transformers: [ - transformer, ...(options.transformers ?? []) - ] - }; - - return ViteDevServer.from(viteConfig)(context); + return new NgViteDevServer(name, options, logger, depsResolver, devFilesMain, workspace); }; } } diff --git a/angular/devkit/vite/plugins/dedupe.plugin.ts b/angular/devkit/vite/plugins/dedupe.plugin.ts new file mode 100644 index 00000000..e10c1ce9 --- /dev/null +++ b/angular/devkit/vite/plugins/dedupe.plugin.ts @@ -0,0 +1,47 @@ +import { Plugin, PluginBuild, ResolveResult } from 'esbuild'; + +const DEDUPE_PACKAGE_RESOLUTION = Symbol('DEDUPE_PACKAGE_RESOLUTION'); +const resolvedPaths = new Map>(); + +function toESBuildFilter(packages: string[] = ['@angular/', '@ngrx/', 'apollo-angular']): RegExp { + const patterns = packages.map((pkg) => pkg.replace(/\//g, '[\\/]')); + const conditionalPatterns = patterns.join('|'); + return new RegExp(`^(${ conditionalPatterns })`); +} + +/** + * Creates a plugin that stores the first resolved path and returns it on subsequent requests, + * effectively deduping packages. + */ +export default function dedupePlugin(options?: { packages?: string[] }): Plugin { + const pattern = toESBuildFilter(options?.packages); + return { + name: 'dedupe-packages', + setup(build: PluginBuild) { + // Only attempt resolve of Angular packages for now + build.onResolve({ filter: pattern }, async args => { + if (args.pluginData?.[DEDUPE_PACKAGE_RESOLUTION]) { + return null; + } + if (resolvedPaths?.has(args.path)) { + return resolvedPaths.get(args.path); + } + + const { importer, kind, resolveDir, namespace, pluginData = {} } = args; + pluginData[DEDUPE_PACKAGE_RESOLUTION] = true; + + const result = build.resolve(args.path, { + importer, + kind, + namespace, + pluginData, + resolveDir, + }); + + resolvedPaths.set(args.path, result); + + return result; + }); + }, + }; +} diff --git a/angular/app-types/angular-app-type/plugins/define.plugin.ts b/angular/devkit/vite/plugins/define.plugin.ts similarity index 88% rename from angular/app-types/angular-app-type/plugins/define.plugin.ts rename to angular/devkit/vite/plugins/define.plugin.ts index 31e0cecc..43c7109f 100644 --- a/angular/app-types/angular-app-type/plugins/define.plugin.ts +++ b/angular/devkit/vite/plugins/define.plugin.ts @@ -1,4 +1,4 @@ -import { Plugin, PluginBuild } from 'esbuild'; +import { PluginBuild } from 'esbuild'; import { merge } from 'lodash-es'; export const stringifyDefine = (define: any) => { @@ -16,9 +16,8 @@ export default function(defineValues: any = {}) { // set variables on global so that they also work during ssr merge(global, defineValues); - const plugin: Plugin = { - name: 'env', - + return { + name: 'env-define', setup(build: PluginBuild) { const { platform, define = {} } = build.initialOptions; if (platform === 'node') { @@ -35,6 +34,4 @@ export default function(defineValues: any = {}) { }; } }; - - return plugin; } diff --git a/angular/devkit/vite/plugins/index-file/augment-index-html.ts b/angular/devkit/vite/plugins/index-file/augment-index-html.ts deleted file mode 100644 index d11a263f..00000000 --- a/angular/devkit/vite/plugins/index-file/augment-index-html.ts +++ /dev/null @@ -1,276 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import { loadEsmModule } from '@bitdev/angular.dev-services.common'; -import assert from 'assert'; -import { extname } from 'path'; -import { htmlRewritingStream } from './html-rewriting-stream'; -import { EntryPointsType } from './package-chunk-sort'; - -export type CrossOriginValue = 'none' | 'anonymous' | 'use-credentials'; - -export interface AugmentIndexHtmlOptions { - /* Input contents */ - html: string; - baseHref?: string; - deployUrl?: string; - /** crossorigin attribute setting of elements that provide CORS support */ - crossOrigin?: CrossOriginValue; - /** Used to sort the insertion of files in the HTML file */ - entrypoints: EntryPointsType[]; - /** Used to set the document default locale */ - lang?: string; - hints?: { url: string; mode: string; as?: string }[]; -} - -function isString(value: unknown): value is string { - return typeof value === 'string'; -} - -async function getLanguageDirectionFromLocales(locale: string): Promise { - try { - const localeData = ( - await loadEsmModule( - `@angular/common/locales/${locale}`, - ) - ).default; - - const dir = localeData[localeData.length - 2]; - - return isString(dir) ? dir : undefined; - } catch { - // In some cases certain locales might map to files which are named only with language id. - // Example: `en-US` -> `en`. - const [languageId] = locale.split('-', 1); - if (languageId !== locale) { - return getLanguageDirectionFromLocales(languageId); - } - } - - return undefined; -} - -async function getLanguageDirection( - locale: string, - warnings: string[], -): Promise { - const dir = await getLanguageDirectionFromLocales(locale); - - if (!dir) { - warnings.push( - `Locale data for '${locale}' cannot be found. 'dir' attribute will not be set for this locale.`, - ); - } - - return dir; -} - -function updateAttribute( - tag: { attrs: { name: string; value: string }[] }, - name: string, - value: string, -): void { - const index = tag.attrs.findIndex((a) => a.name === name); - const newValue = { name, value }; - - if (index === -1) { - tag.attrs.push(newValue); - } else { - // eslint-disable-next-line no-param-reassign - tag.attrs[index] = newValue; - } -} - -/* - * Helper function used by the IndexHtmlWebpackPlugin. - * Can also be directly used by builder, e.g. in order to generate an index.html - * after processing several configurations in order to build different sets of - * bundles for differential serving. - */ -export async function augmentIndexHtml( - params: AugmentIndexHtmlOptions, -): Promise<{ content: string; warnings: string[]; errors: string[] }> { - const { entrypoints, deployUrl = '', lang, baseHref, html } = params; - - const warnings: string[] = []; - const errors: string[] = []; - - const { crossOrigin = 'none' } = params; - - const stylesheets = new Set(); - const scripts = new Map(); - - // Sort files in the order we want to insert them by entrypoint - // eslint-disable-next-line no-restricted-syntax - for (const [file, isModule] of entrypoints) { - const extension = extname(file); - if (scripts.has(file) || stylesheets.has(file)) { - // eslint-disable-next-line no-continue - continue; - } - - switch (extension) { - case '.js': - case '.jsx': - case '.ts': - case '.tsx': - default: - // Also, non entrypoints need to be loaded as no module as they can contain problematic code. - scripts.set(file, isModule); - break; - case '.mjs': - case '.mts': - // It would be very confusing to link an `*.mjs` file in a non-module script context, - // so we disallow it entirely. - assert(isModule, '`.mjs` & `.mts` files *must* set `isModule` to `true`.'); - scripts.set(file, true /* isModule */); - break; - case '.css': - case '.scss': - case '.sass': - case '.less': - stylesheets.add(file); - break; - } - } - - let scriptTags: string[] = []; - // eslint-disable-next-line no-restricted-syntax - for (const [src, isModule] of scripts) { - const attrs = [`src="${deployUrl}${src}"`]; - - // This is also need for non-entry-points as they may contain problematic code. - if (isModule) { - attrs.push('type="module"'); - } else { - attrs.push('defer'); - } - - if (crossOrigin !== 'none') { - attrs.push(`crossorigin="${crossOrigin}"`); - } - - scriptTags.push(``); - } - - let linkTags: string[] = []; - // eslint-disable-next-line no-restricted-syntax - for (const src of stylesheets) { - const attrs = [`rel="stylesheet"`, `href="${deployUrl}${src}"`]; - - if (crossOrigin !== 'none') { - attrs.push(`crossorigin="${crossOrigin}"`); - } - - linkTags.push(``); - } - - if (params.hints?.length) { - // eslint-disable-next-line no-restricted-syntax - for (const hint of params.hints) { - const attrs = [`rel="${hint.mode}"`, `href="${deployUrl}${hint.url}"`]; - - if (hint.mode !== 'modulepreload' && crossOrigin !== 'none') { - // Value is considered anonymous by the browser when not present or empty - attrs.push(crossOrigin === 'anonymous' ? 'crossorigin' : `crossorigin="${crossOrigin}"`); - } - - if (hint.mode === 'preload' || hint.mode === 'prefetch') { - switch (extname(hint.url)) { - case '.js': - attrs.push('as="script"'); - break; - case '.css': - attrs.push('as="style"'); - break; - default: - if (hint.as) { - attrs.push(`as="${hint.as}"`); - } - break; - } - } - - linkTags.push(``); - } - } - - const dir = lang ? await getLanguageDirection(lang, warnings) : undefined; - const { rewriter, transformedContent } = await htmlRewritingStream(html); - const baseTagExists = html.includes(' { - // eslint-disable-next-line default-case - switch (tag.tagName) { - case 'html': - // Adjust document locale if specified - if (isString(lang)) { - updateAttribute(tag, 'lang', lang); - } - - if (dir) { - updateAttribute(tag, 'dir', dir); - } - break; - case 'head': - // Base href should be added before any link, meta tags - if (!baseTagExists && isString(baseHref)) { - rewriter.emitStartTag(tag); - rewriter.emitRaw(``); - - return; - } - break; - case 'base': - // Adjust base href if specified - if (isString(baseHref)) { - updateAttribute(tag, 'href', baseHref); - } - break; - } - - rewriter.emitStartTag(tag); - }) - .on('endTag', (tag) => { - // eslint-disable-next-line default-case - switch (tag.tagName) { - case 'head': - // eslint-disable-next-line no-restricted-syntax - for (const linkTag of linkTags) { - rewriter.emitRaw(linkTag); - } - - linkTags = []; - break; - case 'body': - // Add script tags - // eslint-disable-next-line no-restricted-syntax - for (const scriptTag of scriptTags) { - rewriter.emitRaw(scriptTag); - } - - scriptTags = []; - break; - } - - rewriter.emitEndTag(tag); - }); - - const content = await transformedContent(); - - return { - content: - linkTags.length || scriptTags.length - ? // In case no body/head tags are not present (dotnet partial templates) - linkTags.join('') + scriptTags.join('') + content - : content, - warnings, - errors, - }; -} diff --git a/angular/devkit/vite/plugins/index-file/html-rewriting-stream.ts b/angular/devkit/vite/plugins/index-file/html-rewriting-stream.ts deleted file mode 100644 index 6b1ec1c3..00000000 --- a/angular/devkit/vite/plugins/index-file/html-rewriting-stream.ts +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import { Readable, Writable } from 'stream'; -import { loadEsmModule } from '@bitdev/angular.dev-services.common'; - -export async function htmlRewritingStream(content: string): Promise<{ - rewriter: import('parse5-html-rewriting-stream').RewritingStream; - transformedContent: () => Promise; -}> { - const { RewritingStream } = await loadEsmModule( - 'parse5-html-rewriting-stream', - ); - const chunks: Buffer[] = []; - const rewriter = new RewritingStream(); - - return { - rewriter, - transformedContent: () => { - return new Promise((resolve) => { - new Readable({ - encoding: 'utf8', - read(): void { - this.push(Buffer.from(content)); - this.push(null); - }, - }) - .pipe(rewriter) - .pipe( - new Writable({ - write( - chunk: string | Buffer, - encoding: string | undefined, - callback: Function, - ): void { - chunks.push( - typeof chunk === 'string' - ? Buffer.from(chunk, encoding as BufferEncoding) - : chunk, - ); - callback(); - }, - final(callback: (error?: Error) => void): void { - callback(); - resolve(Buffer.concat(chunks).toString()); - }, - }), - ); - }); - }, - }; -} diff --git a/angular/devkit/vite/plugins/index-file/index-html-generator.ts b/angular/devkit/vite/plugins/index-file/index-html-generator.ts deleted file mode 100644 index 3330f4d5..00000000 --- a/angular/devkit/vite/plugins/index-file/index-html-generator.ts +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import * as fs from 'fs'; -import { join } from 'path'; -import { EntryPointsType } from './package-chunk-sort'; -import { stripBom } from './strip-bom'; -import { CrossOriginValue, augmentIndexHtml } from './augment-index-html'; - -type IndexHtmlGeneratorPlugin = ( - html: string, - options: IndexHtmlGeneratorProcessOptions, -) => Promise; - -export type HintMode = 'prefetch' | 'preload' | 'modulepreload' | 'preconnect' | 'dns-prefetch'; - -export interface IndexHtmlGeneratorProcessOptions { - lang: string | undefined; - baseHref: string | undefined; - hints?: { url: string; mode: HintMode; as?: string }[]; -} - -export interface IndexHtmlGeneratorOptions { - rootPath: string; - indexPath: string; - deployUrl?: string; - entrypoints: EntryPointsType[]; - crossOrigin?: CrossOriginValue; -} - -export interface IndexHtmlTransformResult { - content: string; - warnings: string[]; - errors: string[]; -} - -function augmentIndexHtmlPlugin(generator: IndexHtmlGenerator): IndexHtmlGeneratorPlugin { - const { deployUrl, crossOrigin, entrypoints } = generator.options; - - return async (html, options) => { - const { lang, baseHref, hints } = options; - - return augmentIndexHtml({ - html, - baseHref, - deployUrl, - crossOrigin, - lang, - entrypoints, - hints, - }); - }; -} - -export class IndexHtmlGenerator { - private readonly plugins: IndexHtmlGeneratorPlugin[]; - - constructor(readonly options: IndexHtmlGeneratorOptions) { - this.plugins = [ - augmentIndexHtmlPlugin(this) - ]; - } - - async process(options: IndexHtmlGeneratorProcessOptions): Promise { - let content = stripBom(await this.readIndex(join(this.options.rootPath, this.options.indexPath))); - const warnings: string[] = []; - const errors: string[] = []; - - // eslint-disable-next-line no-restricted-syntax - for (const plugin of this.plugins) { - // eslint-disable-next-line no-await-in-loop - const result = await plugin(content, options); - if (typeof result === 'string') { - content = result; - } else { - content = result.content; - - if (result.warnings.length) { - warnings.push(...result.warnings); - } - - if (result.errors.length) { - errors.push(...result.errors); - } - } - } - - return { - content, - warnings, - errors, - }; - } - - protected async readIndex(path: string): Promise { - return fs.promises.readFile(path, 'utf-8'); - } -} diff --git a/angular/devkit/vite/plugins/index-file/package-chunk-sort.ts b/angular/devkit/vite/plugins/index-file/package-chunk-sort.ts deleted file mode 100644 index d8ca0db4..00000000 --- a/angular/devkit/vite/plugins/index-file/package-chunk-sort.ts +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import {parse} from 'path'; -// import { ScriptElement, StyleElement } from '@angular-devkit/build-angular/src/builders/browser/schema'; -import type { BrowserBuilderOptions } from '@bitdev/angular.dev-services.ng-compat'; - -export type EntryPointsType = [name: string, isModule: boolean, inject: boolean]; - -type Flatten = T extends any[] ? T[number] : T; -export type ScriptElement = NonNullable>; -export type StyleElement = NonNullable>; - -export type NormalizedEntryPoint = Required>; - -export function normalizeExtraEntryPoints( - extraEntryPoints: (ScriptElement | StyleElement)[], - defaultBundleName: string, -): NormalizedEntryPoint[] { - return extraEntryPoints.map((entry) => { - if(!entry) { - throw new Error('Empty entry point found.'); - } - - if (typeof entry === 'string') { - return { input: entry || '', inject: true, bundleName: defaultBundleName }; - } - - const { inject = true, ...newEntry } = entry; - let bundleName; - if (entry.bundleName) { - bundleName = entry.bundleName; - } else if (!inject) { - // Lazy entry points use the file name as bundle name. - bundleName = parse(entry.input).name; - } else { - bundleName = defaultBundleName; - } - - return { ...newEntry, inject, bundleName }; - }); -} - -export function generateEntryPoints(options: { - main: string; - polyfills?: string[] | string; - styles: StyleElement[]; - scripts: ScriptElement[]; - isHMREnabled?: boolean; -}): EntryPointsType[] { - // Add all styles/scripts, except lazy-loaded ones. - const extraEntryPoints = ( - eePoints: (ScriptElement | StyleElement)[], - defaultBundleName: string, - ) => { - const entryPoints = normalizeExtraEntryPoints(eePoints, defaultBundleName) - .filter((entry) => entry.inject) - .map((entry) => entry.input); - - // remove duplicates - return [...new Set(entryPoints)].map((f) => [f, defaultBundleName === 'scripts', defaultBundleName === 'scripts']); - }; - - let polyfills: EntryPointsType[] = []; - if(options.polyfills) { - polyfills = Array.isArray(options.polyfills) ? options.polyfills.map((p: string) => [p, true, false]) : [[options.polyfills, true, false]]; - } - const entryPoints: EntryPointsType[] = [ - ...polyfills, - ...extraEntryPoints(options.styles, 'styles'), - ...extraEntryPoints(options.scripts, 'scripts'), - [options.main, true, false], - ]; - - const duplicates = entryPoints.filter( - ([name]) => entryPoints[0].indexOf(name) !== entryPoints[0].lastIndexOf(name), - ); - - if (duplicates.length > 0) { - throw new Error(`Multiple bundles have been named the same: '${duplicates.join(`', '`)}'.`); - } - - return entryPoints; -} diff --git a/angular/devkit/vite/plugins/index-file/strip-bom.ts b/angular/devkit/vite/plugins/index-file/strip-bom.ts deleted file mode 100644 index f6ed209f..00000000 --- a/angular/devkit/vite/plugins/index-file/strip-bom.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -// Strip BOM from file data. -// https://stackoverflow.com/questions/24356713 -export function stripBom(data: string) { - return data.replace(/^\uFEFF/, ''); -} diff --git a/angular/devkit/vite/plugins/index-html.plugin.ts b/angular/devkit/vite/plugins/index-html.plugin.ts deleted file mode 100644 index 2a96e027..00000000 --- a/angular/devkit/vite/plugins/index-html.plugin.ts +++ /dev/null @@ -1,79 +0,0 @@ -import type { ServerResponse } from 'http'; -import memoize from 'memoizee'; -// @ts-ignore -import type { Connect, Plugin, ViteDevServer } from 'vite'; -import { ApplicationOptions } from '@bitdev/angular.dev-services.common'; -import { IndexHtmlGenerator } from './index-file/index-html-generator'; -import { generateEntryPoints } from './index-file/package-chunk-sort'; -import assert from 'assert'; - -export function getIndexInputFile(index: ApplicationOptions['index']): string { - assert(index, 'No index file provided'); - if (typeof index === 'string') { - return index; - } - return (index as any).input; -} - -const cleanUrl = (url: string) => url.replace(/#.*$/s, '').replace(/\?.*$/s, ''); - -async function genHtml(options: Partial, rootPath: string, indexPath: string) { - assert(options.browser, 'No main file provided'); - const entrypoints = generateEntryPoints({ - main: options.browser, - polyfills: options.polyfills ?? [], - scripts: options.scripts ?? [], - styles: options.styles ?? [] - }); - - const indexHtmlGenerator = new IndexHtmlGenerator({ - rootPath, - indexPath, - entrypoints, - crossOrigin: options.crossOrigin - }); - - const { content, warnings, errors } = await indexHtmlGenerator.process({ - baseHref: options.baseHref ?? './', - // i18nLocale is used when Ivy is disabled - lang: undefined - }); - - if (warnings.length) { - // eslint-disable-next-line no-console - warnings.forEach((warning) => console.warn(warning)); - } - - if (errors.length) { - throw new Error(`Index html generation failed: ${errors.join(', ')}`); - } - - return content; -}; - -const memoized = memoize(genHtml); - -export const htmlPlugin = (options: Partial, rootPath: string, indexPath: string, ssr: boolean): Plugin => { - return { - name: 'ng-vite-html-plugin', - configureServer(server: ViteDevServer) { - return (): void => { - // if(ssr) { - // return; - // } - server.middlewares.use(async(req: Connect.IncomingMessage, res: ServerResponse, next: Connect.NextFunction) => { - const url = req.url && cleanUrl(req.url); - if (url?.endsWith('.html')) { - res.statusCode = 200; - res.setHeader('Content-Type', 'text/html'); - let html = await memoized(options, rootPath, indexPath); - html = await server.transformIndexHtml(indexPath, html, req.originalUrl); - res.end(html); - return; - } - next(); - }); - }; - } - }; -}; diff --git a/angular/devkit/vite/plugins/md.plugin.ts b/angular/devkit/vite/plugins/md.plugin.ts new file mode 100644 index 00000000..d22d3a5b --- /dev/null +++ b/angular/devkit/vite/plugins/md.plugin.ts @@ -0,0 +1,37 @@ +import markdoc from '@markdoc/markdoc'; +import { Plugin, PluginBuild } from 'esbuild'; +import { promises } from 'fs'; + +/** + * This plugin uses build.onLoad to intercept .md filenames. + * These files are then read from disk and parsed by remark. + * @returns An esbuild plugin. + */ +export default function () { + const plugin: Plugin = { + name: 'md-loader', + + setup(build: PluginBuild) { + // intercept .md files + build.onResolve({ filter: /\.md$/ }, args => { + return { + path: args.path, + namespace: 'md-ns', + } + }); + + build.onLoad({ filter: /.*/, namespace: 'md-ns' }, async args => { + const data = await promises.readFile(args.path, 'utf8'); + const ast = markdoc.parse(data); + const content = markdoc.transform(ast, {}); + const html = markdoc.renderers.html(content); + return { + contents: html, + loader: 'text', + }; + }) + } + }; + + return plugin; +} diff --git a/angular/devkit/vite/plugins/server-entry.plugin.ts b/angular/devkit/vite/plugins/server-entry.plugin.ts deleted file mode 100644 index fb998fe2..00000000 --- a/angular/devkit/vite/plugins/server-entry.plugin.ts +++ /dev/null @@ -1,113 +0,0 @@ -// // SSR dev server, middleware and error page source modified from -// // https://github.com/solidjs/solid-start/blob/main/packages/start/dev/server.js -// -// import { Connect, Plugin, ViteDevServer } from 'vite'; -// import * as path from 'path'; -// import * as fs from 'fs'; -// -// interface ServerOptions { -// indexPath?: string; -// entryServer?: string; -// } -// -// export function devServerPlugin(options: ServerOptions): Plugin { -// const entryServer = options.entryServer || 'src/main.server.ts'; -// const index = options.indexPath || 'index.html'; -// -// return { -// name: 'ng-vite-server-entry-plugin', -// config() { -// return { -// resolve: { -// alias: { -// '~ng-vite/main-server': entryServer, -// }, -// }, -// }; -// }, -// configureServer(viteServer) { -// return async () => { -// remove_html_middlewares(viteServer.middlewares); -// viteServer.middlewares.use(async (req, res) => { -// let template = fs.readFileSync( -// path.resolve(viteServer.config.root, index), -// 'utf-8' -// ); -// -// template = await viteServer.transformIndexHtml( -// req.originalUrl as string, -// template -// ); -// -// console.log(template); -// -// try { -// const entryServer = ( -// await viteServer.ssrLoadModule('~ng-vite/main-server') -// )['default']; -// const result = await entryServer(req.originalUrl, template); -// console.log(result); -// -// res.setHeader('Content-Type', 'text/html'); -// res.end(result); -// } catch (e) { -// viteServer && viteServer.ssrFixStacktrace(e as Error); -// res.statusCode = 500; -// res.end(` -// -// -// -// -// Error -// -// -// -// -// -// `); -// } -// }); -// }; -// }, -// }; -// } -// -// /** -// * Removes Vite internal middleware -// * -// * @param server -// */ -// function remove_html_middlewares(server: ViteDevServer['middlewares']) { -// const html_middlewares = [ -// 'viteIndexHtmlMiddleware', -// 'vite404Middleware', -// 'viteSpaFallbackMiddleware', -// ]; -// for (let i = server.stack.length - 1; i > 0; i--) { -// // @ts-ignore -// if (html_middlewares.includes(server.stack[i].handle.name)) { -// server.stack.splice(i, 1); -// } -// } -// } -// -// /** -// * Formats error for SSR message in error overlay -// * @param req -// * @param error -// * @returns -// */ -// function prepareError(req: Connect.IncomingMessage, error: unknown) { -// const e = error as Error; -// return { -// message: `An error occured while server rendering ${req.url}:\n\n\t${ -// typeof e === 'string' ? e : e.message -// } `, -// stack: typeof e === 'string' ? '' : e.stack, -// }; -// } diff --git a/angular/app-types/angular-app-type/runtime/api-middleware.js b/angular/devkit/vite/runtime/api-middleware.js similarity index 100% rename from angular/app-types/angular-app-type/runtime/api-middleware.js rename to angular/devkit/vite/runtime/api-middleware.js diff --git a/angular/app-types/angular-app-type/runtime/renderer.js b/angular/devkit/vite/runtime/renderer.js similarity index 100% rename from angular/app-types/angular-app-type/runtime/renderer.js rename to angular/devkit/vite/runtime/renderer.js diff --git a/angular/devkit/vite/utils/host-alias.ts b/angular/devkit/vite/utils/host-alias.ts deleted file mode 100644 index 22dd5331..00000000 --- a/angular/devkit/vite/utils/host-alias.ts +++ /dev/null @@ -1,58 +0,0 @@ -// @ts-nocheck - -import findRoot from 'find-root'; -import type { Alias } from 'vite'; -import type {BundlerContext, DevServerContext} from '@teambit/bundler'; - -export type ViteContext = { - /** - * A path for the host root dir - * Host root dir is usually the env root dir - * This can be used in different bundle options which run require.resolve - * for example when configuring webpack aliases or webpack expose loader on the peers deps - */ - hostRootDir?: string; - /** - * Array of host dependencies, they are used later in case you use one of the following: - * - */ - hostDependencies?: string[]; - /** - * Make the hostDependencies externals. externals (from webpack docs): - * The externals configuration option provides a way of excluding dependencies from the output bundles. - * Instead, the created bundle relies on that dependency to be present in the consumer's (any end-user application) environment. - */ - externalizeHostDependencies?: boolean; - /** - * Make aliases for the hostDependencies. - * the path of each one will be resolved by [hostRootDir, process.cwd(), __dirname] - * this will usually replace the instance of import one of the host dependencies by the instance of the env provided it - */ - aliasHostDependencies?: boolean; -}; - -export function getHostAlias(context: BundlerContext | DevServerContext): [] { - const alias: Alias[] = []; - const { hostDependencies: deps, aliasHostDependencies, hostRootDir } = context; - if (deps && aliasHostDependencies) { - deps.forEach(dep => { - let resolved: string; - try { - resolved = require.resolve(dep, { paths: [hostRootDir, process.cwd(), __dirname] }); - const folder = findRoot(resolved); - alias.push({ - find: dep, - replacement: folder - }) - } catch (e) { - if (resolved) { - alias.push({ - find: dep, - replacement: resolved - }) - } - } - }) - } - return alias; -} diff --git a/angular/devkit/vite/utils/types.ts b/angular/devkit/vite/utils/types.ts index ac8b517e..dc59d433 100644 --- a/angular/devkit/vite/utils/types.ts +++ b/angular/devkit/vite/utils/types.ts @@ -1,13 +1,4 @@ -import { ApplicationOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; -import { Logger } from '@teambit/logger'; -import type { ViteDevServerOptions } from '@teambit/vite.vite-dev-server'; -import { Workspace } from '@teambit/workspace'; - - -export type ViteAspectsContext = { - logger: Logger; - workspace: Workspace; -}; +import { ApplicationOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; export enum BuildMode { Development = 'development', @@ -15,17 +6,12 @@ export enum BuildMode { } export type NgViteOptions = { - angularOptions: Partial; + angularOptions: any;//Partial<(BrowserOptions | ApplicationOptions) & DevServerOptions>; /** name of the dev server */ name?: string; - // TODO: fix type once we can support preview with vite - /** list of transformers to modify Vite config in an advanced way */ - transformers?: ViteDevServerOptions['transformers']; - - /** optimize entries before passing them to Vite */ - optimizeEntries?: (entries: string[], context: ViteAspectsContext) => string[]; + appRootPath: string; /** Output folder path for build files */ outputPath?: string; diff --git a/angular/devkit/vite/utils/utils.ts b/angular/devkit/vite/utils/utils.ts index 1251c9fe..11f68ecd 100644 --- a/angular/devkit/vite/utils/utils.ts +++ b/angular/devkit/vite/utils/utils.ts @@ -1,21 +1,160 @@ -import * as path from 'path'; +import { ApplicationOptions, normalizePath } from "@bitdev/angular.dev-services.common"; +import { Component } from '@teambit/component'; +import { DependencyResolverMain } from '@teambit/dependency-resolver'; +import { DevFilesMain } from '@teambit/dev-files'; +import { TesterAspect } from '@teambit/tester'; +import { Workspace } from '@teambit/workspace'; +import assert from 'assert'; +import fs from "fs-extra"; +import { flatten } from 'lodash-es'; +import objectHash from "object-hash"; +import { basename, dirname, isAbsolute, join, relative } from "path"; +import ts from 'typescript'; -function removeWindowsDriveLetter(osSpecificPath: string): string { - return osSpecificPath.replace(/^[A-Z]:/, ''); + +const writeHash = new Map(); +export const ENTRY_REGEXP = new RegExp(/(import\s.*['"])(.*)(@teambit(\/|\\\\).*['"];)/gm); +export interface JsonObject { + [prop: string]: any; +} + +export function generateMainEntryFile(appRootPath: string, tempFolder: string, entryPoints: string[]): string { + const entryFileContent = entryPoints.map(entry => `import './${normalizePath(relative(tempFolder, entry.endsWith('.ts') ? entry.replace(/\.ts$/, '') : entry))}';`).join('\n'); + const entryFile = join(tempFolder, `main-${Date.now()}.ts`); + fs.outputFileSync(entryFile, entryFileContent); + return normalizePath(relative(appRootPath, entryFile)); } /** - * Coverts an os specific path to a unix style path. Use this when writing paths to config files. - * This should not be used to read files on disk because of the removal of Windows drive letters. + * We need to move the entries to `.git/bit/tmp/preview-entries/` + * out of `node_modules` since Vite doesn't support entries in it. */ -export function normalizePath(osSpecificPath: string): string { - return removeWindowsDriveLetter(osSpecificPath).split('\\').join('/'); +export function fixEntries(tempFolder: string, entries: string[]) { + return entries.filter(entry => !!entry.match(/(compositions-\d*\.js|overview-\d*\.js|preview\.root.*\.js|preview\.entry.*\.js)/)) + .map(entry => { + const name = basename(entry); + const newEntry = join(tempFolder, name); + let content = fs.readFileSync(entry, 'utf8'); + content = content.replaceAll(ENTRY_REGEXP, '$1$3').replaceAll(/\\\\/gm, '/'); + // content = content.replaceAll("@teambit/preview/dist/preview.preview.runtime.js", "@teambit/preview/dist/preview-modules.js"); + fs.outputFileSync(newEntry, content); + return newEntry; + }); } + /** - * Normalized path fragments and joins them. Use this when writing paths to config files. - * This should not be used to read files on disk because of the removal of Windows drive letters. + * Takes a tsconfig.json file, a list of component directories, and returns a new tsconfig.json file with the include + * and exclude properties expanded to include all the component directories + * @param {any} tsconfigJSON - The path to the existing tsconfig.json file. + * @param {string} targetPath - The path to the new tsconfig.json file. + * @param {string[]} compDirs - An array of paths to the component directories. + * @returns the tsConfig object. */ -export function joinPathFragments(...fragments: string[]): string { - return normalizePath(path.join(...fragments)); +export function expandIncludeExclude(tsconfigJSON: JsonObject, targetPath: string, compDirs: string[]): JsonObject { + // eslint-disable-next-line no-param-reassign + targetPath = dirname(targetPath); + + if (tsconfigJSON.include) { + // eslint-disable-next-line no-param-reassign + tsconfigJSON.include = flatten( + tsconfigJSON.include.map((includedPath: string) => { + return compDirs.map((compDir: string) => { + return isAbsolute(includedPath) ? normalizePath(includedPath) : `${normalizePath(relative(targetPath, compDir))}/${includedPath}`; + }); + }) + ); + } + if (tsconfigJSON.exclude) { + // eslint-disable-next-line no-param-reassign + tsconfigJSON.exclude = flatten( + tsconfigJSON.exclude.map((excludedPath: string) => { + return compDirs.map((compDir: string) => { + return isAbsolute(excludedPath) ? normalizePath(excludedPath) : `${normalizePath(relative(targetPath, compDir))}/${excludedPath}`; + }); + }) + ); + } + if (tsconfigJSON.files) { + // eslint-disable-next-line no-param-reassign + tsconfigJSON.files = flatten( + tsconfigJSON.files.map((filesPath: string) => { + return compDirs.map((compDir: string) => { + return isAbsolute(filesPath) ? normalizePath(relative(targetPath, filesPath)) : `${normalizePath(relative(targetPath, compDir))}/${filesPath}`; + }); + }) + ); + } + + return tsconfigJSON; +} + + +export function getIndexInputFile(index: ApplicationOptions['index']): string { + assert(index, 'No index file provided'); + if (typeof index === 'string') { + return index; + } + return (index as any).input; +} + +export function generateAppTsConfig( + bitCmps: Component[], + appRootPath: string, + appTsconfigPath: string, + tsconfigPath: string, + depsResolver: DependencyResolverMain, + workspace?: Workspace, + additionalEntries?: string[], + devFilesMain?: DevFilesMain +): void { + const configFile = ts.readConfigFile(appTsconfigPath, ts.sys.readFile); + if (configFile.error) { + throw configFile.error; + } + const tsconfigJSON: JsonObject = configFile.config; + // Add the paths to tsconfig to remap bit components to local folders + tsconfigJSON.compilerOptions = tsconfigJSON.compilerOptions || {}; + tsconfigJSON.compilerOptions.paths = tsconfigJSON.compilerOptions.paths || {}; + bitCmps.forEach((dep: Component) => { + let componentDir = workspace?.componentDir(dep.id, { + ignoreVersion: true + }); + if (componentDir && dep.config.main === 'public-api.ts' || componentDir === appRootPath) { + componentDir = normalizePath(componentDir); + const pkgName = depsResolver.getPackageName(dep); + tsconfigJSON.compilerOptions.paths[pkgName] = [`${componentDir}/${dep.config.main}`, `${componentDir}`]; + tsconfigJSON.compilerOptions.paths[`${pkgName}/*`] = [`${componentDir}/*`]; + if (devFilesMain) { + tsconfigJSON.include.push(`${componentDir}/**/*`); + + // get the list of spec patterns + const devPatterns: string[] = devFilesMain.getDevPatterns(dep, TesterAspect.id); + devPatterns.forEach(specPattern => { + tsconfigJSON.exclude.push(`${componentDir}/${specPattern}`); + }); + } + } + }); + + if (additionalEntries) { + tsconfigJSON.files.push(...additionalEntries); + } + + const tsconfigContent = expandIncludeExclude(tsconfigJSON, tsconfigPath, [appRootPath]); + const hash = objectHash(tsconfigContent); + // write only if link has changed (prevents triggering fs watches) + if (writeHash.get(tsconfigPath) !== hash) { + fs.outputJsonSync(tsconfigPath, tsconfigContent, { spaces: 2 }); + writeHash.set(tsconfigPath, hash); + } +} + +export async function getEnvFile(mode: string, rootDir: string, overrides?: Record) { + const vite = await import('vite'); + const dotenv = vite.loadEnv(mode, rootDir); + return { + ...overrides, + ...dotenv + }; } diff --git a/angular/devkit/webpack/component.json b/angular/devkit/webpack/component.json index bb15d913..1adb9c12 100644 --- a/angular/devkit/webpack/component.json +++ b/angular/devkit/webpack/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "dev-services/webpack", - "version": "7.0.0" + "version": "2ef44a3d81b791be618aec5ccb179aea5f1b6953" }, "propagate": false, "extensions": { @@ -21,7 +21,6 @@ } } }, - "teambit.node/node@1.0.54": {}, "teambit.envs/envs": {}, "teambit.component/dev-files": {}, "teambit.pkg/pkg": {}, @@ -29,6 +28,7 @@ "teambit.compositions/compositions": {}, "teambit.docs/docs": {}, "teambit.pipelines/builder": {}, - "teambit.semantics/schema": {} + "teambit.semantics/schema": {}, + "teambit.node/node@1.0.103": {} } } diff --git a/angular/devkit/webpack/ng-webpack-bundler.ts b/angular/devkit/webpack/ng-webpack-bundler.ts index 311c3f6d..e4513499 100644 --- a/angular/devkit/webpack/ng-webpack-bundler.ts +++ b/angular/devkit/webpack/ng-webpack-bundler.ts @@ -14,7 +14,7 @@ import { BundlerContext } from '@teambit/bundler'; import { DevFilesAspect, DevFilesMain } from '@teambit/dev-files'; import { AsyncEnvHandler, EnvContext } from '@teambit/envs'; import { IsolatorAspect, IsolatorMain } from '@teambit/isolator'; -import { CACHE_ROOT } from '@teambit/legacy/dist/constants'; +import { CACHE_ROOT } from '@teambit/legacy.constants'; import { PkgAspect, PkgMain } from '@teambit/pkg'; import { ScopeAspect, ScopeMain } from '@teambit/scope'; import { diff --git a/angular/devkit/webpack/ng-webpack-dev-server.ts b/angular/devkit/webpack/ng-webpack-dev-server.ts index c6d7960c..fd853e7e 100644 --- a/angular/devkit/webpack/ng-webpack-dev-server.ts +++ b/angular/devkit/webpack/ng-webpack-dev-server.ts @@ -15,7 +15,7 @@ import { Component } from '@teambit/component'; import { DevFilesAspect, DevFilesMain } from '@teambit/dev-files'; import { AsyncEnvHandler, EnvContext } from '@teambit/envs'; import { IsolatorAspect, IsolatorMain } from '@teambit/isolator'; -import { CACHE_ROOT } from '@teambit/legacy/dist/constants'; +import { CACHE_ROOT } from '@teambit/legacy.constants'; import { PkgAspect, PkgMain } from '@teambit/pkg'; import { PubsubMain } from '@teambit/pubsub'; import { ScopeAspect, ScopeMain } from '@teambit/scope'; diff --git a/angular/docs/build-pipelines/build-pipelines.mdx b/angular/docs/build-pipelines/build-pipelines.mdx index 579b0ed6..9fc8fb87 100644 --- a/angular/docs/build-pipelines/build-pipelines.mdx +++ b/angular/docs/build-pipelines/build-pipelines.mdx @@ -73,10 +73,10 @@ The following example replaces the default `Jest` build task with the same task, ```ts // @filename: my-angular-env.bit-env.ts // ... -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { JestTask } from '@teambit/defender.jest-tester'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { build() { /* replace the default Jest build task with a new one, that uses a different config */ return super.build().replace([ @@ -110,9 +110,9 @@ Get the task name from [the component's list of build tasks](#review-a-component ```ts // @filename: my-angular-env.bit-env.ts // ... -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { build() { return super.build().remove('JestTask'); } diff --git a/angular/docs/build-pipelines/code-snippets/add-replace-task-build.mdx b/angular/docs/build-pipelines/code-snippets/add-replace-task-build.mdx index b2e876ee..7d0e13bc 100644 --- a/angular/docs/build-pipelines/code-snippets/add-replace-task-build.mdx +++ b/angular/docs/build-pipelines/code-snippets/add-replace-task-build.mdx @@ -1,12 +1,12 @@ It is common to both replace tasks and add new tasks. ```ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { JestTask } from '@teambit/defender.jest-tester'; /* import the task you want to add */ import { ComponentNameTask } from '@learnbit/extending-bit.build-tasks.component-name'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { build() { return ( super diff --git a/angular/docs/build-pipelines/code-snippets/add-task-build.mdx b/angular/docs/build-pipelines/code-snippets/add-task-build.mdx index 6965f946..205b92b5 100644 --- a/angular/docs/build-pipelines/code-snippets/add-task-build.mdx +++ b/angular/docs/build-pipelines/code-snippets/add-task-build.mdx @@ -1,11 +1,11 @@ The following code snippet adds a task to the default build pipeline of the Angular env. ```ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; /* import the task you want to add */ import { ComponentNameTask } from '@learnbit/extending-bit.build-tasks.component-name'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { build() { /* add your task to the build pipeline */ return super.build().add([ComponentNameTask.from({})]); diff --git a/angular/docs/build-pipelines/code-snippets/add-task-snap.mdx b/angular/docs/build-pipelines/code-snippets/add-task-snap.mdx index 174cc0c1..6918d69c 100644 --- a/angular/docs/build-pipelines/code-snippets/add-task-snap.mdx +++ b/angular/docs/build-pipelines/code-snippets/add-task-snap.mdx @@ -2,12 +2,12 @@ The Angular env does not register tasks to the snap pipeline. To add a new task, first create a new snap pipeline. ```ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { Pipeline } from '@teambit/builder'; /* import the task you want to add */ import { ComponentNameTask } from '@learnbit/extending-bit.build-tasks.component-name'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { snap() { /* create a new pipeline and add your task */ return Pipeline.from([ComponentNameTask.from({})]); diff --git a/angular/docs/build-pipelines/code-snippets/add-task-tag.mdx b/angular/docs/build-pipelines/code-snippets/add-task-tag.mdx index d1e1f68d..76c08052 100644 --- a/angular/docs/build-pipelines/code-snippets/add-task-tag.mdx +++ b/angular/docs/build-pipelines/code-snippets/add-task-tag.mdx @@ -2,12 +2,12 @@ The Angular env does not register tasks to the tag pipeline. To add a new task, first create a new tag pipeline. ```ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { Pipeline } from '@teambit/builder'; /* import the task you want to add */ import { ComponentNameTask } from '@learnbit/extending-bit.build-tasks.component-name'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { tag() { /* create a new pipeline and add your task */ return Pipeline.from([ComponentNameTask.from({})]); diff --git a/angular/docs/build-pipelines/code-snippets/jest-build-task.mdx b/angular/docs/build-pipelines/code-snippets/jest-build-task.mdx index a3a57f96..0010d3d1 100644 --- a/angular/docs/build-pipelines/code-snippets/jest-build-task.mdx +++ b/angular/docs/build-pipelines/code-snippets/jest-build-task.mdx @@ -1,11 +1,11 @@ ```ts // @filename: my-angular-env.bit-env.ts // ... -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { JestTask } from '@teambit/defender.jest-tester'; import { Pipeline } from '@teambit/builder'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { build() { return Pipeline.from([ // ... diff --git a/angular/docs/build-pipelines/code-snippets/jest-service.mdx b/angular/docs/build-pipelines/code-snippets/jest-service.mdx index 66dd1f2e..07124863 100644 --- a/angular/docs/build-pipelines/code-snippets/jest-service.mdx +++ b/angular/docs/build-pipelines/code-snippets/jest-service.mdx @@ -1,12 +1,12 @@ ```ts // @filename: my-angular-env.bit-env.ts // ... -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { EnvHandler } from '@teambit/envs'; import { Tester } from '@teambit/tester'; import { JestTester } from '@teambit/defender.jest-tester'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { tester(): EnvHandler { return JestTester.from({ jest: require.resolve('jest'), diff --git a/angular/docs/component-generators/component-generators.mdx b/angular/docs/component-generators/component-generators.mdx index 8f04de8e..a79ba0b5 100644 --- a/angular/docs/component-generators/component-generators.mdx +++ b/angular/docs/component-generators/component-generators.mdx @@ -75,11 +75,11 @@ Implement the `generator` env handler in your env, and provide the generators wi ```ts // @filename: my-angular-env.bit-env.ts -import { AngularV18Env } from '@bitdev/angular.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.angular-v19-env'; import { TemplateList } from '@teambit/generator'; import { NgModuleTemplate } from '@bitdev/angular.templates.generators'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { generators() { return TemplateList.from([ NgModuleTemplate.from({ diff --git a/angular/docs/components-preview/code-examples.tsx b/angular/docs/components-preview/code-examples.tsx index c9924f61..807a828f 100644 --- a/angular/docs/components-preview/code-examples.tsx +++ b/angular/docs/components-preview/code-examples.tsx @@ -10,7 +10,7 @@ import CompositionMounterEnv from './snippets/composition-mounter-env.mdx'; const compositionProviderContent = [ { title: 'my-angular-env.bit-env.ts', body: }, - { title: 'preview/mounter.ts', body: }, + { title: 'config/mounter.ts', body: }, { title: 'wrapper.component.ts', body: }, ]; @@ -20,7 +20,7 @@ export const CompositionProviderExample = () => ( const compositionProviderContent2 = [ { title: 'my-angular-env.bit-env.ts', body: }, - { title: 'preview/mounter.ts', body: }, + { title: 'config/mounter.ts', body: }, { title: 'wrapper.ts', body: }, ]; @@ -30,7 +30,7 @@ export const CompositionProviderExample2 = () => ( const compositionMounterContent = [ { title: 'my-angular-env.bit-env.ts', body: }, - { title: 'preview/docs.tsx', body: }, + { title: 'config/docs.tsx', body: }, ]; export const CompositionMounterExample = () => ( diff --git a/angular/docs/components-preview/components-preview.mdx b/angular/docs/components-preview/components-preview.mdx index c8557ac4..965dc3ac 100644 --- a/angular/docs/components-preview/components-preview.mdx +++ b/angular/docs/components-preview/components-preview.mdx @@ -11,12 +11,12 @@ to customize how your docs and compositions are bundled and rendered: ```ts // @filename: my-angular-env.bit-env.ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { Preview } from '@teambit/preview'; import { EnvHandler } from '@teambit/envs'; import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { preview(): EnvHandler { return AngularPreview.from({ /* preview config goes here */ @@ -94,15 +94,15 @@ providers only once in the bundle of your env and exclude them from the preview You can do that by configuring the `hostDependencies` property of your preview. For example: ```ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { Preview } from '@teambit/preview'; import { EnvHandler } from '@teambit/envs'; import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { preview(): EnvHandler { return AngularPreview.from({ - mounterPath: require.resolve('./preview/mounter'), + mounterPath: require.resolve('./config/mounter'), hostDependencies: [ /* your composition provider */ '@my-scope/my-theme.provider', diff --git a/angular/docs/components-preview/snippets/composition-mounter-env.mdx b/angular/docs/components-preview/snippets/composition-mounter-env.mdx index c2946cf3..359509ae 100644 --- a/angular/docs/components-preview/snippets/composition-mounter-env.mdx +++ b/angular/docs/components-preview/snippets/composition-mounter-env.mdx @@ -1,14 +1,14 @@ ```tsx // @filename: my-angular-env.bit-env.ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { Preview } from '@teambit/preview'; import { EnvHandler } from '@teambit/envs'; import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { preview(): EnvHandler { return AngularPreview.from({ - mounterPath: require.resolve('./preview/mounter') + mounterPath: require.resolve('./config/mounter') }); } } diff --git a/angular/docs/components-preview/snippets/composition-provider-env.mdx b/angular/docs/components-preview/snippets/composition-provider-env.mdx index c2946cf3..359509ae 100644 --- a/angular/docs/components-preview/snippets/composition-provider-env.mdx +++ b/angular/docs/components-preview/snippets/composition-provider-env.mdx @@ -1,14 +1,14 @@ ```tsx // @filename: my-angular-env.bit-env.ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { Preview } from '@teambit/preview'; import { EnvHandler } from '@teambit/envs'; import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { preview(): EnvHandler { return AngularPreview.from({ - mounterPath: require.resolve('./preview/mounter') + mounterPath: require.resolve('./config/mounter') }); } } diff --git a/angular/docs/development-tools/development-tools.mdx b/angular/docs/development-tools/development-tools.mdx index acc0e4d8..8e4ca686 100644 --- a/angular/docs/development-tools/development-tools.mdx +++ b/angular/docs/development-tools/development-tools.mdx @@ -7,7 +7,7 @@ The compilation of the source files is done by the Angular compiler (ngc) throug If you use a custom env, you can configure both webpack and the Angular compiler by overriding the `getDevServer` method: ```ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { AngularEnvOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; import { NgWebpackDevServer } from '@bitdev/angular.dev-services.webpack'; import { Configuration } from 'webpack'; @@ -15,7 +15,7 @@ import { DevServer, DevServerContext } from '@teambit/bundler'; import { WebpackConfigTransformer, WebpackConfigWithDevServer } from '@teambit/webpack'; import { AsyncEnvHandler } from '@teambit/envs'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { // ... override getDevServer( @@ -75,7 +75,7 @@ but the options are optimized for production builds. If you use a custom env, you can configure both webpack and the Angular compiler by overriding the `getBundler` method: ```ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { AngularEnvOptions, BrowserOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; import { NgWebpackBundler } from '@bitdev/angular.dev-services.webpack'; import { Configuration } from 'webpack'; @@ -83,7 +83,7 @@ import { Bundler, BundlerContext } from '@teambit/bundler'; import { WebpackConfigTransformer, WebpackConfigWithDevServer } from '@teambit/webpack'; import { AsyncEnvHandler } from '@teambit/envs'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { // ... override getBundler( diff --git a/angular/docs/ng-theming/code-snippet-tabs.tsx b/angular/docs/ng-theming/code-snippet-tabs.tsx index 05671b33..776cb01d 100644 --- a/angular/docs/ng-theming/code-snippet-tabs.tsx +++ b/angular/docs/ng-theming/code-snippet-tabs.tsx @@ -24,7 +24,7 @@ export const MyDarkThemeTabs = () => ; const compositionProviderContent = [ { title: 'my-angular-env.bit-env.ts', body: }, - { title: 'preview/mounter.ts', body: }, + { title: 'config/mounter.ts', body: }, { title: 'wrapper.component.ts', body: }, ]; diff --git a/angular/docs/ng-theming/code-snippets/composition-provider-env.mdx b/angular/docs/ng-theming/code-snippets/composition-provider-env.mdx index f218c8e6..d298cce1 100644 --- a/angular/docs/ng-theming/code-snippets/composition-provider-env.mdx +++ b/angular/docs/ng-theming/code-snippets/composition-provider-env.mdx @@ -1,14 +1,14 @@ ```ts // @filename: my-angular-env.bit-env.ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { Preview } from '@teambit/preview'; import { EnvHandler } from '@teambit/envs'; import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { preview(): EnvHandler { return AngularPreview.from({ - mounterPath: require.resolve('./preview/mounter') + mounterPath: require.resolve('./config/mounter') }); } } diff --git a/angular/docs/workspace-starters/workspace-starters.mdx b/angular/docs/workspace-starters/workspace-starters.mdx index 3ae4b1c8..137befc2 100644 --- a/angular/docs/workspace-starters/workspace-starters.mdx +++ b/angular/docs/workspace-starters/workspace-starters.mdx @@ -59,12 +59,12 @@ Implement the `starter`` env handler in your env, and provide the starters with ```ts // @filename: my-angular-env.bit-env.ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { EnvHandler } from '@teambit/envs'; import { StarterList } from '@teambit/generator'; import { NgWorkspaceTemplate } from '@bitdev/angular.templates.starters'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { packageName = '@my-org/my-scope.my-angular-env'; starters(): EnvHandler { @@ -93,13 +93,13 @@ Replace the default starter with your own custom one: ```ts // @filename: my-angular-env.bit-env.ts -import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; +import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; import { EnvHandler } from '@teambit/envs'; import { StarterList } from '@teambit/generator'; /* a custom starter */ import { AngularWorkspaceStarter } from '@my-org/my-scope.templates.my-custom-starter'; -export class MyAngularEnv extends AngularV18Env { +export class MyAngularEnv extends AngularV19Env { packageName = '@my-org/my-scope.my-angular-env'; starters(): EnvHandler { diff --git a/angular/envs/angular-env/angular.bit-env.ts b/angular/envs/angular-env/angular.bit-env.ts index 6d0bbb5f..f902bc47 100644 --- a/angular/envs/angular-env/angular.bit-env.ts +++ b/angular/envs/angular-env/angular.bit-env.ts @@ -1,8 +1,4 @@ import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; -import { NativeCompileCache } from '@teambit/toolbox.performance.v8-cache'; - -// Disable v8-caching because it breaks ESM loaders -NativeCompileCache.uninstall(); export class AngularEnv extends AngularV19Env { name = 'Angular'; diff --git a/angular/envs/angular-env/angular.docs.mdx b/angular/envs/angular-env/angular.docs.mdx index e882b7a2..f0ebe9b1 100644 --- a/angular/envs/angular-env/angular.docs.mdx +++ b/angular/envs/angular-env/angular.docs.mdx @@ -60,8 +60,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/envs/angular-env/component.json b/angular/envs/angular-env/component.json index 3898d73c..b15b1dec 100644 --- a/angular/envs/angular-env/component.json +++ b/angular/envs/angular-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "angular-env", - "version": "7.1.0" + "version": "8.0.1" }, "propagate": false, "extensions": { @@ -67,7 +67,9 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {} + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" + } } } diff --git a/angular/envs/angular-env/env.jsonc b/angular/envs/angular-env/env.jsonc index d345a517..7fdba035 100644 --- a/angular/envs/angular-env/env.jsonc +++ b/angular/envs/angular-env/env.jsonc @@ -18,13 +18,6 @@ * as a direct component dependencies. they are used for component development only. **/ "dev": [ - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^20.11.22", @@ -84,7 +77,7 @@ { "name": "@angular/platform-browser", "version": "^19.0.0", - "supportedRange": "19.0.0" + "supportedRange": "^19.0.0" }, { "name": "@angular/platform-browser-dynamic", @@ -111,6 +104,11 @@ "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "express", "version": "~4.21.1", diff --git a/angular/envs/angular-env/index.ts b/angular/envs/angular-env/index.ts index c54c49f0..916f5d49 100644 --- a/angular/envs/angular-env/index.ts +++ b/angular/envs/angular-env/index.ts @@ -1,4 +1,2 @@ export { AngularEnv } from './angular.bit-env.js'; export { ngEnvOptions } from '@bitdev/angular.envs.angular-v19-env'; -// @ts-ignore -export { default as jestConfig } from './jest/jest.config.cjs'; diff --git a/angular/envs/angular-v16-env/angular-v16-env.bit-env.ts b/angular/envs/angular-v16-env/angular-v16-env.bit-env.ts index 110b6f9d..5947c863 100644 --- a/angular/envs/angular-v16-env/angular-v16-env.bit-env.ts +++ b/angular/envs/angular-v16-env/angular-v16-env.bit-env.ts @@ -1,20 +1,18 @@ import { AngularEnvOptions } from '@bitdev/angular.dev-services.common'; +import { AngularPreview } from "@bitdev/angular.dev-services.preview.preview"; import { AngularBaseEnv } from '@bitdev/angular.envs.base-env'; -import { NativeCompileCache } from '@teambit/toolbox.performance.v8-cache'; +import { EnvHandler } from '@teambit/envs'; +import { Preview } from '@teambit/preview'; import { createRequire } from 'node:module'; import { webpackConfigFactory } from './webpack-config.factory.js'; -// Disable v8-caching because it breaks ESM loaders -NativeCompileCache.uninstall(); - const require = createRequire(import.meta.url); export const ngEnvOptions: AngularEnvOptions = { useAngularElementsPreview: false, // angularElementsModulePath: require.resolve('@angular/elements'), - jestConfigPath: require.resolve('./jest/jest.config.cjs'), jestModulePath: require.resolve('jest'), - ngPackagrModulePath: import.meta.resolve('ng-packagr'), + ngPackagrModulePath: require.resolve('ng-packagr'), webpackConfigFactory, webpackDevServerModulePath: require.resolve('webpack-dev-server'), // resolving to the webpack used by angular devkit to avoid multiple instances of webpack @@ -32,6 +30,26 @@ export class AngularV16Env extends AngularBaseEnv { angularVersion = 16; ngEnvOptions: AngularEnvOptions = ngEnvOptions; + + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = require.resolve('./jest/jest.config.cjs'); + + /** + * Esbuild plugins are not supported in Angular v16 and required for the preview, so we can't use vite dev server. + * Instead, we use the old webpack dev server. + */ + override preview(): EnvHandler { + return AngularPreview.from({ + ngEnvOptions: this.getNgEnvOptions(), + hostDependencies: [ + '@teambit/mdx.ui.mdx-scope-context', + '@mdx-js/react', + 'react', + 'react-dom', + ], + mounterPath: require.resolve('./config/mounter.js') + }); + } } export default new AngularV16Env(); diff --git a/angular/envs/angular-v16-env/angular-v16-env.docs.mdx b/angular/envs/angular-v16-env/angular-v16-env.docs.mdx index df0af439..31fb8ae2 100644 --- a/angular/envs/angular-v16-env/angular-v16-env.docs.mdx +++ b/angular/envs/angular-v16-env/angular-v16-env.docs.mdx @@ -60,8 +60,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/envs/angular-v16-env/component.json b/angular/envs/angular-v16-env/component.json index 70c1984e..13b0b404 100644 --- a/angular/envs/angular-v16-env/component.json +++ b/angular/envs/angular-v16-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "envs/angular-v16-env", - "version": "7.1.0" + "version": "8.0.1" }, "propagate": false, "extensions": { @@ -67,14 +67,16 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {}, "teambit.component/renaming": { "renamedFrom": { "scope": "bitdev.angular", "name": "envs/v16", "version": "277a7758ede161c02a2f2d01b02f056782c45d67" } + }, + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" } } } diff --git a/angular/envs/base-env/preview/mounter.ts b/angular/envs/angular-v16-env/config/mounter.ts similarity index 95% rename from angular/envs/base-env/preview/mounter.ts rename to angular/envs/angular-v16-env/config/mounter.ts index af297c87..e0b86263 100644 --- a/angular/envs/base-env/preview/mounter.ts +++ b/angular/envs/angular-v16-env/config/mounter.ts @@ -5,7 +5,7 @@ import { Component, ViewEncapsulation } from '@angular/core'; /** * Provide your component compositions (preview) with the context they need to run. * for example, a router, a theme, a data provider, etc. - * components added here as providers should be listed as host-dependencies in your host-dependencies.ts file. + * components added here as providers should be listed as host-dependencies * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers */ @Component({ @@ -19,7 +19,6 @@ import { Component, ViewEncapsulation } from '@angular/core'; `, }) export class WrapperComponent {} - /** * the entry for the app (preview runtime) that renders your component previews. * use the default template or create your own. diff --git a/angular/envs/angular-v16-env/env.jsonc b/angular/envs/angular-v16-env/env.jsonc index ab1e5f9e..9f6c02f9 100644 --- a/angular/envs/angular-v16-env/env.jsonc +++ b/angular/envs/angular-v16-env/env.jsonc @@ -18,13 +18,6 @@ * as a direct component dependencies. they are used for component development only. **/ "dev": [ - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^16.11.7", @@ -95,6 +88,11 @@ "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "jest", "version": "^29.5.0", diff --git a/angular/envs/angular-v16-env/index.ts b/angular/envs/angular-v16-env/index.ts index 84c8f74f..3c73bc7d 100644 --- a/angular/envs/angular-v16-env/index.ts +++ b/angular/envs/angular-v16-env/index.ts @@ -1,3 +1 @@ export { AngularV16Env, ngEnvOptions } from './angular-v16-env.bit-env.js'; -// @ts-ignore -export { default as jestConfig } from './jest/jest.config.cjs'; diff --git a/angular/envs/angular-v16-env/webpack-config.factory.ts b/angular/envs/angular-v16-env/webpack-config.factory.ts index bc9c31d4..8c4e3ca9 100644 --- a/angular/envs/angular-v16-env/webpack-config.factory.ts +++ b/angular/envs/angular-v16-env/webpack-config.factory.ts @@ -1,7 +1,7 @@ /* eslint-disable no-param-reassign */ import { OutputHashing } from '@angular-devkit/build-angular'; import { getSystemPath, normalize, tags } from '@angular-devkit/core'; -import { BundlerSetup, dedupPaths, getLoggerApi } from '@bitdev/angular.dev-services.common'; +import { BundlerSetup, dedupePaths, getLoggerApi } from '@bitdev/angular.dev-services.common'; import type { BrowserBuilderOptions } from '@bitdev/angular.dev-services.ng-compat'; import { generateEntryPoints, @@ -108,8 +108,8 @@ async function getWebpackConfig( main: angularOptions.main ?? `./${join(sourceRoot, `main.ts`)}`, polyfills: angularOptions.polyfills, tsConfig: angularOptions.tsConfig ?? tsconfigPath, - assets: dedupPaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]), - styles: dedupPaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage ?? 'scss' }`), ...(angularOptions.styles ?? [])]), + assets: dedupePaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]), + styles: dedupePaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage ?? 'scss' }`), ...(angularOptions.styles ?? [])]), scripts: angularOptions.scripts, vendorChunk: angularOptions.vendorChunk ?? true, namedChunks: angularOptions.namedChunks ?? true, diff --git a/angular/envs/angular-v16-env/webpack/module-rules.config.ts b/angular/envs/angular-v16-env/webpack/module-rules.config.ts index bfdf9b8c..4fd1ab04 100644 --- a/angular/envs/angular-v16-env/webpack/module-rules.config.ts +++ b/angular/envs/angular-v16-env/webpack/module-rules.config.ts @@ -28,7 +28,7 @@ const postCssConfig = { // Adds PostCSS Normalize as the reset css with default options, // so that it honors browserslist config in package.json // which in turn lets users customize the target behavior as per their needs. - // require.resolve('postcss-normalize'), + // req.resolve('postcss-normalize'), ], }; diff --git a/angular/envs/angular-v17-env/angular-v17-env.bit-env.ts b/angular/envs/angular-v17-env/angular-v17-env.bit-env.ts index b0d40628..28d8bf92 100644 --- a/angular/envs/angular-v17-env/angular-v17-env.bit-env.ts +++ b/angular/envs/angular-v17-env/angular-v17-env.bit-env.ts @@ -1,20 +1,15 @@ import { AngularEnvOptions } from '@bitdev/angular.dev-services.common'; import { AngularBaseEnv } from '@bitdev/angular.envs.base-env'; -import { NativeCompileCache } from '@teambit/toolbox.performance.v8-cache'; import { createRequire } from 'node:module'; import { webpackConfigFactory } from './webpack-config.factory.js'; -// Disable v8-caching because it breaks ESM loaders -NativeCompileCache.uninstall(); - const require = createRequire(import.meta.url); export const ngEnvOptions: AngularEnvOptions = { useAngularElementsPreview: false, - // angularElementsModulePath: require.resolve('@angular/elements'), - jestConfigPath: require.resolve('./jest/jest.config.cjs'), + // angularElementsModulePath: req.resolve('@angular/elements'), jestModulePath: require.resolve('jest'), - ngPackagrModulePath: import.meta.resolve('ng-packagr'), + ngPackagrModulePath: require.resolve('ng-packagr'), webpackConfigFactory, webpackDevServerModulePath: require.resolve('webpack-dev-server'), // resolving to the webpack used by angular devkit to avoid multiple instances of webpack @@ -32,6 +27,9 @@ export class AngularV17Env extends AngularBaseEnv { angularVersion = 17; ngEnvOptions: AngularEnvOptions = ngEnvOptions; + + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = require.resolve('./jest/jest.config.cjs'); } export default new AngularV17Env(); diff --git a/angular/envs/angular-v17-env/angular-v17-env.docs.mdx b/angular/envs/angular-v17-env/angular-v17-env.docs.mdx index 0d9c7b5a..98869f19 100644 --- a/angular/envs/angular-v17-env/angular-v17-env.docs.mdx +++ b/angular/envs/angular-v17-env/angular-v17-env.docs.mdx @@ -60,8 +60,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/envs/angular-v17-env/component.json b/angular/envs/angular-v17-env/component.json index 8be176fc..d7406345 100644 --- a/angular/envs/angular-v17-env/component.json +++ b/angular/envs/angular-v17-env/component.json @@ -2,34 +2,34 @@ "componentId": { "scope": "bitdev.angular", "name": "envs/angular-v17-env", - "version": "6.1.0" + "version": "7.0.1" }, "propagate": false, "extensions": { "teambit.dependencies/dependency-resolver": { "policy": { "dependencies": { - "@angular-devkit/architect": "0.1700.0", - "@angular-devkit/build-angular": "^17.0.0", - "@angular-devkit/build-webpack": "0.1700.0", - "@angular-devkit/core": "^17.0.0", - "@angular-devkit/schematics": "^17.0.0", + "@angular-devkit/architect": "0.1703.11", + "@angular-devkit/build-angular": "^17.3.0", + "@angular-devkit/build-webpack": "0.1703.11", + "@angular-devkit/core": "^17.3.0", + "@angular-devkit/schematics": "^17.3.0", "@angular-eslint/eslint-plugin": "~16.1.1", "@angular-eslint/eslint-plugin-template": "~16.1.1", "@angular-eslint/template-parser": "~16.1.1", - "@angular/animations": "^17.0.0", - "@angular/cli": "^17.0.0", - "@angular/common": "^17.0.0", - "@angular/compiler": "^17.0.0", - "@angular/compiler-cli": "^17.0.0", - "@angular/core": "^17.0.0", - "@angular/elements": "^17.0.0", - "@angular/platform-browser": "^17.0.0", - "@angular/platform-browser-dynamic": "^17.0.0", - "@angular/platform-server": "^17.0.0", - "@angular/ssr": "^17.0.0", + "@angular/animations": "^17.3.0", + "@angular/cli": "^17.3.0", + "@angular/common": "^17.3.0", + "@angular/compiler": "^17.3.0", + "@angular/compiler-cli": "^17.3.0", + "@angular/core": "^17.3.0", + "@angular/elements": "^17.3.0", + "@angular/platform-browser": "^17.3.0", + "@angular/platform-browser-dynamic": "^17.3.0", + "@angular/platform-server": "^17.3.0", + "@angular/ssr": "^17.3.0", "@jest/globals": "^29.3.1", - "@ngtools/webpack": "^17.0.0", + "@ngtools/webpack": "^17.3.0", "@types/eslint": "^8.40.0", "@types/jest": "^29.5.0", "@types/react-dev-utils": "~9.0.8", @@ -44,7 +44,7 @@ "jest-environment-jsdom": "^29.0.3", "jest-environment-node": "^29.0.3", "jest-preset-angular": "~13.1.3", - "ng-packagr": "^17.0.0", + "ng-packagr": "^17.3.0", "postcss": "8.4.23", "postcss-flexbugs-fixes": "5.0.2", "postcss-loader": "7.2.4", @@ -68,7 +68,9 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {} + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" + } } } diff --git a/angular/envs/angular-v17-env/env.jsonc b/angular/envs/angular-v17-env/env.jsonc index 704692e3..a5333fa5 100644 --- a/angular/envs/angular-v17-env/env.jsonc +++ b/angular/envs/angular-v17-env/env.jsonc @@ -18,13 +18,6 @@ * as a direct component dependencies. they are used for component development only. **/ "dev": [ - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^20.11.22", @@ -42,59 +35,64 @@ "peers": [ { "name": "@angular/animations", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/common", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/compiler", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/compiler-cli", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/core", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/forms", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/platform-browser", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/platform-browser-dynamic", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/platform-server", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/router", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@types/eslint", "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "jest", "version": "^29.5.0", diff --git a/angular/envs/angular-v17-env/index.ts b/angular/envs/angular-v17-env/index.ts index ac37e154..654a7ac2 100644 --- a/angular/envs/angular-v17-env/index.ts +++ b/angular/envs/angular-v17-env/index.ts @@ -1,3 +1 @@ export { AngularV17Env, ngEnvOptions } from './angular-v17-env.bit-env.js'; -// @ts-ignore -export { default as jestConfig } from './jest/jest.config.cjs'; diff --git a/angular/envs/angular-v17-env/webpack-config.factory.ts b/angular/envs/angular-v17-env/webpack-config.factory.ts index 7645044e..c7b28201 100644 --- a/angular/envs/angular-v17-env/webpack-config.factory.ts +++ b/angular/envs/angular-v17-env/webpack-config.factory.ts @@ -1,7 +1,7 @@ /* eslint-disable no-param-reassign */ import { OutputHashing } from '@angular-devkit/build-angular'; import { getSystemPath, normalize, tags } from '@angular-devkit/core'; -import { BundlerSetup, dedupPaths, getLoggerApi } from '@bitdev/angular.dev-services.common'; +import { BundlerSetup, dedupePaths, getLoggerApi } from '@bitdev/angular.dev-services.common'; import type { BrowserBuilderOptions} from '@bitdev/angular.dev-services.ng-compat'; import { generateEntryPoints, @@ -108,8 +108,8 @@ async function getWebpackConfig( main: angularOptions.browser ?? `./${join(sourceRoot, `main.ts`)}`, polyfills: angularOptions.polyfills, tsConfig: angularOptions.tsConfig ?? tsconfigPath, - assets: dedupPaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]), - styles: dedupPaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage ?? 'scss' }`), ...(angularOptions.styles ?? [])]), + assets: dedupePaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]), + styles: dedupePaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage ?? 'scss' }`), ...(angularOptions.styles ?? [])]), scripts: angularOptions.scripts, vendorChunk: angularOptions.vendorChunk ?? true, namedChunks: angularOptions.namedChunks ?? true, diff --git a/angular/envs/angular-v17-env/webpack/module-rules.config.ts b/angular/envs/angular-v17-env/webpack/module-rules.config.ts index bfdf9b8c..81222520 100644 --- a/angular/envs/angular-v17-env/webpack/module-rules.config.ts +++ b/angular/envs/angular-v17-env/webpack/module-rules.config.ts @@ -16,9 +16,7 @@ const postCssConfig = { // https://github.com/facebook/create-react-app/issues/2677 ident: 'postcss', plugins: [ - // eslint-disable-next-line global-require require.resolve('postcss-flexbugs-fixes'), - // eslint-disable-next-line global-require require('postcss-preset-env')({ autoprefixer: { flexbox: 'no-2009', @@ -28,7 +26,7 @@ const postCssConfig = { // Adds PostCSS Normalize as the reset css with default options, // so that it honors browserslist config in package.json // which in turn lets users customize the target behavior as per their needs. - // require.resolve('postcss-normalize'), + // req.resolve('postcss-normalize'), ], }; diff --git a/angular/envs/angular-v18-env/angular-v18-env.bit-env.ts b/angular/envs/angular-v18-env/angular-v18-env.bit-env.ts index 1b37466b..75044114 100644 --- a/angular/envs/angular-v18-env/angular-v18-env.bit-env.ts +++ b/angular/envs/angular-v18-env/angular-v18-env.bit-env.ts @@ -1,20 +1,15 @@ import { AngularEnvOptions } from '@bitdev/angular.dev-services.common'; import { AngularBaseEnv } from '@bitdev/angular.envs.base-env'; -import { NativeCompileCache } from '@teambit/toolbox.performance.v8-cache'; import { createRequire } from 'node:module'; import { webpackConfigFactory } from './webpack-config.factory.js'; -// Disable v8-caching because it breaks ESM loaders -NativeCompileCache.uninstall(); - const require = createRequire(import.meta.url); export const ngEnvOptions: AngularEnvOptions = { useAngularElementsPreview: false, - // angularElementsModulePath: require.resolve('@angular/elements'), - jestConfigPath: require.resolve('./jest/jest.config.cjs'), + // angularElementsModulePath: req.resolve('@angular/elements'), jestModulePath: require.resolve('jest'), - ngPackagrModulePath: import.meta.resolve('ng-packagr'), + ngPackagrModulePath: require.resolve('ng-packagr'), webpackConfigFactory, webpackDevServerModulePath: require.resolve('webpack-dev-server'), // resolving to the webpack used by angular devkit to avoid multiple instances of webpack @@ -32,6 +27,9 @@ export class AngularV18Env extends AngularBaseEnv { angularVersion = 18; ngEnvOptions: AngularEnvOptions = ngEnvOptions; + + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = require.resolve('./jest/jest.config.cjs'); } export default new AngularV18Env(); diff --git a/angular/envs/angular-v18-env/angular-v18-env.docs.mdx b/angular/envs/angular-v18-env/angular-v18-env.docs.mdx index 8e22471f..ea99b46e 100644 --- a/angular/envs/angular-v18-env/angular-v18-env.docs.mdx +++ b/angular/envs/angular-v18-env/angular-v18-env.docs.mdx @@ -60,8 +60,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/envs/angular-v18-env/component.json b/angular/envs/angular-v18-env/component.json index 2db849b4..f6fd5eb4 100644 --- a/angular/envs/angular-v18-env/component.json +++ b/angular/envs/angular-v18-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "envs/angular-v18-env", - "version": "2.1.0" + "version": "3.0.1" }, "propagate": false, "extensions": { @@ -69,7 +69,9 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {} + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" + } } } diff --git a/angular/envs/angular-v18-env/env.jsonc b/angular/envs/angular-v18-env/env.jsonc index 074e9052..0600575f 100644 --- a/angular/envs/angular-v18-env/env.jsonc +++ b/angular/envs/angular-v18-env/env.jsonc @@ -18,13 +18,6 @@ * as a direct component dependencies. they are used for component development only. **/ "dev": [ - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^20.11.22", @@ -100,6 +93,11 @@ "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "jest", "version": "^29.5.0", diff --git a/angular/envs/angular-v18-env/index.ts b/angular/envs/angular-v18-env/index.ts index a0c5ac92..108f367b 100644 --- a/angular/envs/angular-v18-env/index.ts +++ b/angular/envs/angular-v18-env/index.ts @@ -1,3 +1 @@ export { AngularV18Env, ngEnvOptions } from './angular-v18-env.bit-env.js'; -// @ts-ignore -export { default as jestConfig } from './jest/jest.config.cjs'; diff --git a/angular/envs/angular-v18-env/webpack-config.factory.ts b/angular/envs/angular-v18-env/webpack-config.factory.ts index 1e6147a6..d689be50 100644 --- a/angular/envs/angular-v18-env/webpack-config.factory.ts +++ b/angular/envs/angular-v18-env/webpack-config.factory.ts @@ -1,7 +1,7 @@ /* eslint-disable no-param-reassign */ import { OutputHashing } from '@angular-devkit/build-angular'; import { getSystemPath, normalize, tags } from '@angular-devkit/core'; -import { BundlerSetup, dedupPaths, getLoggerApi } from '@bitdev/angular.dev-services.common'; +import { BundlerSetup, dedupePaths, getLoggerApi } from '@bitdev/angular.dev-services.common'; import type { BrowserBuilderOptions} from '@bitdev/angular.dev-services.ng-compat'; import { generateEntryPoints, @@ -108,8 +108,8 @@ async function getWebpackConfig( main: angularOptions.browser ?? `./${join(sourceRoot, `main.ts`)}`, polyfills: angularOptions.polyfills, tsConfig: angularOptions.tsConfig ?? tsconfigPath, - assets: dedupPaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]), - styles: dedupPaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage ?? 'scss' }`), ...(angularOptions.styles ?? [])]), + assets: dedupePaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]), + styles: dedupePaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage ?? 'scss' }`), ...(angularOptions.styles ?? [])]), scripts: angularOptions.scripts, vendorChunk: angularOptions.vendorChunk ?? true, namedChunks: angularOptions.namedChunks ?? true, diff --git a/angular/envs/angular-v19-env/angular-v19-env.bit-env.ts b/angular/envs/angular-v19-env/angular-v19-env.bit-env.ts index 640c3a31..e303c761 100644 --- a/angular/envs/angular-v19-env/angular-v19-env.bit-env.ts +++ b/angular/envs/angular-v19-env/angular-v19-env.bit-env.ts @@ -1,20 +1,15 @@ import { AngularEnvOptions } from '@bitdev/angular.dev-services.common'; import { AngularBaseEnv } from '@bitdev/angular.envs.base-env'; -import { NativeCompileCache } from '@teambit/toolbox.performance.v8-cache'; import { createRequire } from 'node:module'; import { webpackConfigFactory } from './webpack-config.factory.js'; -// Disable v8-caching because it breaks ESM loaders -NativeCompileCache.uninstall(); - const require = createRequire(import.meta.url); export const ngEnvOptions: AngularEnvOptions = { useAngularElementsPreview: false, - // angularElementsModulePath: require.resolve('@angular/elements'), - jestConfigPath: require.resolve('./jest/jest.config.cjs'), + // angularElementsModulePath: req.resolve('@angular/elements'), jestModulePath: require.resolve('jest'), - ngPackagrModulePath: import.meta.resolve('ng-packagr'), + ngPackagrModulePath: require.resolve('ng-packagr'), webpackConfigFactory, webpackDevServerModulePath: require.resolve('webpack-dev-server'), // resolving to the webpack used by angular devkit to avoid multiple instances of webpack @@ -32,6 +27,9 @@ export class AngularV19Env extends AngularBaseEnv { angularVersion = 19; ngEnvOptions: AngularEnvOptions = ngEnvOptions; + + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = require.resolve('./jest/jest.config.cjs'); } export default new AngularV19Env(); diff --git a/angular/envs/angular-v19-env/angular-v19-env.docs.mdx b/angular/envs/angular-v19-env/angular-v19-env.docs.mdx index 2fa7c23b..731165d4 100644 --- a/angular/envs/angular-v19-env/angular-v19-env.docs.mdx +++ b/angular/envs/angular-v19-env/angular-v19-env.docs.mdx @@ -60,8 +60,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/envs/angular-v19-env/component.json b/angular/envs/angular-v19-env/component.json index af32e418..1a8a0cd1 100644 --- a/angular/envs/angular-v19-env/component.json +++ b/angular/envs/angular-v19-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "envs/angular-v19-env", - "version": "1.1.0" + "version": "2.0.1" }, "propagate": false, "extensions": { @@ -67,7 +67,9 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {} + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" + } } } diff --git a/angular/envs/angular-v19-env/env.jsonc b/angular/envs/angular-v19-env/env.jsonc index d413aee8..5f811413 100644 --- a/angular/envs/angular-v19-env/env.jsonc +++ b/angular/envs/angular-v19-env/env.jsonc @@ -24,13 +24,6 @@ "hidden": true, "force": true }, - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^20.11.22", @@ -84,7 +77,7 @@ { "name": "@angular/platform-browser", "version": "^19.0.0", - "supportedRange": "19.0.0" + "supportedRange": "^19.0.0" }, { "name": "@angular/platform-browser-dynamic", @@ -111,6 +104,11 @@ "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "express", "version": "~4.21.1", diff --git a/angular/envs/angular-v19-env/index.ts b/angular/envs/angular-v19-env/index.ts index 7ea66394..09234856 100644 --- a/angular/envs/angular-v19-env/index.ts +++ b/angular/envs/angular-v19-env/index.ts @@ -1,3 +1 @@ export { AngularV19Env, ngEnvOptions } from './angular-v19-env.bit-env.js'; -// @ts-ignore -export { default as jestConfig } from './jest/jest.config.cjs'; diff --git a/angular/envs/angular-v19-env/webpack-config.factory.ts b/angular/envs/angular-v19-env/webpack-config.factory.ts index b691057f..67b1cbb5 100644 --- a/angular/envs/angular-v19-env/webpack-config.factory.ts +++ b/angular/envs/angular-v19-env/webpack-config.factory.ts @@ -1,7 +1,7 @@ /* eslint-disable no-param-reassign */ import { OutputHashing } from '@angular-devkit/build-angular'; import { getSystemPath, normalize, tags } from '@angular-devkit/core'; -import { BundlerSetup, dedupPaths, getLoggerApi } from '@bitdev/angular.dev-services.common'; +import { BundlerSetup, dedupePaths, getLoggerApi } from '@bitdev/angular.dev-services.common'; import type { BrowserBuilderOptions} from '@bitdev/angular.dev-services.ng-compat'; import { generateEntryPoints, @@ -108,8 +108,8 @@ async function getWebpackConfig( main: angularOptions.browser ?? `./${join(sourceRoot, `main.ts`)}`, polyfills: angularOptions.polyfills, tsConfig: angularOptions.tsConfig ?? tsconfigPath, - assets: dedupPaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]), - styles: dedupPaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage ?? 'scss' }`), ...(angularOptions.styles ?? [])]), + assets: dedupePaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]), + styles: dedupePaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage ?? 'scss' }`), ...(angularOptions.styles ?? [])]), scripts: angularOptions.scripts, vendorChunk: angularOptions.vendorChunk ?? true, namedChunks: angularOptions.namedChunks ?? true, diff --git a/angular/envs/angular-v19-env/webpack/module-rules.config.ts b/angular/envs/angular-v19-env/webpack/module-rules.config.ts index bfdf9b8c..00c99cc7 100644 --- a/angular/envs/angular-v19-env/webpack/module-rules.config.ts +++ b/angular/envs/angular-v19-env/webpack/module-rules.config.ts @@ -1,7 +1,8 @@ import { generateStyleLoaders } from '@teambit/webpack.modules.generate-style-loaders'; import * as stylesRegexps from '@teambit/webpack.modules.style-regexps'; import { merge } from 'lodash-es'; -import { createRequire } from 'node:module'; +// @ts-ignore +import postCssPresetEnv from 'postcss-preset-env'; // @ts-ignore import getLocalIdent from 'react-dev-utils-esm/getCSSModuleLocalIdent.js'; import RemarkFrontmatter from 'remark-frontmatter'; @@ -9,17 +10,13 @@ import RemarkHTML from 'remark-html'; import RemarkPrism from 'remark-prism'; import { RuleSetRule } from 'webpack'; -const require = createRequire(import.meta.url); - const postCssConfig = { // Necessary for external CSS imports to work // https://github.com/facebook/create-react-app/issues/2677 ident: 'postcss', plugins: [ - // eslint-disable-next-line global-require - require.resolve('postcss-flexbugs-fixes'), - // eslint-disable-next-line global-require - require('postcss-preset-env')({ + import.meta.resolve('postcss-flexbugs-fixes'), + postCssPresetEnv({ autoprefixer: { flexbox: 'no-2009', }, @@ -28,11 +25,11 @@ const postCssConfig = { // Adds PostCSS Normalize as the reset css with default options, // so that it honors browserslist config in package.json // which in turn lets users customize the target behavior as per their needs. - // require.resolve('postcss-normalize'), + // import.meta.resolve('postcss-normalize'), ], }; -const styleLoaderPath = require.resolve('style-loader'); +const styleLoaderPath = import.meta.resolve('style-loader'); // Source maps are resource heavy and can cause out of memory issue for large source files. const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; @@ -40,8 +37,8 @@ const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; export function getModuleRulesConfig(isEnvProduction: boolean): RuleSetRule[] { const baseStyleLoadersOptions = { injectingLoader: styleLoaderPath, - cssLoaderPath: require.resolve('css-loader'), - postCssLoaderPath: require.resolve('postcss-loader'), + cssLoaderPath: import.meta.resolve('css-loader'), + postCssLoaderPath: import.meta.resolve('postcss-loader'), postCssConfig }; @@ -130,8 +127,8 @@ export function getModuleRulesConfig(isEnvProduction: boolean): RuleSetRule[] { }, shouldUseSourceMap: isEnvProduction || shouldUseSourceMap, preProcessOptions: { - resolveUrlLoaderPath: require.resolve('resolve-url-loader'), - preProcessorPath: require.resolve('sass-loader') + resolveUrlLoaderPath: import.meta.resolve('resolve-url-loader'), + preProcessorPath: import.meta.resolve('sass-loader') } }) ) 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 b2725c18..a017784d 100644 --- a/angular/envs/base-env/angular-base-env.bit-env.ts +++ b/angular/envs/base-env/angular-base-env.bit-env.ts @@ -1,20 +1,13 @@ import { AngularEnvOptions } from '@bitdev/angular.dev-services.common'; -import { - NgMultiCompiler, - NgMultiCompilerTask -} from '@bitdev/angular.dev-services.compiler.multi-compiler'; -import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; +import { NgMultiCompiler, NgMultiCompilerTask } from '@bitdev/angular.dev-services.compiler.multi-compiler'; +import { AngularVitePreview } from "@bitdev/angular.dev-services.preview.vite-preview"; import { NgAppTemplate, NgEnvTemplate, NgModuleTemplate, NgStandaloneTemplate } from '@bitdev/angular.templates.generators'; -import { - AngularStarter, - DesignSystemStarter, - MaterialDesignSystemStarter -} from '@bitdev/angular.templates.starters'; +import { AngularStarter, DesignSystemStarter, MaterialDesignSystemStarter } from '@bitdev/angular.templates.starters'; import { CAPSULE_ARTIFACTS_DIR, Pipeline } from '@teambit/builder'; import { Compiler } from '@teambit/compiler'; import { EslintConfigWriter, ESLintLinter, EslintTask } from '@teambit/defender.eslint-linter'; @@ -35,7 +28,6 @@ import { ESLint as ESLintLib } from 'eslint'; import { merge } from 'lodash-es'; import { createRequire } from 'node:module'; import { AngularEnvInterface } from './angular-env.interface.js'; -import hostDependencies from './preview/host-dependencies.js'; let ngMultiCompiler: EnvHandler | undefined; @@ -56,6 +48,23 @@ export abstract class AngularBaseEnv implements AngularEnvInterface { [key: string]: any; + /*** Default functions & properties that custom envs will override ***/ + /* Typescript config used for linter, schema extractor and config writer */ + protected tsconfigPath = require.resolve('./config/tsconfig.json'); + + /* ESLint config. Learn how to replace linter - https://bit.dev/reference/linting/set-up-linter */ + protected eslintConfigPath = require.resolve('./config/eslintrc.cjs'); + + /* Prettier config. Learn how to replace formatter - https://bit.dev/reference/formatting/set-up-formatter */ + protected prettierConfigPath = require.resolve('./config/prettier.config.cjs'); + + /* Component mounting and dev-server config. Learn how to replace dev-server - https://bit.dev/reference/preview/setup-preview */ + protected previewMounterPath = require.resolve('./config/mounter.js'); + + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected abstract jestConfigPath: string; + /*** End of default functions & properties ***/ + public getNgEnvOptions(): AngularEnvOptions { return { ...this.ngEnvOptions }; } @@ -98,15 +107,15 @@ export abstract class AngularBaseEnv implements AngularEnvInterface { formatter(): EnvHandler { return PrettierFormatter.from({ - configPath: require.resolve('./config/prettier.config.cjs') + configPath: this.prettierConfigPath }); } getLinterConfig(): any { return { - tsconfig: require.resolve('./config/tsconfig.json'), + tsconfig: this.tsconfigPath, eslint: ESLintLib, - configPath: require.resolve('./config/eslintrc.cjs'), + configPath: this.eslintConfigPath, // resolve all plugins from the angular environment. pluginsPath: import.meta.dirname, extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs'] @@ -149,12 +158,22 @@ export abstract class AngularBaseEnv implements AngularEnvInterface { } preview(): EnvHandler { + return AngularVitePreview.from({ + mounterPath: this.previewMounterPath + }); + + /*const hostDependencies = [ + '@teambit/mdx.ui.mdx-scope-context', + '@mdx-js/react', + 'react', + 'react-dom', + ]; const ngEnvOptions = this.getNgEnvOptions(); return AngularPreview.from({ ngEnvOptions, hostDependencies, - mounterPath: require.resolve('./preview/mounter.js'), - }); + mounterPath: this.previewMounterPath + });*/ } /** @@ -163,7 +182,7 @@ export abstract class AngularBaseEnv implements AngularEnvInterface { */ schemaExtractor(): EnvHandler { return TypeScriptExtractor.from({ - tsconfig: require.resolve('./config/tsconfig.json') + tsconfig: this.tsconfigPath }); } @@ -213,23 +232,22 @@ export abstract class AngularBaseEnv implements AngularEnvInterface { workspaceConfig(): ConfigWriterList { return ConfigWriterList.from([ TypescriptConfigWriter.from({ - tsconfig: require.resolve('./config/tsconfig.json') + tsconfig: this.tsconfigPath }), EslintConfigWriter.from({ - configPath: require.resolve('./config/eslintrc.cjs'), - tsconfig: require.resolve('./config/tsconfig.json') + configPath: this.eslintConfigPath, + tsconfig: this.tsconfigPath }), PrettierConfigWriter.from({ - configPath: require.resolve('./config/prettier.config.cjs') + configPath: this.prettierConfigPath }) ]); } getTesterConfig() { - const ngEnvOptions = this.getNgEnvOptions(); return { - jest: ngEnvOptions.jestModulePath, - config: ngEnvOptions.jestConfigPath + jest: this.jestModulePath, + config: this.jestConfigPath }; // return VitestTester.from({ // config: require.resolve(ngEnvOptions.vitestConfigPath) diff --git a/angular/envs/base-env/component.json b/angular/envs/base-env/component.json index ba9efa83..938208c4 100644 --- a/angular/envs/base-env/component.json +++ b/angular/envs/base-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "envs/base-env", - "version": "7.1.0" + "version": "8.0.1" }, "propagate": false, "extensions": { @@ -52,14 +52,16 @@ } } }, - "teambit.envs/envs": {}, - "bitdev.node/node-env@2.0.2": {}, "teambit.component/renaming": { "renamedFrom": { "scope": "bitdev.angular", "name": "envs/base", "version": "547117b9b87b26959751781746560193ca3af410" } + }, + "bitdev.node/node-env@2.0.40": {}, + "teambit.envs/envs": { + "env": "bitdev.node/node-env" } } } diff --git a/angular/envs/base-env/config/mounter.ts b/angular/envs/base-env/config/mounter.ts new file mode 100644 index 00000000..e0b86263 --- /dev/null +++ b/angular/envs/base-env/config/mounter.ts @@ -0,0 +1,27 @@ +import { createMounter } from '@bitdev/angular.dev-services.preview.mounter'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import { Component, ViewEncapsulation } from '@angular/core'; + +/** + * Provide your component compositions (preview) with the context they need to run. + * for example, a router, a theme, a data provider, etc. + * components added here as providers should be listed as host-dependencies + * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers + */ +@Component({ + selector: 'bit-wrapper', + // @ts-ignore + standalone: true, + imports: [], + encapsulation: ViewEncapsulation.None, + template: ` + + `, +}) export class WrapperComponent {} + +/** + * the entry for the app (preview runtime) that renders your component previews. + * use the default template or create your own. + * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers + */ +export default createMounter(WrapperComponent); diff --git a/angular/envs/base-env/index.ts b/angular/envs/base-env/index.ts index bf36fe2b..94b91a3a 100644 --- a/angular/envs/base-env/index.ts +++ b/angular/envs/base-env/index.ts @@ -1,4 +1,2 @@ export { AngularBaseEnv } from './angular-base-env.bit-env.js'; export type { AngularEnvInterface } from './angular-env.interface.js'; -// @ts-ignore -export { default as prettierConfig } from './config/prettier.config.cjs'; diff --git a/angular/envs/base-env/preview/host-dependencies.ts b/angular/envs/base-env/preview/host-dependencies.ts deleted file mode 100644 index 6f6a9bb7..00000000 --- a/angular/envs/base-env/preview/host-dependencies.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Dependencies to be bundled only once, in the env preview template, and not in each component preview. - * most of your peer dependencies should be listed here to avoid duplications in the preview. - * React, ReactDOM, and MDX are included as they are part of the preview ui. - */ -export default [ - '@teambit/mdx.ui.mdx-scope-context', - '@mdx-js/react', - 'react', - 'react-dom', -]; diff --git a/angular/examples/my-angular-env/component.json b/angular/examples/my-angular-env/component.json index 4ef9c801..518ed2cb 100644 --- a/angular/examples/my-angular-env/component.json +++ b/angular/examples/my-angular-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "examples/my-angular-env", - "version": "7.1.0" + "version": "8.0.1" }, "propagate": false, "extensions": { @@ -18,14 +18,16 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {}, "teambit.component/renaming": { "renamedFrom": { "scope": "bitdev.angular", "name": "examples/angular-env", "version": "1.0.1" } + }, + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" } } } diff --git a/angular/examples/my-angular-v17-env/preview/mounter.ts b/angular/examples/my-angular-env/config/mounter.ts similarity index 95% rename from angular/examples/my-angular-v17-env/preview/mounter.ts rename to angular/examples/my-angular-env/config/mounter.ts index 6831d115..1420a724 100644 --- a/angular/examples/my-angular-v17-env/preview/mounter.ts +++ b/angular/examples/my-angular-env/config/mounter.ts @@ -5,7 +5,7 @@ import { Component, ViewEncapsulation } from '@angular/core'; /** * Provide your component compositions (preview) with the context they need to run. * for example, a router, a theme, a data provider, etc. - * components added here as providers should be listed as host-dependencies in your host-dependencies.ts file. + * components added here as providers should be listed as host-dependencies * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers */ @Component({ diff --git a/angular/examples/my-angular-env/env.jsonc b/angular/examples/my-angular-env/env.jsonc index d345a517..7fdba035 100644 --- a/angular/examples/my-angular-env/env.jsonc +++ b/angular/examples/my-angular-env/env.jsonc @@ -18,13 +18,6 @@ * as a direct component dependencies. they are used for component development only. **/ "dev": [ - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^20.11.22", @@ -84,7 +77,7 @@ { "name": "@angular/platform-browser", "version": "^19.0.0", - "supportedRange": "19.0.0" + "supportedRange": "^19.0.0" }, { "name": "@angular/platform-browser-dynamic", @@ -111,6 +104,11 @@ "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "express", "version": "~4.21.1", 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 369cf101..93f8a604 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,141 +1,26 @@ import { AngularEnv } from '@bitdev/angular.angular-env'; -import { - NgMultiCompiler, - NgMultiCompilerTask -} from '@bitdev/angular.dev-services.compiler.multi-compiler'; -import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; -import { Pipeline } from '@teambit/builder'; -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'; -import { EnvHandler } from '@teambit/envs'; -import { Linter } from '@teambit/linter'; -import { Preview } from '@teambit/preview'; -import { Tester } from '@teambit/tester'; -import { TypescriptConfigWriter } from '@teambit/typescript.typescript-compiler'; -import { ConfigWriterList } from '@teambit/workspace-config-files'; -import { ESLint as ESLintLib } from 'eslint'; import { createRequire } from 'node:module'; -import hostDependencies from './preview/host-dependencies.js'; -let ngMultiCompiler: EnvHandler | undefined; - -const require = createRequire(import.meta.url); +const req = createRequire(import.meta.url); export class MyAngularEnv extends AngularEnv { - // Name of the environment, used for friendly mentions across bit + /* Name of the environment, used for friendly mentions across bit */ name = 'my-angular-env'; - getTesterConfig() { - return { - jest: require.resolve('jest'), - config: require.resolve('./config/jest.config.cjs') - }; - } - - /** - * Returns a tester to use during development - * Required for `bit start` & `bit test` - */ - override tester(): EnvHandler { - /** - * @see https://bit.dev/reference/jest/using-jest - * */ - return JestTester.from(this.getTesterConfig()); - } - - getLinterConfig() { - return { - tsconfig: require.resolve('./config/tsconfig.json'), - eslint: ESLintLib, - configPath: require.resolve('./config/eslintrc.cjs'), - // resolve all plugins from the angular environment. - pluginsPath: import.meta.dirname, - extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs'] - }; - } - - /** - * 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. - * bit will write the minimum required files in any workspace to optimize - * for dev experience. - */ - override linter(): EnvHandler { - return ESLintLinter.from(this.getLinterConfig()); - } + /* Typescript config used for linter, schema extractor and config writer */ + protected tsconfigPath = req.resolve('./config/tsconfig.json'); - /** - * The formatter to use during development - * (source files are not formatted as part of the components' build) - * */ - override formatter() { - /** - * @see https://bit.dev/reference/prettier/using-prettier - * */ - return PrettierFormatter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }); - } + /* ESLint config. Learn how to replace linter - https://bit.dev/reference/linting/set-up-linter */ + protected eslintConfigPath = req.resolve('./config/eslintrc.cjs'); - /** - * Generates the component previews during development and build - */ - override preview(): EnvHandler { - const tsConfig = require.resolve('./config/tsconfig.json'); - return AngularPreview.from({ - ngEnvOptions: this.getNgEnvOptions(), - hostDependencies, - mounterPath: require.resolve('./preview/mounter.js'), - angularServeOptions: { tsConfig }, - angularBuildOptions: { tsConfig }, - }); - } + /* Prettier config. Learn how to replace formatter - https://bit.dev/reference/formatting/set-up-formatter */ + protected prettierConfigPath = req.resolve('./config/prettier.config.cjs'); - /** - * Defines the build pipeline for a component. - * Pipelines are optimized for performance and consistency, making sure every component is - * independently built and tested. - * This is a set of processes to be performed before a component is snapped, during its build phase - * @see https://bit.dev/docs/my-angular-env/build-pipelines - */ - override build(): Pipeline { - return Pipeline.from([ - NgMultiCompilerTask.from({ ngMultiCompiler: this.compiler() }), - EslintTask.from(this.getLinterConfig()), - JestTask.from(this.getTesterConfig()) - ]); - } + /* Component mounting and dev-server config. Learn how to replace dev-server - https://bit.dev/reference/preview/setup-preview */ + protected previewMounterPath = req.resolve('./config/mounter.js'); - override workspaceConfig(): ConfigWriterList { - return ConfigWriterList.from([ - TypescriptConfigWriter.from({ - tsconfig: require.resolve('./config/tsconfig.json') - }), - EslintConfigWriter.from({ - configPath: require.resolve('./config/eslintrc.cjs'), - tsconfig: require.resolve('./config/tsconfig.json') - }), - PrettierConfigWriter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }) - ]); - } + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = req.resolve('./config/jest.config.cjs'); } export default new MyAngularEnv(); diff --git a/angular/examples/my-angular-env/my-angular-env.docs.mdx b/angular/examples/my-angular-env/my-angular-env.docs.mdx index 9cf3bfcb..9133eb13 100644 --- a/angular/examples/my-angular-env/my-angular-env.docs.mdx +++ b/angular/examples/my-angular-env/my-angular-env.docs.mdx @@ -61,8 +61,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/examples/my-angular-env/preview/host-dependencies.ts b/angular/examples/my-angular-env/preview/host-dependencies.ts deleted file mode 100644 index 6f6a9bb7..00000000 --- a/angular/examples/my-angular-env/preview/host-dependencies.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Dependencies to be bundled only once, in the env preview template, and not in each component preview. - * most of your peer dependencies should be listed here to avoid duplications in the preview. - * React, ReactDOM, and MDX are included as they are part of the preview ui. - */ -export default [ - '@teambit/mdx.ui.mdx-scope-context', - '@mdx-js/react', - 'react', - 'react-dom', -]; diff --git a/angular/examples/my-angular-v16-env/component.json b/angular/examples/my-angular-v16-env/component.json index e91ef92d..c6e4b363 100644 --- a/angular/examples/my-angular-v16-env/component.json +++ b/angular/examples/my-angular-v16-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "examples/my-angular-v16-env", - "version": "6.1.0" + "version": "7.0.1" }, "propagate": false, "extensions": { @@ -17,14 +17,16 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {}, "teambit.component/renaming": { "renamedFrom": { "scope": "bitdev.angular", "name": "examples/angular-v16-env", "version": "1.0.1" } + }, + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" } } } diff --git a/angular/examples/my-angular-v18-env/preview/mounter.ts b/angular/examples/my-angular-v16-env/config/mounter.ts similarity index 95% rename from angular/examples/my-angular-v18-env/preview/mounter.ts rename to angular/examples/my-angular-v16-env/config/mounter.ts index 6831d115..1420a724 100644 --- a/angular/examples/my-angular-v18-env/preview/mounter.ts +++ b/angular/examples/my-angular-v16-env/config/mounter.ts @@ -5,7 +5,7 @@ import { Component, ViewEncapsulation } from '@angular/core'; /** * Provide your component compositions (preview) with the context they need to run. * for example, a router, a theme, a data provider, etc. - * components added here as providers should be listed as host-dependencies in your host-dependencies.ts file. + * components added here as providers should be listed as host-dependencies * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers */ @Component({ diff --git a/angular/examples/my-angular-v16-env/env.jsonc b/angular/examples/my-angular-v16-env/env.jsonc index ab1e5f9e..9f6c02f9 100644 --- a/angular/examples/my-angular-v16-env/env.jsonc +++ b/angular/examples/my-angular-v16-env/env.jsonc @@ -18,13 +18,6 @@ * as a direct component dependencies. they are used for component development only. **/ "dev": [ - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^16.11.7", @@ -95,6 +88,11 @@ "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "jest", "version": "^29.5.0", 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 0cd48761..7a5caa20 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,141 +1,26 @@ -import { - NgMultiCompiler, - NgMultiCompilerTask -} from '@bitdev/angular.dev-services.compiler.multi-compiler'; -import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; import { AngularV16Env } from '@bitdev/angular.envs.angular-v16-env'; -import { Pipeline } from '@teambit/builder'; -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'; -import { EnvHandler } from '@teambit/envs'; -import { Linter } from '@teambit/linter'; -import { Preview } from '@teambit/preview'; -import { Tester } from '@teambit/tester'; -import { TypescriptConfigWriter } from '@teambit/typescript.typescript-compiler'; -import { ConfigWriterList } from '@teambit/workspace-config-files'; -import { ESLint as ESLintLib } from 'eslint'; import { createRequire } from 'node:module'; -import hostDependencies from './preview/host-dependencies.js'; -let ngMultiCompiler: EnvHandler | undefined; - -const require = createRequire(import.meta.url); +const req = createRequire(import.meta.url); export class MyAngularV16Env extends AngularV16Env { - // Name of the environment, used for friendly mentions across bit + /* Name of the environment, used for friendly mentions across bit */ name = 'my-angular-v16-env'; - getTesterConfig() { - return { - jest: require.resolve('jest'), - config: require.resolve('./config/jest.config.cjs') - }; - } - - /** - * Returns a tester to use during development - * Required for `bit start` & `bit test` - */ - override tester(): EnvHandler { - /** - * @see https://bit.dev/reference/jest/using-jest - * */ - return JestTester.from(this.getTesterConfig()); - } - - getLinterConfig() { - return { - tsconfig: require.resolve('./config/tsconfig.json'), - eslint: ESLintLib, - configPath: require.resolve('./config/eslintrc.cjs'), - // resolve all plugins from the angular environment. - pluginsPath: import.meta.dirname, - extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs'] - }; - } - - /** - * 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. - * bit will write the minimum required files in any workspace to optimize - * for dev experience. - */ - override linter(): EnvHandler { - return ESLintLinter.from(this.getLinterConfig()); - } + /* Typescript config used for linter, schema extractor and config writer */ + protected tsconfigPath = req.resolve('./config/tsconfig.json'); - /** - * The formatter to use during development - * (source files are not formatted as part of the components' build) - * */ - override formatter() { - /** - * @see https://bit.dev/reference/prettier/using-prettier - * */ - return PrettierFormatter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }); - } + /* ESLint config. Learn how to replace linter - https://bit.dev/reference/linting/set-up-linter */ + protected eslintConfigPath = req.resolve('./config/eslintrc.cjs'); - /** - * Generates the component previews during development and build - */ - override preview(): EnvHandler { - const tsConfig = require.resolve('./config/tsconfig.json'); - return AngularPreview.from({ - ngEnvOptions: this.getNgEnvOptions(), - hostDependencies, - mounterPath: require.resolve('./preview/mounter.js'), - angularServeOptions: { tsConfig }, - angularBuildOptions: { tsConfig }, - }); - } + /* Prettier config. Learn how to replace formatter - https://bit.dev/reference/formatting/set-up-formatter */ + protected prettierConfigPath = req.resolve('./config/prettier.config.cjs'); - /** - * Defines the build pipeline for a component. - * Pipelines are optimized for performance and consistency, making sure every component is - * independently built and tested. - * This is a set of processes to be performed before a component is snapped, during its build phase - * @see https://bit.dev/docs/angular-env/build-pipelines - */ - override build(): Pipeline { - return Pipeline.from([ - NgMultiCompilerTask.from({ ngMultiCompiler: this.compiler() }), - EslintTask.from(this.getLinterConfig()), - JestTask.from(this.getTesterConfig()) - ]); - } + /* Component mounting and dev-server config. Learn how to replace dev-server - https://bit.dev/reference/preview/setup-preview */ + protected previewMounterPath = req.resolve('./config/mounter.js'); - override workspaceConfig(): ConfigWriterList { - return ConfigWriterList.from([ - TypescriptConfigWriter.from({ - tsconfig: require.resolve('./config/tsconfig.json') - }), - EslintConfigWriter.from({ - configPath: require.resolve('./config/eslintrc.cjs'), - tsconfig: require.resolve('./config/tsconfig.json') - }), - PrettierConfigWriter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }) - ]); - } + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = req.resolve('./config/jest.config.cjs'); } export default new MyAngularV16Env(); diff --git a/angular/examples/my-angular-v16-env/my-angular-v16-env.docs.mdx b/angular/examples/my-angular-v16-env/my-angular-v16-env.docs.mdx index 75a0dcaf..f2843bb7 100644 --- a/angular/examples/my-angular-v16-env/my-angular-v16-env.docs.mdx +++ b/angular/examples/my-angular-v16-env/my-angular-v16-env.docs.mdx @@ -61,8 +61,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/examples/my-angular-v16-env/preview/host-dependencies.ts b/angular/examples/my-angular-v16-env/preview/host-dependencies.ts deleted file mode 100644 index 6f6a9bb7..00000000 --- a/angular/examples/my-angular-v16-env/preview/host-dependencies.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Dependencies to be bundled only once, in the env preview template, and not in each component preview. - * most of your peer dependencies should be listed here to avoid duplications in the preview. - * React, ReactDOM, and MDX are included as they are part of the preview ui. - */ -export default [ - '@teambit/mdx.ui.mdx-scope-context', - '@mdx-js/react', - 'react', - 'react-dom', -]; diff --git a/angular/examples/my-angular-v17-env/component.json b/angular/examples/my-angular-v17-env/component.json index 0a9e9386..cb6ffc93 100644 --- a/angular/examples/my-angular-v17-env/component.json +++ b/angular/examples/my-angular-v17-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "examples/my-angular-v17-env", - "version": "6.1.0" + "version": "7.0.1" }, "propagate": false, "extensions": { @@ -17,7 +17,9 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {} + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" + } } } diff --git a/angular/examples/my-angular-env/preview/mounter.ts b/angular/examples/my-angular-v17-env/config/mounter.ts similarity index 95% rename from angular/examples/my-angular-env/preview/mounter.ts rename to angular/examples/my-angular-v17-env/config/mounter.ts index 6831d115..1420a724 100644 --- a/angular/examples/my-angular-env/preview/mounter.ts +++ b/angular/examples/my-angular-v17-env/config/mounter.ts @@ -5,7 +5,7 @@ import { Component, ViewEncapsulation } from '@angular/core'; /** * Provide your component compositions (preview) with the context they need to run. * for example, a router, a theme, a data provider, etc. - * components added here as providers should be listed as host-dependencies in your host-dependencies.ts file. + * components added here as providers should be listed as host-dependencies * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers */ @Component({ diff --git a/angular/examples/my-angular-v17-env/env.jsonc b/angular/examples/my-angular-v17-env/env.jsonc index 704692e3..a5333fa5 100644 --- a/angular/examples/my-angular-v17-env/env.jsonc +++ b/angular/examples/my-angular-v17-env/env.jsonc @@ -18,13 +18,6 @@ * as a direct component dependencies. they are used for component development only. **/ "dev": [ - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^20.11.22", @@ -42,59 +35,64 @@ "peers": [ { "name": "@angular/animations", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/common", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/compiler", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/compiler-cli", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/core", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/forms", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/platform-browser", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/platform-browser-dynamic", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/platform-server", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@angular/router", - "version": "^17.0.0", - "supportedRange": "^17.0.0" + "version": "^17.3.0", + "supportedRange": "^17.3.0" }, { "name": "@types/eslint", "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "jest", "version": "^29.5.0", diff --git a/angular/examples/my-angular-v17-env/index.ts b/angular/examples/my-angular-v17-env/index.ts index d54add6b..0e0f4d0a 100644 --- a/angular/examples/my-angular-v17-env/index.ts +++ b/angular/examples/my-angular-v17-env/index.ts @@ -1,3 +1 @@ export { MyAngularV17Env, MyAngularV17Env as default } from './my-angular-v17-env.bit-env.js'; -// @ts-ignore -export { default as jestConfig } from './config/jest.config.cjs'; \ No newline at end of file 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 0b76e6de..bae92eb6 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,141 +1,26 @@ -import { - NgMultiCompiler, - NgMultiCompilerTask -} from '@bitdev/angular.dev-services.compiler.multi-compiler'; -import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; import { AngularV17Env } from '@bitdev/angular.envs.angular-v17-env'; -import { Pipeline } from '@teambit/builder'; -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'; -import { EnvHandler } from '@teambit/envs'; -import { Linter } from '@teambit/linter'; -import { Preview } from '@teambit/preview'; -import { Tester } from '@teambit/tester'; -import { TypescriptConfigWriter } from '@teambit/typescript.typescript-compiler'; -import { ConfigWriterList } from '@teambit/workspace-config-files'; -import { ESLint as ESLintLib } from 'eslint'; import { createRequire } from 'node:module'; -import hostDependencies from './preview/host-dependencies.js'; -let ngMultiCompiler: EnvHandler | undefined; - -const require = createRequire(import.meta.url); +const req = createRequire(import.meta.url); export class MyAngularV17Env extends AngularV17Env { // Name of the environment, used for friendly mentions across bit name = 'my-angular-v17-env'; - getTesterConfig() { - return { - jest: require.resolve('jest'), - config: require.resolve('./config/jest.config.cjs') - }; - } - - /** - * Returns a tester to use during development - * Required for `bit start` & `bit test` - */ - override tester(): EnvHandler { - /** - * @see https://bit.dev/reference/jest/using-jest - * */ - return JestTester.from(this.getTesterConfig()); - } - - getLinterConfig() { - return { - tsconfig: require.resolve('./config/tsconfig.json'), - eslint: ESLintLib, - configPath: require.resolve('./config/eslintrc.cjs'), - // resolve all plugins from the angular environment. - pluginsPath: import.meta.dirname, - extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs'] - }; - } - - /** - * 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. - * bit will write the minimum required files in any workspace to optimize - * for dev experience. - */ - override linter(): EnvHandler { - return ESLintLinter.from(this.getLinterConfig()); - } + /* Typescript config used for linter, schema extractor and config writer */ + protected tsconfigPath = req.resolve('./config/tsconfig.json'); - /** - * The formatter to use during development - * (source files are not formatted as part of the components' build) - * */ - override formatter() { - /** - * @see https://bit.dev/reference/prettier/using-prettier - * */ - return PrettierFormatter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }); - } + /* ESLint config. Learn how to replace linter - https://bit.dev/reference/linting/set-up-linter */ + protected eslintConfigPath = req.resolve('./config/eslintrc.cjs'); - /** - * Generates the component previews during development and build - */ - override preview(): EnvHandler { - const tsConfig = require.resolve('./config/tsconfig.json'); - return AngularPreview.from({ - ngEnvOptions: this.getNgEnvOptions(), - hostDependencies, - mounterPath: require.resolve('./preview/mounter.js'), - angularServeOptions: { tsConfig }, - angularBuildOptions: { tsConfig }, - }); - } + /* Prettier config. Learn how to replace formatter - https://bit.dev/reference/formatting/set-up-formatter */ + protected prettierConfigPath = req.resolve('./config/prettier.config.cjs'); - /** - * Defines the build pipeline for a component. - * Pipelines are optimized for performance and consistency, making sure every component is - * independently built and tested. - * This is a set of processes to be performed before a component is snapped, during its build phase - * @see https://bit.dev/docs/angular-env/build-pipelines - */ - override build(): Pipeline { - return Pipeline.from([ - NgMultiCompilerTask.from({ ngMultiCompiler: this.compiler() }), - EslintTask.from(this.getLinterConfig()), - JestTask.from(this.getTesterConfig()) - ]); - } + /* Component mounting and dev-server config. Learn how to replace dev-server - https://bit.dev/reference/preview/setup-preview */ + protected previewMounterPath = req.resolve('./config/mounter.js'); - override workspaceConfig(): ConfigWriterList { - return ConfigWriterList.from([ - TypescriptConfigWriter.from({ - tsconfig: require.resolve('./config/tsconfig.json') - }), - EslintConfigWriter.from({ - configPath: require.resolve('./config/eslintrc.cjs'), - tsconfig: require.resolve('./config/tsconfig.json') - }), - PrettierConfigWriter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }) - ]); - } + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = req.resolve('./config/jest.config.cjs'); } export default new MyAngularV17Env(); diff --git a/angular/examples/my-angular-v17-env/my-angular-v17-env.docs.mdx b/angular/examples/my-angular-v17-env/my-angular-v17-env.docs.mdx index e424639a..6ca0b3f1 100644 --- a/angular/examples/my-angular-v17-env/my-angular-v17-env.docs.mdx +++ b/angular/examples/my-angular-v17-env/my-angular-v17-env.docs.mdx @@ -61,8 +61,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/examples/my-angular-v17-env/preview/host-dependencies.ts b/angular/examples/my-angular-v17-env/preview/host-dependencies.ts deleted file mode 100644 index 6f6a9bb7..00000000 --- a/angular/examples/my-angular-v17-env/preview/host-dependencies.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Dependencies to be bundled only once, in the env preview template, and not in each component preview. - * most of your peer dependencies should be listed here to avoid duplications in the preview. - * React, ReactDOM, and MDX are included as they are part of the preview ui. - */ -export default [ - '@teambit/mdx.ui.mdx-scope-context', - '@mdx-js/react', - 'react', - 'react-dom', -]; diff --git a/angular/examples/my-angular-v18-env/component.json b/angular/examples/my-angular-v18-env/component.json index 9e93474a..20967327 100644 --- a/angular/examples/my-angular-v18-env/component.json +++ b/angular/examples/my-angular-v18-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "examples/my-angular-v18-env", - "version": "2.1.0" + "version": "3.0.1" }, "propagate": false, "extensions": { @@ -18,7 +18,9 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {} + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" + } } } diff --git a/angular/examples/my-angular-v16-env/preview/mounter.ts b/angular/examples/my-angular-v18-env/config/mounter.ts similarity index 95% rename from angular/examples/my-angular-v16-env/preview/mounter.ts rename to angular/examples/my-angular-v18-env/config/mounter.ts index 6831d115..1420a724 100644 --- a/angular/examples/my-angular-v16-env/preview/mounter.ts +++ b/angular/examples/my-angular-v18-env/config/mounter.ts @@ -5,7 +5,7 @@ import { Component, ViewEncapsulation } from '@angular/core'; /** * Provide your component compositions (preview) with the context they need to run. * for example, a router, a theme, a data provider, etc. - * components added here as providers should be listed as host-dependencies in your host-dependencies.ts file. + * components added here as providers should be listed as host-dependencies * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers */ @Component({ diff --git a/angular/examples/my-angular-v18-env/env.jsonc b/angular/examples/my-angular-v18-env/env.jsonc index 074e9052..0600575f 100644 --- a/angular/examples/my-angular-v18-env/env.jsonc +++ b/angular/examples/my-angular-v18-env/env.jsonc @@ -18,13 +18,6 @@ * as a direct component dependencies. they are used for component development only. **/ "dev": [ - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^20.11.22", @@ -100,6 +93,11 @@ "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "jest", "version": "^29.5.0", diff --git a/angular/examples/my-angular-v18-env/index.ts b/angular/examples/my-angular-v18-env/index.ts index ed75e91a..2f3de0f3 100644 --- a/angular/examples/my-angular-v18-env/index.ts +++ b/angular/examples/my-angular-v18-env/index.ts @@ -1,3 +1 @@ export { MyAngularV18Env, MyAngularV18Env as default } from './my-angular-v18-env.bit-env.js'; -// @ts-ignore -export { default as jestConfig } from './config/jest.config.cjs'; diff --git a/angular/examples/my-angular-v18-env/my-angular-v18-env.bit-env.ts b/angular/examples/my-angular-v18-env/my-angular-v18-env.bit-env.ts index 9d4ff624..6cbaa230 100644 --- a/angular/examples/my-angular-v18-env/my-angular-v18-env.bit-env.ts +++ b/angular/examples/my-angular-v18-env/my-angular-v18-env.bit-env.ts @@ -1,141 +1,26 @@ -import { - NgMultiCompiler, - NgMultiCompilerTask -} from '@bitdev/angular.dev-services.compiler.multi-compiler'; -import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; import { AngularV18Env } from '@bitdev/angular.envs.angular-v18-env'; -import { Pipeline } from '@teambit/builder'; -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'; -import { EnvHandler } from '@teambit/envs'; -import { Linter } from '@teambit/linter'; -import { Preview } from '@teambit/preview'; -import { Tester } from '@teambit/tester'; -import { TypescriptConfigWriter } from '@teambit/typescript.typescript-compiler'; -import { ConfigWriterList } from '@teambit/workspace-config-files'; -import { ESLint as ESLintLib } from 'eslint'; import { createRequire } from 'node:module'; -import hostDependencies from './preview/host-dependencies.js'; -let ngMultiCompiler: EnvHandler | undefined; - -const require = createRequire(import.meta.url); +const req = createRequire(import.meta.url); export class MyAngularV18Env extends AngularV18Env { - // Name of the environment, used for friendly mentions across bit + /* Name of the environment, used for friendly mentions across bit */ name = 'my-angular-v18-env'; - getTesterConfig() { - return { - jest: require.resolve('jest'), - config: require.resolve('./config/jest.config.cjs') - }; - } - - /** - * Returns a tester to use during development - * Required for `bit start` & `bit test` - */ - override tester(): EnvHandler { - /** - * @see https://bit.dev/reference/jest/using-jest - * */ - return JestTester.from(this.getTesterConfig()); - } - - getLinterConfig() { - return { - tsconfig: require.resolve('./config/tsconfig.json'), - eslint: ESLintLib, - configPath: require.resolve('./config/eslintrc.cjs'), - // resolve all plugins from the angular environment. - pluginsPath: import.meta.dirname, - extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs'] - }; - } - - /** - * 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. - * bit will write the minimum required files in any workspace to optimize - * for dev experience. - */ - override linter(): EnvHandler { - return ESLintLinter.from(this.getLinterConfig()); - } + /* Typescript config used for linter, schema extractor and config writer */ + protected tsconfigPath = req.resolve('./config/tsconfig.json'); - /** - * The formatter to use during development - * (source files are not formatted as part of the components' build) - * */ - override formatter() { - /** - * @see https://bit.dev/reference/prettier/using-prettier - * */ - return PrettierFormatter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }); - } + /* ESLint config. Learn how to replace linter - https://bit.dev/reference/linting/set-up-linter */ + protected eslintConfigPath = req.resolve('./config/eslintrc.cjs'); - /** - * Generates the component previews during development and build - */ - override preview(): EnvHandler { - const tsConfig = require.resolve('./config/tsconfig.json'); - return AngularPreview.from({ - ngEnvOptions: this.getNgEnvOptions(), - hostDependencies, - mounterPath: require.resolve('./preview/mounter.js'), - angularServeOptions: { tsConfig }, - angularBuildOptions: { tsConfig }, - }); - } + /* Prettier config. Learn how to replace formatter - https://bit.dev/reference/formatting/set-up-formatter */ + protected prettierConfigPath = req.resolve('./config/prettier.config.cjs'); - /** - * Defines the build pipeline for a component. - * Pipelines are optimized for performance and consistency, making sure every component is - * independently built and tested. - * This is a set of processes to be performed before a component is snapped, during its build phase - * @see https://bit.dev/docs/angular-env/build-pipelines - */ - override build(): Pipeline { - return Pipeline.from([ - NgMultiCompilerTask.from({ ngMultiCompiler: this.compiler() }), - EslintTask.from(this.getLinterConfig()), - JestTask.from(this.getTesterConfig()) - ]); - } + /* Component mounting and dev-server config. Learn how to replace dev-server - https://bit.dev/reference/preview/setup-preview */ + protected previewMounterPath = req.resolve('./config/mounter.js'); - override workspaceConfig(): ConfigWriterList { - return ConfigWriterList.from([ - TypescriptConfigWriter.from({ - tsconfig: require.resolve('./config/tsconfig.json') - }), - EslintConfigWriter.from({ - configPath: require.resolve('./config/eslintrc.cjs'), - tsconfig: require.resolve('./config/tsconfig.json') - }), - PrettierConfigWriter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }) - ]); - } + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = req.resolve('./config/jest.config.cjs'); } export default new MyAngularV18Env(); diff --git a/angular/examples/my-angular-v18-env/my-angular-v18-env.docs.mdx b/angular/examples/my-angular-v18-env/my-angular-v18-env.docs.mdx index 09f8d70d..ee3728ae 100644 --- a/angular/examples/my-angular-v18-env/my-angular-v18-env.docs.mdx +++ b/angular/examples/my-angular-v18-env/my-angular-v18-env.docs.mdx @@ -61,8 +61,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/examples/my-angular-v18-env/preview/host-dependencies.ts b/angular/examples/my-angular-v18-env/preview/host-dependencies.ts deleted file mode 100644 index 6f6a9bb7..00000000 --- a/angular/examples/my-angular-v18-env/preview/host-dependencies.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Dependencies to be bundled only once, in the env preview template, and not in each component preview. - * most of your peer dependencies should be listed here to avoid duplications in the preview. - * React, ReactDOM, and MDX are included as they are part of the preview ui. - */ -export default [ - '@teambit/mdx.ui.mdx-scope-context', - '@mdx-js/react', - 'react', - 'react-dom', -]; diff --git a/angular/examples/my-angular-v19-env/component.json b/angular/examples/my-angular-v19-env/component.json index 8534df31..c9cce2af 100644 --- a/angular/examples/my-angular-v19-env/component.json +++ b/angular/examples/my-angular-v19-env/component.json @@ -2,7 +2,7 @@ "componentId": { "scope": "bitdev.angular", "name": "examples/my-angular-v19-env", - "version": "1.1.0" + "version": "2.0.1" }, "propagate": false, "extensions": { @@ -18,7 +18,9 @@ } } }, - "bitdev.general/envs/bit-env@1.0.1": {}, - "teambit.envs/envs": {} + "bitdev.general/envs/bit-env@1.0.21": {}, + "teambit.envs/envs": { + "env": "bitdev.general/envs/bit-env" + } } } diff --git a/angular/examples/my-angular-v19-env/config/mounter.ts b/angular/examples/my-angular-v19-env/config/mounter.ts new file mode 100644 index 00000000..1420a724 --- /dev/null +++ b/angular/examples/my-angular-v19-env/config/mounter.ts @@ -0,0 +1,27 @@ +/* eslint-disable import/no-unresolved */ +import { createMounter } from '@bitdev/angular.dev-services.preview.mounter'; +import { Component, ViewEncapsulation } from '@angular/core'; + +/** + * Provide your component compositions (preview) with the context they need to run. + * for example, a router, a theme, a data provider, etc. + * components added here as providers should be listed as host-dependencies + * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers + */ +@Component({ + selector: 'bit-wrapper', + standalone: true, + imports: [], + encapsulation: ViewEncapsulation.None, + template: ` + + `, +}) export class WrapperComponent {} + + +/** + * the entry for the app (preview runtime) that renders your component previews. + * use the default template or create your own. + * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers + */ +export default createMounter(WrapperComponent); diff --git a/angular/examples/my-angular-v19-env/env.jsonc b/angular/examples/my-angular-v19-env/env.jsonc index d345a517..7fdba035 100644 --- a/angular/examples/my-angular-v19-env/env.jsonc +++ b/angular/examples/my-angular-v19-env/env.jsonc @@ -18,13 +18,6 @@ * as a direct component dependencies. they are used for component development only. **/ "dev": [ - { - "name": "@types/jest", - "version": "^29.5.0", - "supportedRange": "^29.0.0", - "hidden": true, - "force": true - }, { "name": "@types/node", "version": "^20.11.22", @@ -84,7 +77,7 @@ { "name": "@angular/platform-browser", "version": "^19.0.0", - "supportedRange": "19.0.0" + "supportedRange": "^19.0.0" }, { "name": "@angular/platform-browser-dynamic", @@ -111,6 +104,11 @@ "version": "^8.40.0", "supportedRange": "^8.40.0" }, + { + "name": "@types/jest", + "version": "^29.5.0", + "supportedRange": "^29.0.0" + }, { "name": "express", "version": "~4.21.1", diff --git a/angular/examples/my-angular-v19-env/index.ts b/angular/examples/my-angular-v19-env/index.ts index 6b283234..c54f01e8 100644 --- a/angular/examples/my-angular-v19-env/index.ts +++ b/angular/examples/my-angular-v19-env/index.ts @@ -1,3 +1 @@ export { MyAngularV19Env, MyAngularV19Env as default } from './my-angular-v19-env.bit-env.js'; -// @ts-ignore -export { default as jestConfig } from './config/jest.config.cjs'; diff --git a/angular/examples/my-angular-v19-env/my-angular-v19-env.bit-env.ts b/angular/examples/my-angular-v19-env/my-angular-v19-env.bit-env.ts index 10b1ebab..9cb48c94 100644 --- a/angular/examples/my-angular-v19-env/my-angular-v19-env.bit-env.ts +++ b/angular/examples/my-angular-v19-env/my-angular-v19-env.bit-env.ts @@ -1,141 +1,26 @@ -import { - NgMultiCompiler, - NgMultiCompilerTask -} from '@bitdev/angular.dev-services.compiler.multi-compiler'; -import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; import { AngularV19Env } from '@bitdev/angular.envs.angular-v19-env'; -import { Pipeline } from '@teambit/builder'; -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'; -import { EnvHandler } from '@teambit/envs'; -import { Linter } from '@teambit/linter'; -import { Preview } from '@teambit/preview'; -import { Tester } from '@teambit/tester'; -import { TypescriptConfigWriter } from '@teambit/typescript.typescript-compiler'; -import { ConfigWriterList } from '@teambit/workspace-config-files'; -import { ESLint as ESLintLib } from 'eslint'; import { createRequire } from 'node:module'; -import hostDependencies from './preview/host-dependencies.js'; -let ngMultiCompiler: EnvHandler | undefined; - -const require = createRequire(import.meta.url); +const req = createRequire(import.meta.url); export class MyAngularV19Env extends AngularV19Env { - // Name of the environment, used for friendly mentions across bit + /* Name of the environment, used for friendly mentions across bit */ name = 'my-angular-v19-env'; - getTesterConfig() { - return { - jest: require.resolve('jest'), - config: require.resolve('./config/jest.config.cjs') - }; - } - - /** - * Returns a tester to use during development - * Required for `bit start` & `bit test` - */ - override tester(): EnvHandler { - /** - * @see https://bit.dev/reference/jest/using-jest - * */ - return JestTester.from(this.getTesterConfig()); - } - - getLinterConfig() { - return { - tsconfig: require.resolve('./config/tsconfig.json'), - eslint: ESLintLib, - configPath: require.resolve('./config/eslintrc.cjs'), - // resolve all plugins from the angular environment. - pluginsPath: import.meta.dirname, - extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs'] - }; - } - - /** - * 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. - * bit will write the minimum required files in any workspace to optimize - * for dev experience. - */ - override linter(): EnvHandler { - return ESLintLinter.from(this.getLinterConfig()); - } + /* Typescript config used for linter, schema extractor and config writer */ + protected tsconfigPath = req.resolve('./config/tsconfig.json'); - /** - * The formatter to use during development - * (source files are not formatted as part of the components' build) - * */ - override formatter() { - /** - * @see https://bit.dev/reference/prettier/using-prettier - * */ - return PrettierFormatter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }); - } + /* ESLint config. Learn how to replace linter - https://bit.dev/reference/linting/set-up-linter */ + protected eslintConfigPath = req.resolve('./config/eslintrc.cjs'); - /** - * Generates the component previews during development and build - */ - override preview(): EnvHandler { - const tsConfig = require.resolve('./config/tsconfig.json'); - return AngularPreview.from({ - ngEnvOptions: this.getNgEnvOptions(), - hostDependencies, - mounterPath: require.resolve('./preview/mounter.js'), - angularServeOptions: { tsConfig }, - angularBuildOptions: { tsConfig }, - }); - } + /* Prettier config. Learn how to replace formatter - https://bit.dev/reference/formatting/set-up-formatter */ + protected prettierConfigPath = req.resolve('./config/prettier.config.cjs'); - /** - * Defines the build pipeline for a component. - * Pipelines are optimized for performance and consistency, making sure every component is - * independently built and tested. - * This is a set of processes to be performed before a component is snapped, during its build phase - * @see https://bit.dev/docs/angular-env/build-pipelines - */ - override build(): Pipeline { - return Pipeline.from([ - NgMultiCompilerTask.from({ ngMultiCompiler: this.compiler() }), - EslintTask.from(this.getLinterConfig()), - JestTask.from(this.getTesterConfig()) - ]); - } + /* Component mounting and dev-server config. Learn how to replace dev-server - https://bit.dev/reference/preview/setup-preview */ + protected previewMounterPath = req.resolve('./config/mounter.js'); - override workspaceConfig(): ConfigWriterList { - return ConfigWriterList.from([ - TypescriptConfigWriter.from({ - tsconfig: require.resolve('./config/tsconfig.json') - }), - EslintConfigWriter.from({ - configPath: require.resolve('./config/eslintrc.cjs'), - tsconfig: require.resolve('./config/tsconfig.json') - }), - PrettierConfigWriter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }) - ]); - } + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = req.resolve('./config/jest.config.cjs'); } export default new MyAngularV19Env(); diff --git a/angular/examples/my-angular-v19-env/my-angular-v19-env.docs.mdx b/angular/examples/my-angular-v19-env/my-angular-v19-env.docs.mdx index d7f68af8..12cbd864 100644 --- a/angular/examples/my-angular-v19-env/my-angular-v19-env.docs.mdx +++ b/angular/examples/my-angular-v19-env/my-angular-v19-env.docs.mdx @@ -61,8 +61,7 @@ import { EnvOverview } from '@teambit/envs.docs.env-overview-template'; name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts' ], }, { diff --git a/angular/examples/my-angular-v19-env/preview/host-dependencies.ts b/angular/examples/my-angular-v19-env/preview/host-dependencies.ts deleted file mode 100644 index 6f6a9bb7..00000000 --- a/angular/examples/my-angular-v19-env/preview/host-dependencies.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Dependencies to be bundled only once, in the env preview template, and not in each component preview. - * most of your peer dependencies should be listed here to avoid duplications in the preview. - * React, ReactDOM, and MDX are included as they are part of the preview ui. - */ -export default [ - '@teambit/mdx.ui.mdx-scope-context', - '@mdx-js/react', - 'react', - 'react-dom', -]; diff --git a/angular/examples/my-angular-v19-env/preview/mounter.ts b/angular/examples/my-angular-v19-env/preview/mounter.ts deleted file mode 100644 index 6831d115..00000000 --- a/angular/examples/my-angular-v19-env/preview/mounter.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* eslint-disable import/no-unresolved */ -import { createMounter } from '@bitdev/angular.dev-services.preview.mounter'; -import { Component, ViewEncapsulation } from '@angular/core'; - -/** - * Provide your component compositions (preview) with the context they need to run. - * for example, a router, a theme, a data provider, etc. - * components added here as providers should be listed as host-dependencies in your host-dependencies.ts file. - * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers - */ -@Component({ - selector: 'bit-wrapper', - standalone: true, - imports: [], - encapsulation: ViewEncapsulation.None, - template: ` - - `, -}) export class WrapperComponent {} - - -/** - * the entry for the app (preview runtime) that renders your component previews. - * use the default template or create your own. - * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers - */ -export default createMounter(WrapperComponent); diff --git a/angular/integration/demo-app/demo-app.bit-app.ts b/angular/integration/demo-app/demo-app.bit-app.ts index e3b19a79..c9942c01 100644 --- a/angular/integration/demo-app/demo-app.bit-app.ts +++ b/angular/integration/demo-app/demo-app.bit-app.ts @@ -1,6 +1,5 @@ import { type AngularAppOptions, AngularApp } from '@bitdev/angular.app-types.angular-app-type'; import type { ApplicationOptions, DevServerOptions } from '@bitdev/angular.dev-services.common'; -import { ngEnvOptions } from '@bitdev/angular.angular-env'; const angularOptions: ApplicationOptions & DevServerOptions = { browser: './src/main.ts', @@ -10,7 +9,6 @@ const angularOptions: ApplicationOptions & DevServerOptions = { assets: ['./src/favicon.ico', './src/assets'], styles: ['./src/styles.scss'], inlineStyleLanguage: "scss", - prerender: true, outputMode: "server", ssr: { "entry": "./src/server.ts" @@ -36,12 +34,7 @@ export const DemoAppOptions: AngularAppOptions = { /** * Angular options for `bit run` */ - angularServeOptions: angularOptions, - - /** - * Env-specific options depending on the version of Angular used. - */ - ngEnvOptions + angularServeOptions: angularOptions }; export default AngularApp.from(DemoAppOptions); diff --git a/angular/integration/demo-app/src/app/app.config.ts b/angular/integration/demo-app/src/app/app.config.ts index a9af5184..64ab414a 100644 --- a/angular/integration/demo-app/src/app/app.config.ts +++ b/angular/integration/demo-app/src/app/app.config.ts @@ -1,8 +1,7 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; - -import { routes } from './app.routes'; import { provideClientHydration, withEventReplay } from '@angular/platform-browser'; +import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideClientHydration(withEventReplay())] diff --git a/angular/integration/demo-app/src/main.ts b/angular/integration/demo-app/src/main.ts index 272abdb0..28b8e271 100644 --- a/angular/integration/demo-app/src/main.ts +++ b/angular/integration/demo-app/src/main.ts @@ -17,4 +17,6 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { AppComponent } from './app/app.component'; import { appConfig } from './app/app.config'; -bootstrapApplication(AppComponent, appConfig); +bootstrapApplication(AppComponent, appConfig) + .catch((err) => console.error(err)); + diff --git a/angular/integration/demo-app/src/server.ts b/angular/integration/demo-app/src/server.ts index bbeed293..bb9fee8c 100644 --- a/angular/integration/demo-app/src/server.ts +++ b/angular/integration/demo-app/src/server.ts @@ -5,8 +5,8 @@ import { writeResponseToNodeResponse, } from '@angular/ssr/node'; import express from 'express'; -import { dirname, resolve } from 'node:path'; -import { fileURLToPath } from 'node:url'; +import { dirname, resolve } from 'path'; +import { fileURLToPath } from 'url'; const serverDistFolder = dirname(fileURLToPath(import.meta.url)); const browserDistFolder = resolve(serverDistFolder, '../browser'); @@ -40,7 +40,7 @@ app.use( /** * Handle all other requests by rendering the Angular application. */ -app.use('/**', (req, res, next) => { +app.use('/**', (req: any, res: any, next: any) => { angularApp .handle(req) .then((response) => { @@ -55,6 +55,7 @@ app.use('/**', (req, res, next) => { * The server listens on the port defined by the `PORT` environment variable, or defaults to 4000. */ if (isMainModule(import.meta.url)) { + // @ts-ignore const port = process.env['PORT'] || 4000; app.listen(port, () => { console.log(`Node Express server listening on http://localhost:${port}`); diff --git a/angular/integration/demo-app/tsconfig.app.json b/angular/integration/demo-app/tsconfig.app.json index 8b83f686..10acbb99 100644 --- a/angular/integration/demo-app/tsconfig.app.json +++ b/angular/integration/demo-app/tsconfig.app.json @@ -4,6 +4,7 @@ "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, + "baseUrl": "./", "declaration": false, "downlevelIteration": true, "esModuleInterop": true, diff --git a/angular/integration/demo-lib-v16/src/bit-test.component.ts b/angular/integration/demo-lib-v16/bit-test.component.ts similarity index 100% rename from angular/integration/demo-lib-v16/src/bit-test.component.ts rename to angular/integration/demo-lib-v16/bit-test.component.ts diff --git a/angular/integration/demo-lib-v16/src/bit-test.docs.md b/angular/integration/demo-lib-v16/bit-test.docs.md similarity index 100% rename from angular/integration/demo-lib-v16/src/bit-test.docs.md rename to angular/integration/demo-lib-v16/bit-test.docs.md diff --git a/angular/integration/demo-lib-v16/src/bit-test.module.ts b/angular/integration/demo-lib-v16/bit-test.module.ts similarity index 100% rename from angular/integration/demo-lib-v16/src/bit-test.module.ts rename to angular/integration/demo-lib-v16/bit-test.module.ts diff --git a/angular/integration/demo-lib-v16/src/bit-test.service.ts b/angular/integration/demo-lib-v16/bit-test.service.ts similarity index 100% rename from angular/integration/demo-lib-v16/src/bit-test.service.ts rename to angular/integration/demo-lib-v16/bit-test.service.ts diff --git a/angular/integration/demo-lib-v16/src/bit-test.spec.ts b/angular/integration/demo-lib-v16/bit-test.spec.ts similarity index 100% rename from angular/integration/demo-lib-v16/src/bit-test.spec.ts rename to angular/integration/demo-lib-v16/bit-test.spec.ts diff --git a/angular/integration/demo-lib-v16/src/bit-test2.component.ts b/angular/integration/demo-lib-v16/bit-test2.component.ts similarity index 100% rename from angular/integration/demo-lib-v16/src/bit-test2.component.ts rename to angular/integration/demo-lib-v16/bit-test2.component.ts diff --git a/angular/integration/demo-lib-v16/src/compositions/bit-test.composition.ts b/angular/integration/demo-lib-v16/compositions/bit-test.composition.ts similarity index 100% rename from angular/integration/demo-lib-v16/src/compositions/bit-test.composition.ts rename to angular/integration/demo-lib-v16/compositions/bit-test.composition.ts diff --git a/angular/integration/demo-lib-v16/src/compositions/cmp1.composition.ts b/angular/integration/demo-lib-v16/compositions/cmp1.composition.ts similarity index 100% rename from angular/integration/demo-lib-v16/src/compositions/cmp1.composition.ts rename to angular/integration/demo-lib-v16/compositions/cmp1.composition.ts diff --git a/angular/integration/demo-lib-v16/public-api.ts b/angular/integration/demo-lib-v16/public-api.ts index b0c87230..d49b3a72 100644 --- a/angular/integration/demo-lib-v16/public-api.ts +++ b/angular/integration/demo-lib-v16/public-api.ts @@ -1,6 +1,6 @@ /** * Entry point for this Angular library, do not move or rename this file. */ -export * from './src/bit-test.component'; -export * from './src/bit-test2.component'; -export * from './src/bit-test.module'; +export * from './bit-test.component'; +export * from './bit-test2.component'; +export * from './bit-test.module'; diff --git a/angular/integration/demo-lib-v17/src/bit-test.component.scss b/angular/integration/demo-lib-v17/bit-test.component.scss similarity index 100% rename from angular/integration/demo-lib-v17/src/bit-test.component.scss rename to angular/integration/demo-lib-v17/bit-test.component.scss diff --git a/angular/integration/demo-lib-v17/src/bit-test.component.ts b/angular/integration/demo-lib-v17/bit-test.component.ts similarity index 100% rename from angular/integration/demo-lib-v17/src/bit-test.component.ts rename to angular/integration/demo-lib-v17/bit-test.component.ts diff --git a/angular/integration/demo-lib-v17/src/bit-test.docs.md b/angular/integration/demo-lib-v17/bit-test.docs.md similarity index 100% rename from angular/integration/demo-lib-v17/src/bit-test.docs.md rename to angular/integration/demo-lib-v17/bit-test.docs.md diff --git a/angular/integration/demo-lib-v17/src/bit-test.module.ts b/angular/integration/demo-lib-v17/bit-test.module.ts similarity index 100% rename from angular/integration/demo-lib-v17/src/bit-test.module.ts rename to angular/integration/demo-lib-v17/bit-test.module.ts diff --git a/angular/integration/demo-lib-v17/src/bit-test.service.ts b/angular/integration/demo-lib-v17/bit-test.service.ts similarity index 100% rename from angular/integration/demo-lib-v17/src/bit-test.service.ts rename to angular/integration/demo-lib-v17/bit-test.service.ts diff --git a/angular/integration/demo-lib-v17/src/bit-test.spec.ts b/angular/integration/demo-lib-v17/bit-test.spec.ts similarity index 100% rename from angular/integration/demo-lib-v17/src/bit-test.spec.ts rename to angular/integration/demo-lib-v17/bit-test.spec.ts diff --git a/angular/integration/demo-lib-v17/src/bit-test2.component.ts b/angular/integration/demo-lib-v17/bit-test2.component.ts similarity index 100% rename from angular/integration/demo-lib-v17/src/bit-test2.component.ts rename to angular/integration/demo-lib-v17/bit-test2.component.ts diff --git a/angular/integration/demo-lib-v17/src/compositions/bit-test.composition.ts b/angular/integration/demo-lib-v17/compositions/bit-test.composition.ts similarity index 100% rename from angular/integration/demo-lib-v17/src/compositions/bit-test.composition.ts rename to angular/integration/demo-lib-v17/compositions/bit-test.composition.ts diff --git a/angular/integration/demo-lib-v17/src/compositions/cmp1.composition.ts b/angular/integration/demo-lib-v17/compositions/cmp1.composition.ts similarity index 100% rename from angular/integration/demo-lib-v17/src/compositions/cmp1.composition.ts rename to angular/integration/demo-lib-v17/compositions/cmp1.composition.ts diff --git a/angular/integration/demo-lib-v17/public-api.ts b/angular/integration/demo-lib-v17/public-api.ts index b0c87230..d49b3a72 100644 --- a/angular/integration/demo-lib-v17/public-api.ts +++ b/angular/integration/demo-lib-v17/public-api.ts @@ -1,6 +1,6 @@ /** * Entry point for this Angular library, do not move or rename this file. */ -export * from './src/bit-test.component'; -export * from './src/bit-test2.component'; -export * from './src/bit-test.module'; +export * from './bit-test.component'; +export * from './bit-test2.component'; +export * from './bit-test.module'; diff --git a/angular/integration/demo-lib-v18/src/bit-test.component.scss b/angular/integration/demo-lib-v18/bit-test.component.scss similarity index 100% rename from angular/integration/demo-lib-v18/src/bit-test.component.scss rename to angular/integration/demo-lib-v18/bit-test.component.scss diff --git a/angular/integration/demo-lib-v18/src/bit-test.component.ts b/angular/integration/demo-lib-v18/bit-test.component.ts similarity index 65% rename from angular/integration/demo-lib-v18/src/bit-test.component.ts rename to angular/integration/demo-lib-v18/bit-test.component.ts index 36185b96..452d2dd4 100644 --- a/angular/integration/demo-lib-v18/src/bit-test.component.ts +++ b/angular/integration/demo-lib-v18/bit-test.component.ts @@ -1,4 +1,4 @@ -import { Component } from "@angular/core"; +import { Component, Inject } from "@angular/core"; import { BitTestService } from './bit-test.service'; @Component({ @@ -9,5 +9,5 @@ import { BitTestService } from './bit-test.service'; ` }) export class BitTestComponent { - constructor(public service: BitTestService) {} + constructor(@Inject(BitTestService) public service: BitTestService) {} } diff --git a/angular/integration/demo-lib-v18/src/bit-test.module.ts b/angular/integration/demo-lib-v18/bit-test.module.ts similarity index 100% rename from angular/integration/demo-lib-v18/src/bit-test.module.ts rename to angular/integration/demo-lib-v18/bit-test.module.ts diff --git a/angular/integration/demo-lib-v18/src/bit-test.service.ts b/angular/integration/demo-lib-v18/bit-test.service.ts similarity index 100% rename from angular/integration/demo-lib-v18/src/bit-test.service.ts rename to angular/integration/demo-lib-v18/bit-test.service.ts diff --git a/angular/integration/demo-lib-v18/src/bit-test.spec.ts b/angular/integration/demo-lib-v18/bit-test.spec.ts similarity index 100% rename from angular/integration/demo-lib-v18/src/bit-test.spec.ts rename to angular/integration/demo-lib-v18/bit-test.spec.ts diff --git a/angular/integration/demo-lib-v18/src/bit-test2.component.ts b/angular/integration/demo-lib-v18/bit-test2.component.ts similarity index 100% rename from angular/integration/demo-lib-v18/src/bit-test2.component.ts rename to angular/integration/demo-lib-v18/bit-test2.component.ts diff --git a/angular/integration/demo-lib-v18/src/compositions/bit-test.composition.ts b/angular/integration/demo-lib-v18/compositions/bit-test.composition.ts similarity index 100% rename from angular/integration/demo-lib-v18/src/compositions/bit-test.composition.ts rename to angular/integration/demo-lib-v18/compositions/bit-test.composition.ts diff --git a/angular/integration/demo-lib-v18/src/compositions/cmp1.composition.ts b/angular/integration/demo-lib-v18/compositions/cmp1.composition.ts similarity index 100% rename from angular/integration/demo-lib-v18/src/compositions/cmp1.composition.ts rename to angular/integration/demo-lib-v18/compositions/cmp1.composition.ts diff --git a/angular/integration/demo-lib-v18/src/bit-test.docs.md b/angular/integration/demo-lib-v18/demo-lib-v18.docs.md similarity index 100% rename from angular/integration/demo-lib-v18/src/bit-test.docs.md rename to angular/integration/demo-lib-v18/demo-lib-v18.docs.md diff --git a/angular/integration/demo-lib-v18/public-api.ts b/angular/integration/demo-lib-v18/public-api.ts index b0c87230..d49b3a72 100644 --- a/angular/integration/demo-lib-v18/public-api.ts +++ b/angular/integration/demo-lib-v18/public-api.ts @@ -1,6 +1,6 @@ /** * Entry point for this Angular library, do not move or rename this file. */ -export * from './src/bit-test.component'; -export * from './src/bit-test2.component'; -export * from './src/bit-test.module'; +export * from './bit-test.component'; +export * from './bit-test2.component'; +export * from './bit-test.module'; diff --git a/angular/integration/demo-lib-v19/src/bit-test.component.scss b/angular/integration/demo-lib-v19/bit-test.component.scss similarity index 100% rename from angular/integration/demo-lib-v19/src/bit-test.component.scss rename to angular/integration/demo-lib-v19/bit-test.component.scss diff --git a/angular/integration/demo-lib-v19/src/bit-test.component.ts b/angular/integration/demo-lib-v19/bit-test.component.ts similarity index 100% rename from angular/integration/demo-lib-v19/src/bit-test.component.ts rename to angular/integration/demo-lib-v19/bit-test.component.ts diff --git a/angular/integration/demo-lib-v19/src/bit-test.docs.md b/angular/integration/demo-lib-v19/bit-test.docs.md similarity index 100% rename from angular/integration/demo-lib-v19/src/bit-test.docs.md rename to angular/integration/demo-lib-v19/bit-test.docs.md diff --git a/angular/integration/demo-lib-v19/src/bit-test.module.ts b/angular/integration/demo-lib-v19/bit-test.module.ts similarity index 100% rename from angular/integration/demo-lib-v19/src/bit-test.module.ts rename to angular/integration/demo-lib-v19/bit-test.module.ts diff --git a/angular/integration/demo-lib-v19/src/bit-test.service.ts b/angular/integration/demo-lib-v19/bit-test.service.ts similarity index 100% rename from angular/integration/demo-lib-v19/src/bit-test.service.ts rename to angular/integration/demo-lib-v19/bit-test.service.ts diff --git a/angular/integration/demo-lib-v19/src/bit-test.spec.ts b/angular/integration/demo-lib-v19/bit-test.spec.ts similarity index 100% rename from angular/integration/demo-lib-v19/src/bit-test.spec.ts rename to angular/integration/demo-lib-v19/bit-test.spec.ts diff --git a/angular/integration/demo-lib-v19/src/bit-test2.component.ts b/angular/integration/demo-lib-v19/bit-test2.component.ts similarity index 100% rename from angular/integration/demo-lib-v19/src/bit-test2.component.ts rename to angular/integration/demo-lib-v19/bit-test2.component.ts diff --git a/angular/integration/demo-lib-v19/src/bit-test3.component.ts b/angular/integration/demo-lib-v19/bit-test3.component.ts similarity index 100% rename from angular/integration/demo-lib-v19/src/bit-test3.component.ts rename to angular/integration/demo-lib-v19/bit-test3.component.ts diff --git a/angular/integration/demo-lib-v19/src/compositions/bit-test.composition.ts b/angular/integration/demo-lib-v19/compositions/bit-test.composition.ts similarity index 100% rename from angular/integration/demo-lib-v19/src/compositions/bit-test.composition.ts rename to angular/integration/demo-lib-v19/compositions/bit-test.composition.ts diff --git a/angular/integration/demo-lib-v19/src/compositions/cmp1.composition.ts b/angular/integration/demo-lib-v19/compositions/cmp1.composition.ts similarity index 100% rename from angular/integration/demo-lib-v19/src/compositions/cmp1.composition.ts rename to angular/integration/demo-lib-v19/compositions/cmp1.composition.ts diff --git a/angular/integration/demo-lib-v19/public-api.ts b/angular/integration/demo-lib-v19/public-api.ts index 08d067e3..baf0d610 100644 --- a/angular/integration/demo-lib-v19/public-api.ts +++ b/angular/integration/demo-lib-v19/public-api.ts @@ -1,7 +1,7 @@ /** * Entry point for this Angular library, do not move or rename this file. */ -export * from './src/bit-test.component'; -export * from './src/bit-test2.component'; -export * from './src/bit-test3.component'; -export * from './src/bit-test.module'; +export * from './bit-test.component'; +export * from './bit-test2.component'; +export * from './bit-test3.component'; +export * from './bit-test.module'; diff --git a/angular/templates/generators/ng-app/index.ts b/angular/templates/generators/ng-app/index.ts index 86527d0e..8cbf6fff 100644 --- a/angular/templates/generators/ng-app/index.ts +++ b/angular/templates/generators/ng-app/index.ts @@ -19,7 +19,6 @@ import { indexHtmlFile } from './template-files/src/index-html'; import { mainNgAppFile } from './template-files/src/main'; import { mainServerFile } from './template-files/src/main.server'; import { serverFile } from './template-files/src/server'; -import { polyfillsFile } from './template-files/src/polyfills'; import { helloApiFile } from './template-files/src/server/api/hello'; import { stylesFile } from './template-files/src/styles'; import { tsconfigFile } from './template-files/tsconfig.app'; @@ -59,17 +58,13 @@ export class NgAppTemplate implements ComponentTemplate { }) as Promise }; - if (this.angularVersion > 13) { - prompts.standalone = () => confirm({ - message: 'Do you want to use standalone components?' - }) as Promise; - } + prompts.standalone = () => confirm({ + message: 'Do you want to use standalone components?' + }) as Promise; - if (this.angularVersion >= 16) { - prompts.ssr = () => confirm({ - message: 'Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)?' - }) as Promise; - } + prompts.ssr = () => confirm({ + message: 'Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)?' + }) as Promise; const params = await group(prompts); @@ -81,7 +76,7 @@ export class NgAppTemplate implements ComponentTemplate { async generateFiles(context: ComponentContext) { let params: { [id: string]: any } = { styleSheet: 'scss', - standalone: this.angularVersion > 13, + standalone: true, ssr: this.angularVersion >= 17 }; @@ -114,13 +109,12 @@ export class NgAppTemplate implements ComponentTemplate { ]; if (params.ssr) { - files.push( - mainServerFile(params.standalone), - helloApiFile() - ); + files.push(mainServerFile(params.standalone)); if (this.angularVersion >= 19) { files.push(serverFile()); + } else { + files.push(helloApiFile()); } if (params.standalone) { @@ -128,16 +122,8 @@ export class NgAppTemplate implements ComponentTemplate { } } - if (this.angularVersion < 15) { - files.push( - // starting from Angular 15, the `polyfills` option accept an array of module specifiers. - // https://github.com/angular/angular-cli/commit/597bfea1b29cc7b25d1f466eb313cbeeb6dffc98 - polyfillsFile() - ); - } - if (params.standalone) { - files.push(appConfigFile(this.angularVersion, params.ssr)); + files.push(appConfigFile(params.ssr)); } if (!params.standalone) { files.push(appModuleFile(params.ssr)); diff --git a/angular/templates/generators/ng-app/template-files/src/app/app.config.ts b/angular/templates/generators/ng-app/template-files/src/app/app.config.ts index ba4bfa05..c5ac560b 100644 --- a/angular/templates/generators/ng-app/template-files/src/app/app.config.ts +++ b/angular/templates/generators/ng-app/template-files/src/app/app.config.ts @@ -1,13 +1,12 @@ import { ComponentFile } from '@teambit/generator'; -export const appConfigFile = (angularVersion: number, ssr: boolean): ComponentFile => { +export const appConfigFile = (ssr: boolean): ComponentFile => { return { relativePath: `src/app/app.config.ts`, - content: `import { ApplicationConfig } from '${angularVersion >= 16 ? '@angular/core' : '@angular/platform-browser'}'; -import { provideRouter } from '@angular/router'; - -import { routes } from './app.routes';${ssr ? ` + content: `import { ApplicationConfig } from '@angular/core'; +import { provideRouter } from '@angular/router';${ssr ? ` import { provideClientHydration } from '@angular/platform-browser';` : ''} +import { routes } from './app.routes'; export const appConfig: ApplicationConfig = { providers: [provideRouter(routes)${ssr ? ', provideClientHydration()' : ''}] diff --git a/angular/templates/generators/ng-app/template-files/src/server.ts b/angular/templates/generators/ng-app/template-files/src/server.ts index 5b2e7b02..a0e74b35 100644 --- a/angular/templates/generators/ng-app/template-files/src/server.ts +++ b/angular/templates/generators/ng-app/template-files/src/server.ts @@ -2,7 +2,7 @@ import { ComponentFile } from '@teambit/generator'; export const serverFile = (): ComponentFile => { return { - relativePath: `src/main.server.ts`, + relativePath: `src/server.ts`, content: `import { AngularNodeAppEngine, createNodeRequestHandler, diff --git a/angular/templates/generators/ng-env/files/config/mounter.ts b/angular/templates/generators/ng-env/files/config/mounter.ts new file mode 100644 index 00000000..ec28eba7 --- /dev/null +++ b/angular/templates/generators/ng-env/files/config/mounter.ts @@ -0,0 +1,33 @@ +export const mounterFile = () => { + return { + relativePath: './config/mounter.ts', + content: `/* eslint-disable import/no-unresolved */ +import { createMounter } from '@bitdev/angular.dev-services.preview.mounter'; +import { Component, ViewEncapsulation } from '@angular/core'; + +/** + * Provide your component compositions (preview) with the context they need to run. + * for example, a router, a theme, a data provider, etc. + * components added here as providers should be listed as host-dependencies + * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers + */ +@Component({ + selector: 'bit-wrapper', + standalone: true, + imports: [], + encapsulation: ViewEncapsulation.None, + template: \` + + \`, +}) export class WrapperComponent {} + + +/** + * the entry for the app (preview runtime) that renders your component previews. + * use the default template or create your own. + * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers + */ +export default createMounter(WrapperComponent); +`, + }; +}; diff --git a/angular/templates/generators/ng-env/files/doc.ts b/angular/templates/generators/ng-env/files/doc.ts index 20f25748..060c4916 100644 --- a/angular/templates/generators/ng-env/files/doc.ts +++ b/angular/templates/generators/ng-env/files/doc.ts @@ -63,8 +63,7 @@ tools={{ name: 'Component Preview', toolLink: 'https://bit.cloud/bitdev/angular/dev-services/preview/mounter', configFiles: [ - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/mounter.ts', - 'https://bit.cloud/bitdev/angular/envs/base-env/~code/preview/host-dependencies.ts', + 'https://bit.cloud/bitdev/angular/envs/base-env/~code/config/mounter.ts', ], }, { diff --git a/angular/templates/generators/ng-env/files/env.ts b/angular/templates/generators/ng-env/files/env.ts index ac79c7b3..855bea4b 100644 --- a/angular/templates/generators/ng-env/files/env.ts +++ b/angular/templates/generators/ng-env/files/env.ts @@ -2,141 +2,29 @@ import { ComponentContext } from '@teambit/generator'; export function envFile({ namePascalCase: Name, name }: ComponentContext, envName: string, angularVersion: number, envPkgName: string) { // language=TypeScript - return `import { NgMultiCompiler, NgMultiCompilerTask } from '@bitdev/angular.dev-services.compiler.multi-compiler'; -import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview'; -import { Pipeline } from '@teambit/builder'; -import { ${envName} } from '${envPkgName}'; -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'; -import { EnvHandler } from '@teambit/envs'; -import { Linter } from '@teambit/linter'; -import { Preview } from '@teambit/preview'; -import { Tester } from '@teambit/tester'; -import { TypescriptConfigWriter } from '@teambit/typescript.typescript-compiler'; -import { ConfigWriterList } from '@teambit/workspace-config-files'; -import { ESLint as ESLintLib } from 'eslint'; + return `import { ${envName} } from '${envPkgName}'; import { createRequire } from 'node:module'; -import hostDependencies from './preview/host-dependencies.js'; -let ngMultiCompiler: EnvHandler | undefined; - -const require = createRequire(import.meta.url); +const req = createRequire(import.meta.url); export class ${Name} extends ${envName} { - // Name of the environment, used for friendly mentions across bit + /* Name of the environment, used for friendly mentions across bit */ name = '${name}'; - getTesterConfig() { - return { - jest: require.resolve('jest'), - config: require.resolve('./config/jest.config.cjs') - }; - } - - /** - * Returns a tester to use during development - * Required for \`bit start\` & \`bit test\` - */ - override tester(): EnvHandler { - /** - * @see https://bit.dev/reference/jest/using-jest - * */ - return JestTester.from(this.getTesterConfig()); - } - - getLinterConfig() { - return { - tsconfig: require.resolve('@bitdev/angular.dev-services.linter.eslint/config/tsconfig.json'), - eslint: ESLintLib, - configPath: require.resolve('./config/eslintrc.cjs'), - // resolve all plugins from the angular environment. - pluginsPath: import.meta.dirname, - extensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs'] - }; - } - - /** - * 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. - * bit will write the minimum required files in any workspace to optimize - * for dev experience. - */ - override linter(): EnvHandler { - return ESLintLinter.from(this.getLinterConfig()); - } + /* Typescript config used for linter, schema extractor and config writer */ + protected tsconfigPath = req.resolve('./config/tsconfig.json'); - /** - * The formatter to use during development - * (source files are not formatted as part of the components' build) - * */ - override formatter() { - /** - * @see https://bit.dev/reference/prettier/using-prettier - * */ - return PrettierFormatter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }); - } + /* ESLint config. Learn how to replace linter - https://bit.dev/reference/linting/set-up-linter */ + protected eslintConfigPath = req.resolve('./config/eslintrc.cjs'); - /** - * Generates the component previews during development and build. - */ - override preview(): EnvHandler { - const tsConfig = require.resolve('./config/tsconfig.json'); - return AngularPreview.from({ - ngEnvOptions: this.getNgEnvOptions(), - hostDependencies, - mounterPath: require.resolve('./preview/mounter.js'), - angularServeOptions: { tsConfig }, - angularBuildOptions: { tsConfig }, - }); - } + /* Prettier config. Learn how to replace formatter - https://bit.dev/reference/formatting/set-up-formatter */ + protected prettierConfigPath = req.resolve('./config/prettier.config.cjs'); - /** - * Defines the build pipeline for a component. - * Pipelines are optimized for performance and consistency, making sure every component is - * independently built and tested. - * This is a set of processes to be performed before a component is snapped, during its build phase - * @see https://bit.dev/docs/angular-env/build-pipelines - */ - override build() { - return Pipeline.from([ - NgMultiCompilerTask.from({ ngMultiCompiler: this.compiler() }), - EslintTask.from(this.getLinterConfig()), - JestTask.from(this.getTesterConfig()) - ]); - } + /* Component mounting and dev-server config. Learn how to replace dev-server - https://bit.dev/reference/preview/setup-preview */ + protected previewMounterPath = req.resolve('./config/mounter.js'); - override workspaceConfig(): ConfigWriterList { - return ConfigWriterList.from([ - TypescriptConfigWriter.from({ - tsconfig: require.resolve('./config/tsconfig.json') - }), - EslintConfigWriter.from({ - configPath: require.resolve('./config/eslintrc.cjs'), - tsconfig: require.resolve('./config/tsconfig.json') - }), - PrettierConfigWriter.from({ - configPath: require.resolve('./config/prettier.config.cjs') - }) - ]); - } + /* Jest config. Learn how to replace tester - https://bit.dev/reference/testing/set-up-tester */ + protected jestConfigPath = req.resolve('./config/jest.config.cjs'); } export default new ${Name}(); diff --git a/angular/templates/generators/ng-env/files/preview/host-dependencies.ts b/angular/templates/generators/ng-env/files/preview/host-dependencies.ts deleted file mode 100644 index bc1b1575..00000000 --- a/angular/templates/generators/ng-env/files/preview/host-dependencies.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const hostDependenciesFile = () => { - return { - relativePath: './preview/host-dependencies.ts', - content: `/** - * Dependencies to be bundled only once, in the env preview template, and not in each component preview. - * most of your peer dependencies should be listed here to avoid duplications in the preview. - * React, ReactDOM, and MDX are included as they are part of the preview ui. - */ -export default [ - '@teambit/mdx.ui.mdx-scope-context', - '@mdx-js/react', - 'react', - 'react-dom', -];`, - }; -}; diff --git a/angular/templates/generators/ng-env/files/preview/mounter.ts b/angular/templates/generators/ng-env/files/preview/mounter.ts deleted file mode 100644 index f5af14e9..00000000 --- a/angular/templates/generators/ng-env/files/preview/mounter.ts +++ /dev/null @@ -1,68 +0,0 @@ -export const mounterFile = (angularVersion: number) => { - return { - relativePath: './preview/mounter.ts', - content: angularVersion <= 13 ? `/* eslint-disable import/no-unresolved */ -import { createMounter } from '@bitdev/angular.dev-services.preview.mounter'; -import { Component, NgModule, ViewEncapsulation } from '@angular/core'; - -/** - * Provide your component compositions (preview) with the context they need to run. - * for example, a router, a theme, a data provider, etc. - * components added here as providers should be listed as host-dependencies in your host-dependencies.ts file. - * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers - */ -@Component({ - selector: 'bit-wrapper', - encapsulation: ViewEncapsulation.ShadowDom, - template: \` -
- \`, -}) export class WrapperComponent { -} - -@NgModule({ - declarations: [WrapperComponent], - imports: [], - exports: [WrapperComponent], - bootstrap: [WrapperComponent], -}) export class WrapperModule { -} - - -/** - * the entry for the app (preview runtime) that renders your component previews. - * use the default template or create your own. - * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers - */ -export default createMounter(WrapperModule, {wrapperSelector: '#wrapper-host'});` -// Angular v14+ -: `/* eslint-disable import/no-unresolved */ -import { createMounter } from '@bitdev/angular.dev-services.preview.mounter'; -import { Component, ViewEncapsulation } from '@angular/core'; - -/** - * Provide your component compositions (preview) with the context they need to run. - * for example, a router, a theme, a data provider, etc. - * components added here as providers should be listed as host-dependencies in your host-dependencies.ts file. - * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers - */ -@Component({ - selector: 'bit-wrapper', - standalone: true, - imports: [], - encapsulation: ViewEncapsulation.None, - template: \` - - \`, -}) export class WrapperComponent {} - - -/** - * the entry for the app (preview runtime) that renders your component previews. - * use the default template or create your own. - * @see https://bit.dev/docs/angular-env-env/components-preview#compositions-providers - */ -export default createMounter(WrapperComponent); -`, - }; -}; diff --git a/angular/templates/generators/ng-env/index.ts b/angular/templates/generators/ng-env/index.ts index f20613b1..de20672a 100644 --- a/angular/templates/generators/ng-env/index.ts +++ b/angular/templates/generators/ng-env/index.ts @@ -13,8 +13,7 @@ import { docFile } from './files/doc'; import { envFile } from './files/env'; import { envJsoncFile } from './files/env-jsonc'; import { indexFile } from './files/index'; -import { hostDependenciesFile } from './files/preview/host-dependencies'; -import { mounterFile } from './files/preview/mounter'; +import { mounterFile } from './files/config/mounter'; export class NgEnvTemplate implements ComponentTemplate { installMissingDependencies = true; @@ -66,8 +65,7 @@ export class NgEnvTemplate implements ComponentTemplate { prettierConfigFile(), tsConfigFile(), tsConfigSpecFile(), - mounterFile(this.angularVersion), - hostDependenciesFile() + mounterFile() ]; } diff --git a/angular/templates/generators/ng-module/files/component-spec.ts b/angular/templates/generators/ng-module/files/component-spec.ts index 76b192d6..d18f3bce 100644 --- a/angular/templates/generators/ng-module/files/component-spec.ts +++ b/angular/templates/generators/ng-module/files/component-spec.ts @@ -6,7 +6,6 @@ export const componentSpecFile = (context: ComponentContext): ComponentFile => { return { relativePath: `${name}.spec.ts`, content: `import { ComponentFixture, TestBed } from '@angular/core/testing'; - import { ${Name}Component } from './${name}.component'; import { ${Name}Module } from './${name}.module'; diff --git a/angular/templates/generators/ng-module/files/composition.ts b/angular/templates/generators/ng-module/files/composition.ts index c27aea3b..30e5978a 100644 --- a/angular/templates/generators/ng-module/files/composition.ts +++ b/angular/templates/generators/ng-module/files/composition.ts @@ -1,27 +1,11 @@ import { ComponentContext, ComponentFile } from '@teambit/generator'; -export const compositionFile = (context: ComponentContext, angularVersion: number): ComponentFile => { +export const compositionFile = (context: ComponentContext): ComponentFile => { const { name, namePascalCase: Name } = context; - const moduleComposition = `import { Component, NgModule } from '@angular/core'; -import { ${Name}Module } from './${name}.module'; - -@Component({ - selector: '${name}-composition-cmp', - standalone: false, - template: \`${Name} composition: <${name}>\` -}) -class ${Name}CompositionComponent {} - -@NgModule({ - declarations: [${Name}CompositionComponent], - imports: [${Name}Module], - bootstrap: [${Name}CompositionComponent] -}) -export class ${Name}CompositionModule {} -`; - - const standaloneComposition = `import { Component } from '@angular/core'; + return { + relativePath: `${name}.composition.ts`, + content: `import { Component } from '@angular/core'; import { ${Name}Module } from './${name}.module'; @Component({ @@ -30,11 +14,6 @@ import { ${Name}Module } from './${name}.module'; imports: [${Name}Module], template: \`${Name} composition: <${name}>\` }) -export class ${Name}CompositionComponent {} -`; - - return { - relativePath: `${name}.composition.ts`, - content: angularVersion >= 14 ? standaloneComposition : moduleComposition, +export class ${Name}CompositionComponent {}`, }; }; diff --git a/angular/templates/generators/ng-module/index.ts b/angular/templates/generators/ng-module/index.ts index 37fda9ec..b5b5f3db 100644 --- a/angular/templates/generators/ng-module/index.ts +++ b/angular/templates/generators/ng-module/index.ts @@ -24,7 +24,7 @@ export class NgModuleTemplate implements ComponentTemplate { moduleFile(context), docsFile(context), componentSpecFile(context), - compositionFile(context, this.angularVersion), + compositionFile(context), ]; } diff --git a/angular/templates/generators/ng-standalone/files/component-spec.ts b/angular/templates/generators/ng-standalone/files/component-spec.ts index 27ba4eb9..ded11ef6 100644 --- a/angular/templates/generators/ng-standalone/files/component-spec.ts +++ b/angular/templates/generators/ng-standalone/files/component-spec.ts @@ -6,7 +6,6 @@ export const componentSpecFile = (context: ComponentContext): ComponentFile => { return { relativePath: `${name}.spec.ts`, content: `import { ComponentFixture, TestBed } from '@angular/core/testing'; - import { ${Name}Component } from './${name}.component'; describe('${Name}Component', () => { diff --git a/bit-angular.zip b/bit-angular.zip new file mode 100644 index 00000000..bd49300f Binary files /dev/null and b/bit-angular.zip differ diff --git a/workspace.jsonc b/workspace.jsonc index f4b4d597..d8e4f23f 100644 --- a/workspace.jsonc +++ b/workspace.jsonc @@ -29,38 +29,46 @@ * main configuration for component dependency resolution. **/ "teambit.dependencies/dependency-resolver": { - /** - * choose the package manager for Bit to use. you can choose between 'yarn', 'pnpm' - */ - "packageManager": "teambit.dependencies/pnpm", "policy": { "dependencies": { "@clack/prompts": "^0.7.0", + "@markdoc/markdoc": "^0.4.0", "@teambit/community.ui.bit-cli.command-example": "0.0.8", "@teambit/community.ui.bit-cli.terminal": "0.0.30", "@teambit/community.ui.file-explorer": "1.1.9", + "@teambit/compilation.compiler-task": "1.0.9", + "@teambit/component.sources": "^0.0.53", "@teambit/components.blocks.component-card-display": "0.0.36", - "@teambit/defender.eslint-linter": "1.0.39", - "@teambit/defender.jest-tester": "2.0.14", - "@teambit/defender.prettier-formatter": "1.0.19", + "@teambit/defender.eslint-linter": "1.0.43", + "@teambit/defender.jest-tester": "2.0.16", + "@teambit/defender.prettier-formatter": "1.0.20", "@teambit/docs.entities.docs-routes": "1.95.17", "@teambit/envs.docs.create-env": "1.0.10", - "@teambit/envs.docs.env-overview-template": "0.0.3", + "@teambit/envs.docs.env-overview-template": "0.0.5", "@teambit/envs.docs.envs-build-pipeline": "1.0.8", "@teambit/envs.docs.envs-component-generators": "1.0.8", "@teambit/envs.docs.envs-dependency-policy": "1.0.8", "@teambit/envs.docs.envs-workspace-starters": "0.1.8", - "@teambit/graph.cleargraph": "0.0.9", - "@teambit/harmony.content.cli-reference": "2.0.285", + "@teambit/graph.cleargraph": "0.0.11", + "@teambit/harmony.content.cli-reference": "2.0.492", + "@teambit/legacy.constants": "^0.0.1", + "@teambit/legacy.utils": "^0.0.8", + "@teambit/preview.modules.preview-modules": "^1.0.3", "@teambit/react.ui.docs-app": "1.0.21", - "@teambit/typescript.typescript-compiler": "2.0.44", - "@teambit/webpack.modules.generate-style-loaders": "^1.0.11", - "@teambit/webpack.modules.style-regexps": "^1.0.6", + "@teambit/scope.modules.find-scope-path": "^0.0.2", + "@teambit/toolbox.time.timer": "^0.0.1", + "@teambit/typescript.typescript-compiler": "2.0.46", + "@teambit/vite.vite-utils": "^0.1.14", + "@teambit/webpack.modules.generate-style-loaders": "^1.0.12", + "@teambit/webpack.modules.style-regexps": "^1.0.7", + "@teambit/webpack.webpack-bundler": "1.0.13", "@teambit/workspace.root-components": "^1.0.0", "@types/fs-extra": "~9.0.7", "@types/lodash-es": "^4.17.12", "@types/node": "20.12.7", "@types/object-hash": "~2.1.0", + "@types/prismjs": "^1.26.4", + "esbuild-plugins-node-modules-polyfill": "^1.6.7", "events": "^3.3.0", "fs-extra": "^11.2.0", "json5": "^2.2.3", @@ -69,6 +77,7 @@ "postcss-flexbugs-fixes": "^5.0.2", "postcss-preset-env": "^10.1.0", "prettier": "2.3.2", + "prismjs": "^1.29.0", "react-dev-utils": "10.2.1", "react-dev-utils-esm": "^11.0.3", "remark-frontmatter": "~3.0.0", @@ -80,6 +89,10 @@ "peerDependencies": {} }, "linkCoreAspects": true, + /** + * choose the package manager for Bit to use. you can choose between 'yarn', 'pnpm' + */ + "packageManager": "teambit.dependencies/pnpm", "rootComponents": true, "packageImportMethod": "copy", "packageManagerArgs": [], @@ -92,14 +105,14 @@ }, "teambit.generator/generator": { "envs": [ -// "bitdev.angular/angular-env", + // "bitdev.angular/angular-env", "bitdev.angular/envs/angular-v19-env" // "bitdev.angular/envs/angular-v18-env" // "bitdev.angular/envs/angular-v17-env" // "bitdev.angular/envs/angular-v16-env", ] }, -// "bitdev.angular/angular-env": {}, + // "bitdev.angular/angular-env": {}, "bitdev.angular/envs/angular-v19-env": {}, // "bitdev.angular/envs/angular-v18-env": {}, // "bitdev.angular/envs/angular-v17-env": {},