diff --git a/scopes/harmony/aspect/aspect.env.ts b/scopes/harmony/aspect/aspect.env.ts index c657598929c8..2f5c15432ccc 100644 --- a/scopes/harmony/aspect/aspect.env.ts +++ b/scopes/harmony/aspect/aspect.env.ts @@ -1,10 +1,20 @@ -import { Compiler } from '@teambit/compiler'; -import type { DependenciesEnv, PackageEnv, PreviewEnv } from '@teambit/envs'; +import { JestTask, jestWorkerPath } from '@teambit/defender.jest-tester'; +import type { JestWorker } from '@teambit/defender.jest-tester'; +import { pathNormalizeToLinux } from '@teambit/toolbox.path.path'; +import { BabelCompiler } from '@teambit/compilation.babel-compiler'; +import { Compiler, CompilerMain } from '@teambit/compiler'; +import type { + DependenciesEnv, + PackageEnv, + PipeServiceModifier, + PipeServiceModifiersMap, + PreviewEnv, +} from '@teambit/envs'; import { merge } from 'lodash'; import { PackageJsonProps } from '@teambit/pkg'; import { TsConfigSourceFile } from 'typescript'; import { ReactEnv } from '@teambit/react'; -import { CAPSULE_ARTIFACTS_DIR } from '@teambit/builder'; +import { BuildTask, CAPSULE_ARTIFACTS_DIR } from '@teambit/builder'; import type { AspectLoaderMain } from '@teambit/aspect-loader'; import { Bundler, BundlerContext } from '@teambit/bundler'; import { WebpackConfigTransformer } from '@teambit/webpack'; @@ -15,16 +25,36 @@ import { PrettierConfigWriter } from '@teambit/defender.prettier-formatter'; import { TypescriptConfigWriter } from '@teambit/typescript.typescript-compiler'; import { EslintConfigWriter } from '@teambit/defender.eslint-linter'; import { Logger } from '@teambit/logger'; +import { join } from 'path'; +import { WorkerMain } from '@teambit/worker'; + +import { DevFilesMain } from '@teambit/dev-files'; +import { TsConfigTransformer } from '@teambit/typescript'; +import { TesterTask } from '@teambit/defender.tester-task'; + +import { babelConfig } from './babel/babel-config'; const tsconfig = require('./typescript/tsconfig.json'); export const AspectEnvType = 'aspect'; +type GetBuildPipeModifiers = PipeServiceModifiersMap & { + tsModifier?: PipeServiceModifier; + jestModifier?: PipeServiceModifier; +}; + /** * a component environment built for Aspects . */ export class AspectEnv implements DependenciesEnv, PackageEnv, PreviewEnv { - constructor(private reactEnv: ReactEnv, private aspectLoader: AspectLoaderMain, private logger: Logger) {} + constructor( + private reactEnv: ReactEnv, + private aspectLoader: AspectLoaderMain, + private devFiles: DevFilesMain, + private compiler: CompilerMain, + private worker: WorkerMain, + private logger: Logger + ) {} icon = 'https://static.bit.dev/extensions-icons/default.svg'; @@ -45,12 +75,65 @@ export class AspectEnv implements DependenciesEnv, PackageEnv, PreviewEnv { return this.reactEnv.getTsCjsCompiler(this.getTsConfig(tsConfig)); } + getCompiler(): Compiler { + return this.getBabelCompiler(); + } + + private getBabelCompiler() { + const options = { + babelTransformOptions: babelConfig, + distDir: 'dist', + distGlobPatterns: [`dist/**`, `!dist/**/*.d.ts`, `!dist/tsconfig.tsbuildinfo`], + }; + + const babelCompiler = BabelCompiler.create(options, { logger: this.logger }); + return babelCompiler; + } + /** * returns a component tester. */ getTester(jestConfigPath: string, jestModulePath?: string): Tester { const config = jestConfigPath || require.resolve('./jest/jest.config'); - return this.reactEnv.getCjsJestTester(config, jestModulePath); + return this.reactEnv.createCjsJestTester(config, jestModulePath); + } + + /** + * returns the component build pipeline. + */ + getBuildPipe(modifiers: GetBuildPipeModifiers = {}): BuildTask[] { + const transformer = (tsConfigMutator) => { + tsConfigMutator + .mergeTsConfig(tsconfig) + .setArtifactName('declaration') + .setDistGlobPatterns([`dist/**/*.d.ts`]) + .setShouldCopyNonSupportedFiles(false); + return tsConfigMutator; + }; + // @ts-ignore + const externalTransformer: TsConfigTransformer[] = modifiers?.tsModifier?.transformers || []; + const tsCompilerTask = this.reactEnv.getCjsCompilerTask([transformer, ...externalTransformer]); + const babelCompiler = this.getBabelCompiler(); + const babelCompilerTask = this.compiler.createTask('BabelCompiler', babelCompiler); + const jestTesterTask = this.getJestTesterTask(); + + return [babelCompilerTask, tsCompilerTask, jestTesterTask]; + } + + private getJestTesterTask(jestModifier: PipeServiceModifier = {}): TesterTask { + const pathToSource = pathNormalizeToLinux(__dirname).replace('/dist', ''); + const jestConfigPath = jestModifier?.transformers?.[0]() || join(pathToSource, './jest/jest.config.js'); + const jestPath = jestModifier?.module || require.resolve('jest'); + const worker = this.getJestWorker(); + const testerTask = JestTask.create( + { config: jestConfigPath, jest: jestPath }, + { logger: this.logger, worker, devFiles: this.devFiles } + ); + return testerTask; + } + + private getJestWorker() { + return this.worker.declareWorker('jest', jestWorkerPath); } async getTemplateBundler(context: BundlerContext, transformers: WebpackConfigTransformer[] = []): Promise { diff --git a/scopes/harmony/aspect/aspect.main.runtime.ts b/scopes/harmony/aspect/aspect.main.runtime.ts index 5e91cc1ca3ae..6cfd4ace647a 100644 --- a/scopes/harmony/aspect/aspect.main.runtime.ts +++ b/scopes/harmony/aspect/aspect.main.runtime.ts @@ -1,6 +1,5 @@ import { Harmony } from '@teambit/harmony'; import { AspectLoaderAspect, AspectLoaderMain } from '@teambit/aspect-loader'; -import { BabelCompiler } from '@teambit/compilation.babel-compiler'; import { LoggerAspect, LoggerMain } from '@teambit/logger'; import { BuilderAspect, BuilderMain } from '@teambit/builder'; import { compact, merge } from 'lodash'; @@ -8,7 +7,7 @@ import { EnvPolicyConfigObject } from '@teambit/dependency-resolver'; import { BitError } from '@teambit/bit-error'; import { CLIAspect, CLIMain, MainRuntime } from '@teambit/cli'; import { EnvContext, Environment, EnvsAspect, EnvsMain, EnvTransformer } from '@teambit/envs'; -import { ReactAspect, ReactMain } from '@teambit/react'; +import { ReactAspect, ReactEnv, ReactMain } from '@teambit/react'; import { GeneratorAspect, GeneratorMain } from '@teambit/generator'; import { ComponentID } from '@teambit/component-id'; import { AspectList } from '@teambit/component'; @@ -29,11 +28,10 @@ import { UpdateAspectCmd, } from './aspect.cmd'; import { getTemplates } from './aspect.templates'; +import { DevFilesAspect, DevFilesMain } from '@teambit/dev-files'; export type AspectSource = { aspectName: string; source: string; level: string }; -const tsconfig = require('./typescript/tsconfig.json'); - export class AspectMain { constructor(readonly aspectEnv: AspectEnv, private envs: EnvsMain, private workspace: Workspace) {} @@ -216,10 +214,11 @@ export class AspectMain { CLIAspect, LoggerAspect, WorkerAspect, + DevFilesAspect, ]; static async provider( - [react, envs, builder, aspectLoader, compiler, generator, workspace, cli, loggerMain, workerMain]: [ + [react, envs, builder, aspectLoader, compiler, generator, workspace, cli, loggerMain, workerMain, devFilesMain]: [ ReactMain, EnvsMain, BuilderMain, @@ -229,7 +228,8 @@ export class AspectMain { Workspace, CLIMain, LoggerMain, - WorkerMain + WorkerMain, + DevFilesMain ], config, slots, @@ -237,38 +237,9 @@ export class AspectMain { ) { const logger = loggerMain.createLogger(AspectAspect.id); - const options = { - babelTransformOptions: babelConfig, - distDir: 'dist', - distGlobPatterns: [`dist/**`, `!dist/**/*.d.ts`, `!dist/tsconfig.tsbuildinfo`], - }; - - const babelCompiler = BabelCompiler.create(options, { logger }); - - const compilerOverride = envs.override({ - getCompiler: () => { - return babelCompiler; - }, - }); - - const transformer = (tsConfigMutator) => { - tsConfigMutator - .mergeTsConfig(tsconfig) - .setArtifactName('declaration') - .setDistGlobPatterns([`dist/**/*.d.ts`]) - .setShouldCopyNonSupportedFiles(false); - return tsConfigMutator; - }; - const tsCompiler = react.env.getCjsCompilerTask([transformer]); - - const compilerTasksOverride = react.overrideCompilerTasks([ - compiler.createTask('BabelCompiler', babelCompiler), - tsCompiler, - ]); - - const aspectEnv = react.compose( - [compilerOverride, compilerTasksOverride], - new AspectEnv(react.reactEnv, aspectLoader, logger) + const aspectEnv = envs.merge( + new AspectEnv(react.reactEnv, aspectLoader, devFilesMain, compiler, workerMain, logger), + react.reactEnv ); const coreExporterTask = new CoreExporterTask(aspectEnv, aspectLoader); diff --git a/scopes/harmony/node/node.env.ts b/scopes/harmony/node/node.env.ts index 9d297333c135..ae9573914148 100644 --- a/scopes/harmony/node/node.env.ts +++ b/scopes/harmony/node/node.env.ts @@ -1,3 +1,4 @@ +import { pathNormalizeToLinux } from '@teambit/toolbox.path.path'; import { DependenciesEnv, PackageEnv, PipeServiceModifier, PipeServiceModifiersMap } from '@teambit/envs'; import { VariantPolicyConfigObject } from '@teambit/dependency-resolver'; import { TsConfigTransformer, TypescriptMain } from '@teambit/typescript'; @@ -7,11 +8,13 @@ import { BuildTask } from '@teambit/builder'; import { COMPONENT_PREVIEW_STRATEGY_NAME, PreviewStrategyName } from '@teambit/preview'; import { SchemaExtractor } from '@teambit/schema'; import { TsConfigSourceFile } from 'typescript'; +import { join } from 'path'; export const NodeEnvType = 'node'; type GetBuildPipeModifiers = PipeServiceModifiersMap & { tsModifier?: PipeServiceModifier; + jestModifier?: PipeServiceModifier; }; export class NodeEnv implements DependenciesEnv, PackageEnv { constructor(protected tsAspect: TypescriptMain, protected reactAspect: ReactMain) {} @@ -37,12 +40,11 @@ export class NodeEnv implements DependenciesEnv, PackageEnv { * returns the component build pipeline. */ getBuildPipe(modifiers: GetBuildPipeModifiers = {}): BuildTask[] { - const tsTransformers: TsConfigTransformer[] = - (modifiers?.tsModifier?.transformers as any as TsConfigTransformer[]) || []; - const compilerTask = this.reactAspect.reactEnv.getCjsCompilerTask(tsTransformers, modifiers?.tsModifier?.module); - - const pipeWithoutCompiler = this.reactAspect.reactEnv.getBuildPipeWithoutCompiler(); - return [compilerTask, ...pipeWithoutCompiler]; + const pathToSource = pathNormalizeToLinux(__dirname).replace('/dist', ''); + const jestConfigPath = modifiers?.jestModifier?.transformers?.[0]() || join(pathToSource, './jest/jest.config.js'); + modifiers.jestModifier = modifiers.jestModifier || {}; + modifiers.jestModifier.transformers = [() => jestConfigPath]; + return this.reactAspect.reactEnv.getBuildPipe(modifiers); } /** diff --git a/workspace.jsonc b/workspace.jsonc index 5e95ad96ce55..24a37b8faf22 100644 --- a/workspace.jsonc +++ b/workspace.jsonc @@ -151,6 +151,7 @@ "@teambit/defender.eslint-linter": "^1.0.35", "@teambit/defender.jest-tester": "^2.0.4", "@teambit/defender.prettier-formatter": "1.0.12", + "@teambit/defender.tester-task": "^1.0.12", "@teambit/defender.ui.test-compare-section": "^0.0.100", "@teambit/defender.ui.test-loader": "^0.0.504", "@teambit/defender.ui.test-row": "^0.0.503",