diff --git a/e2e/js/src/js-ts-solution.test.ts b/e2e/js/src/js-ts-solution.test.ts new file mode 100644 index 0000000000000..156a402072afe --- /dev/null +++ b/e2e/js/src/js-ts-solution.test.ts @@ -0,0 +1,183 @@ +import { + cleanupProject, + getPackageManagerCommand, + getSelectedPackageManager, + newProject, + runCLI, + runCommand, + uniq, + updateFile, + updateJson, +} from '@nx/e2e/utils'; + +describe('JS - TS solution setup', () => { + beforeAll(() => { + newProject({ + packages: ['@nx/js'], + preset: 'ts', + }); + }); + + afterAll(() => { + cleanupProject(); + }); + + it('should generate libraries with different bundlers and link them successfully', () => { + const esbuildParentLib = uniq('esbuild-parent-lib'); + const esbuildChildLib = uniq('esbuild-child-lib'); + const rollupParentLib = uniq('rollup-parent-lib'); + const rollupChildLib = uniq('rollup-child-lib'); + const swcParentLib = uniq('swc-parent-lib'); + const swcChildLib = uniq('swc-child-lib'); + const tscParentLib = uniq('tsc-parent-lib'); + const tscChildLib = uniq('tsc-child-lib'); + const viteParentLib = uniq('vite-parent-lib'); + const viteChildLib = uniq('vite-child-lib'); + + runCLI( + `generate @nx/js:lib packages/${esbuildParentLib} --bundler=esbuild --linter=eslint --unitTestRunner=jest` + ); + runCLI( + `generate @nx/js:lib packages/${esbuildChildLib} --bundler=esbuild --linter=eslint --unitTestRunner=jest` + ); + runCLI( + `generate @nx/js:lib packages/${rollupParentLib} --bundler=rollup --linter=eslint --unitTestRunner=jest` + ); + runCLI( + `generate @nx/js:lib packages/${rollupChildLib} --bundler=rollup --linter=eslint --unitTestRunner=jest` + ); + runCLI( + `generate @nx/js:lib packages/${swcParentLib} --bundler=swc --linter=eslint --unitTestRunner=jest` + ); + runCLI( + `generate @nx/js:lib packages/${swcChildLib} --bundler=swc --linter=eslint --unitTestRunner=jest` + ); + runCLI( + `generate @nx/js:lib packages/${tscParentLib} --bundler=tsc --linter=eslint --unitTestRunner=jest` + ); + runCLI( + `generate @nx/js:lib packages/${tscChildLib} --bundler=tsc --linter=eslint --unitTestRunner=jest` + ); + runCLI( + `generate @nx/js:lib packages/${viteParentLib} --bundler=vite --linter=eslint --unitTestRunner=jest` + ); + runCLI( + `generate @nx/js:lib packages/${viteChildLib} --bundler=vite --linter=eslint --unitTestRunner=jest` + ); + + // add deps, each parent lib imports all child libs + const addImports = (parentLib: string) => { + updateFile( + `packages/${parentLib}/src/index.ts`, + (content) => `export * from '@proj/${esbuildChildLib}'; +export * from '@proj/${rollupChildLib}'; +export * from '@proj/${swcChildLib}'; +export * from '@proj/${tscChildLib}'; +export * from '@proj/${viteChildLib}'; +${content}` + ); + }; + + addImports(esbuildParentLib); + addImports(rollupParentLib); + addImports(swcParentLib); + addImports(tscParentLib); + addImports(viteParentLib); + + const pm = getSelectedPackageManager(); + if (pm === 'pnpm') { + // for pnpm we need to add the local packages as dependencies to each consumer package.json + const addDeps = (parentLib: string) => { + updateJson(`packages/${parentLib}/package.json`, (json) => { + json.dependencies ??= {}; + json.dependencies[`@proj/${esbuildChildLib}`] = 'workspace:*'; + json.dependencies[`@proj/${rollupChildLib}`] = 'workspace:*'; + json.dependencies[`@proj/${swcChildLib}`] = 'workspace:*'; + json.dependencies[`@proj/${tscChildLib}`] = 'workspace:*'; + json.dependencies[`@proj/${viteChildLib}`] = 'workspace:*'; + return json; + }); + }; + + addDeps(esbuildParentLib); + addDeps(rollupParentLib); + addDeps(swcParentLib); + addDeps(tscParentLib); + addDeps(viteParentLib); + + const pmc = getPackageManagerCommand({ packageManager: pm }); + runCommand(pmc.install); + } + + // sync to ensure the TS project references are updated + runCLI(`sync`); + + // check build + expect(runCLI(`build ${esbuildParentLib}`)).toContain( + `Successfully ran target build for project ${esbuildParentLib} and 5 tasks it depends on` + ); + expect(runCLI(`build ${rollupParentLib}`)).toContain( + `Successfully ran target build for project ${rollupParentLib} and 5 tasks it depends on` + ); + expect(runCLI(`build ${swcParentLib}`)).toContain( + `Successfully ran target build for project ${swcParentLib} and 5 tasks it depends on` + ); + expect(runCLI(`build ${tscParentLib}`)).toContain( + `Successfully ran target build for project ${tscParentLib} and 5 tasks it depends on` + ); + expect(runCLI(`build ${viteParentLib}`)).toContain( + `Successfully ran target build for project ${viteParentLib} and 5 tasks it depends on` + ); + + // check typecheck + expect(runCLI(`typecheck ${esbuildParentLib}`)).toContain( + `Successfully ran target typecheck for project ${esbuildParentLib} and 5 tasks it depends on` + ); + expect(runCLI(`typecheck ${rollupParentLib}`)).toContain( + `Successfully ran target typecheck for project ${rollupParentLib} and 5 tasks it depends on` + ); + expect(runCLI(`typecheck ${swcParentLib}`)).toContain( + `Successfully ran target typecheck for project ${swcParentLib} and 5 tasks it depends on` + ); + expect(runCLI(`typecheck ${tscParentLib}`)).toContain( + `Successfully ran target typecheck for project ${tscParentLib} and 5 tasks it depends on` + ); + expect(runCLI(`typecheck ${viteParentLib}`)).toContain( + `Successfully ran target typecheck for project ${viteParentLib} and 5 tasks it depends on` + ); + + // check lint + expect(runCLI(`lint ${esbuildParentLib}`)).toContain( + `Successfully ran target lint for project ${esbuildParentLib}` + ); + expect(runCLI(`lint ${rollupParentLib}`)).toContain( + `Successfully ran target lint for project ${rollupParentLib}` + ); + expect(runCLI(`lint ${swcParentLib}`)).toContain( + `Successfully ran target lint for project ${swcParentLib}` + ); + expect(runCLI(`lint ${tscParentLib}`)).toContain( + `Successfully ran target lint for project ${tscParentLib}` + ); + expect(runCLI(`lint ${viteParentLib}`)).toContain( + `Successfully ran target lint for project ${viteParentLib}` + ); + + // check test + expect(runCLI(`test ${esbuildParentLib}`)).toContain( + `Successfully ran target test for project ${esbuildParentLib}` + ); + expect(runCLI(`test ${rollupParentLib}`)).toContain( + `Successfully ran target test for project ${rollupParentLib}` + ); + expect(runCLI(`test ${swcParentLib}`)).toContain( + `Successfully ran target test for project ${swcParentLib}` + ); + expect(runCLI(`test ${tscParentLib}`)).toContain( + `Successfully ran target test for project ${tscParentLib}` + ); + expect(runCLI(`test ${viteParentLib}`)).toContain( + `Successfully ran target test for project ${viteParentLib}` + ); + }, 300_000); +}); diff --git a/e2e/vite/src/vite-ts-solution.test.ts b/e2e/vite/src/vite-ts-solution.test.ts new file mode 100644 index 0000000000000..9ed56e3aede6d --- /dev/null +++ b/e2e/vite/src/vite-ts-solution.test.ts @@ -0,0 +1,98 @@ +import { names } from '@nx/devkit'; +import { + cleanupProject, + getPackageManagerCommand, + getSelectedPackageManager, + newProject, + runCLI, + runCommand, + uniq, + updateFile, + updateJson, +} from '@nx/e2e/utils'; + +describe('Vite - TS solution setup', () => { + beforeAll(() => { + newProject({ + packages: ['@nx/react', '@nx/js'], + preset: 'ts', + }); + }); + + afterAll(() => { + cleanupProject(); + }); + + it('should generate app and consume libraries with different bundlers', () => { + const reactApp = uniq('react-app'); + const esbuildLib = uniq('esbuild-lib'); + const rollupLib = uniq('rollup-lib'); + const swcLib = uniq('swc-lib'); + const tscLib = uniq('tsc-lib'); + const viteLib = uniq('vite-lib'); + const noBundlerLib = uniq('no-bundler-lib'); + + runCLI(`generate @nx/react:app apps/${reactApp} --bundler=vite`); + runCLI(`generate @nx/js:lib packages/${esbuildLib} --bundler=esbuild`); + runCLI(`generate @nx/js:lib packages/${rollupLib} --bundler=rollup`); + runCLI(`generate @nx/js:lib packages/${swcLib} --bundler=swc`); + runCLI(`generate @nx/js:lib packages/${tscLib} --bundler=tsc`); + runCLI(`generate @nx/js:lib packages/${viteLib} --bundler=vite`); + runCLI(`generate @nx/js:lib packages/${noBundlerLib} --bundler=none`); + + // import all libs from the app + updateFile( + `apps/${reactApp}/src/app/app.tsx`, + (content) => `import { ${ + names(esbuildLib).propertyName + } } from '@proj/${esbuildLib}'; +import { ${names(rollupLib).propertyName} } from '@proj/${rollupLib}'; +import { ${names(swcLib).propertyName} } from '@proj/${swcLib}'; +import { ${names(tscLib).propertyName} } from '@proj/${tscLib}'; +import { ${names(viteLib).propertyName} } from '@proj/${viteLib}'; +import { ${names(noBundlerLib).propertyName} } from '@proj/${noBundlerLib}'; + +console.log( + ${names(esbuildLib).propertyName}(), + ${names(rollupLib).propertyName}(), + ${names(swcLib).propertyName}(), + ${names(tscLib).propertyName}(), + ${names(viteLib).propertyName}(), + ${names(noBundlerLib).propertyName}() +); + +${content}` + ); + + const pm = getSelectedPackageManager(); + if (pm === 'pnpm') { + // for pnpm we need to add the local packages as dependencies to each consumer package.json + updateJson(`apps/${reactApp}/package.json`, (json) => { + json.dependencies ??= {}; + json.dependencies[`@proj/${esbuildLib}`] = 'workspace:*'; + json.dependencies[`@proj/${rollupLib}`] = 'workspace:*'; + json.dependencies[`@proj/${swcLib}`] = 'workspace:*'; + json.dependencies[`@proj/${tscLib}`] = 'workspace:*'; + json.dependencies[`@proj/${viteLib}`] = 'workspace:*'; + json.dependencies[`@proj/${noBundlerLib}`] = 'workspace:*'; + return json; + }); + + const pmc = getPackageManagerCommand({ packageManager: pm }); + runCommand(pmc.install); + } + + // sync to ensure the TS project references are updated + runCLI(`sync`); + + // check build + expect(runCLI(`build ${reactApp}`)).toContain( + `Successfully ran target build for project ${reactApp} and 5 tasks it depends on` + ); + + // check typecheck + expect(runCLI(`typecheck ${reactApp}`)).toContain( + `Successfully ran target typecheck for project ${reactApp} and 6 tasks it depends on` + ); + }, 300_000); +}); diff --git a/packages/esbuild/src/executors/esbuild/esbuild.impl.ts b/packages/esbuild/src/executors/esbuild/esbuild.impl.ts index 83c6bed8ebb15..16c7f1f3f949e 100644 --- a/packages/esbuild/src/executors/esbuild/esbuild.impl.ts +++ b/packages/esbuild/src/executors/esbuild/esbuild.impl.ts @@ -134,8 +134,8 @@ export async function* esbuildExecutor( setup(build: esbuild.PluginBuild) { build.onEnd(async (result: esbuild.BuildResult) => { if ( - !options.skipTypeCheck && - !options.isTsSolutionSetup + !options.skipTypeCheck || + options.isTsSolutionSetup ) { const { errors } = await runTypeCheck( options, @@ -183,7 +183,7 @@ export async function* esbuildExecutor( ); } else { // Run type-checks first and bail if they don't pass. - if (!options.skipTypeCheck && !options.isTsSolutionSetup) { + if (!options.skipTypeCheck || options.isTsSolutionSetup) { const { errors } = await runTypeCheck(options, context); if (errors.length > 0) { yield { success: false }; @@ -245,6 +245,10 @@ function getTypeCheckOptions( typeCheckOptions.cacheDir = cacheDir; } + if (options.isTsSolutionSetup && options.skipTypeCheck) { + typeCheckOptions.ignoreDiagnostics = true; + } + return typeCheckOptions; } diff --git a/packages/js/src/executors/swc/swc.impl.ts b/packages/js/src/executors/swc/swc.impl.ts index 31b0c097e97bf..5a042bb74380b 100644 --- a/packages/js/src/executors/swc/swc.impl.ts +++ b/packages/js/src/executors/swc/swc.impl.ts @@ -56,9 +56,7 @@ function normalizeOptions( const outputPath = join(root, options.outputPath); - if (options.skipTypeCheck == null && !isTsSolutionSetup) { - options.skipTypeCheck = false; - } + options.skipTypeCheck ??= !isTsSolutionSetup; if (options.watch == null) { options.watch = false; diff --git a/packages/js/src/generators/library/files/lib/src/lib/__fileName__.spec.ts__tmpl__ b/packages/js/src/generators/library/files/lib/src/lib/__fileName__.spec.ts__tmpl__ index d410ff0297e64..038364176bb00 100644 --- a/packages/js/src/generators/library/files/lib/src/lib/__fileName__.spec.ts__tmpl__ +++ b/packages/js/src/generators/library/files/lib/src/lib/__fileName__.spec.ts__tmpl__ @@ -1,4 +1,4 @@ -import { <%= propertyName %> } from './<%= fileName %>'; +import { <%= propertyName %> } from './<%= fileNameImport %>'; describe('<%= propertyName %>', () => { it('should work', () => { diff --git a/packages/js/src/generators/library/library.spec.ts b/packages/js/src/generators/library/library.spec.ts index 86713cfc4c45e..cf902d66dd5cf 100644 --- a/packages/js/src/generators/library/library.spec.ts +++ b/packages/js/src/generators/library/library.spec.ts @@ -1439,7 +1439,7 @@ describe('lib', () => { { ignoredFiles: [ '{projectRoot}/eslint.config.{js,cjs,mjs}', - '{projectRoot}/rollup.config.{js,ts,mjs,mts}', + '{projectRoot}/rollup.config.{js,ts,mjs,mts,cjs,cts}', ], }, ], @@ -1671,5 +1671,130 @@ describe('lib', () => { } `); }); + + it('should set "type: module" in package.json for bundler=tsc', async () => { + await libraryGenerator(tree, { + ...defaultOptions, + directory: 'my-ts-lib', + bundler: 'tsc', + unitTestRunner: 'none', + linter: 'none', + }); + + expect(readJson(tree, 'my-ts-lib/package.json')).toMatchInlineSnapshot(` + { + "dependencies": { + "tslib": "^2.3.0", + }, + "main": "./dist/index.js", + "name": "@proj/my-ts-lib", + "private": true, + "type": "module", + "typings": "./dist/index.d.ts", + "version": "0.0.1", + } + `); + }); + + it('should set "type: module" in package.json for bundler=swc', async () => { + await libraryGenerator(tree, { + ...defaultOptions, + directory: 'my-ts-lib', + bundler: 'swc', + unitTestRunner: 'none', + linter: 'none', + }); + + expect(readJson(tree, 'my-ts-lib/package.json')).toMatchInlineSnapshot(` + { + "dependencies": { + "@swc/helpers": "~0.5.11", + }, + "main": "./dist/index.js", + "name": "@proj/my-ts-lib", + "private": true, + "type": "module", + "typings": "./dist/index.d.ts", + "version": "0.0.1", + } + `); + }); + + it('should set "type: es6" in .swcrc for bundler=swc', async () => { + await libraryGenerator(tree, { + ...defaultOptions, + directory: 'my-ts-lib', + bundler: 'swc', + unitTestRunner: 'none', + linter: 'none', + }); + + expect(tree.read('my-ts-lib/.swcrc', 'utf-8')).toMatchInlineSnapshot(` + "{ + "jsc": { + "target": "es2017", + "parser": { + "syntax": "typescript", + "decorators": true, + "dynamicImport": true + }, + "transform": { + "decoratorMetadata": true, + "legacyDecorator": true + }, + "keepClassNames": true, + "externalHelpers": true, + "loose": true + }, + "module": { + "type": "es6" + }, + "sourceMaps": true, + "exclude": [ + "jest.config.ts", + ".*\\\\.spec.tsx?$", + ".*\\\\.test.tsx?$", + "./src/jest-setup.ts$", + "./**/jest-setup.ts$", + ".*.js$" + ] + } + " + `); + }); + + it('should generate relative import paths with file extension for bundler=tsc', async () => { + await libraryGenerator(tree, { + ...defaultOptions, + directory: 'my-ts-lib', + bundler: 'tsc', + unitTestRunner: 'jest', + linter: 'none', + }); + + expect(tree.read('my-ts-lib/src/index.ts', 'utf-8')).toContain( + `export * from './lib/my-ts-lib.js';` + ); + expect( + tree.read('my-ts-lib/src/lib/my-ts-lib.spec.ts', 'utf-8') + ).toContain(`import { myTsLib } from './my-ts-lib.js';`); + }); + + it('should generate relative import paths with file extension for bundler=swc', async () => { + await libraryGenerator(tree, { + ...defaultOptions, + directory: 'my-ts-lib', + bundler: 'swc', + unitTestRunner: 'vitest', + linter: 'none', + }); + + expect(tree.read('my-ts-lib/src/index.ts', 'utf-8')).toContain( + `export * from './lib/my-ts-lib.js';` + ); + expect( + tree.read('my-ts-lib/src/lib/my-ts-lib.spec.ts', 'utf-8') + ).toContain(`import { myTsLib } from './my-ts-lib.js';`); + }); }); }); diff --git a/packages/js/src/generators/library/library.ts b/packages/js/src/generators/library/library.ts index aa48b57982ec9..b74fb86fe0cca 100644 --- a/packages/js/src/generators/library/library.ts +++ b/packages/js/src/generators/library/library.ts @@ -236,7 +236,7 @@ export async function libraryGeneratorInternal( // Always run install to link packages. if (options.isUsingTsSolutionConfig) { - tasks.push(() => installPackagesTask(tree)); + tasks.push(() => installPackagesTask(tree, true)); } tasks.push(() => { @@ -285,10 +285,6 @@ async function configureProject( }, }; - if (options.bundler === 'esbuild') { - projectConfiguration.targets.build.options.format = ['cjs']; - } - if ( options.bundler === 'swc' && (options.skipTypeCheck || options.isUsingTsSolutionConfig) @@ -298,6 +294,7 @@ async function configureProject( if (options.isUsingTsSolutionConfig) { if (options.bundler === 'esbuild') { + projectConfiguration.targets.build.options.format = ['esm']; projectConfiguration.targets.build.options.declarationRootDir = `${options.projectRoot}/src`; } else if (options.bundler === 'swc') { projectConfiguration.targets.build.options.stripLeadingPaths = true; @@ -306,6 +303,7 @@ async function configureProject( projectConfiguration.targets.build.options.assets = []; if (options.bundler === 'esbuild') { + projectConfiguration.targets.build.options.format = ['cjs']; projectConfiguration.targets.build.options.generatePackageJson = true; } @@ -468,7 +466,7 @@ export async function addLint( } else if (options.bundler === 'rollup') { ruleOptions.ignoredFiles ??= []; ruleOptions.ignoredFiles.push( - '{projectRoot}/rollup.config.{js,ts,mjs,mts}' + '{projectRoot}/rollup.config.{js,ts,mjs,mts,cjs,cts}' ); o.rules['@nx/dependency-checks'] = [ruleSeverity, ruleOptions]; } else if (options.bundler === 'esbuild') { @@ -503,7 +501,11 @@ function createFiles(tree: Tree, options: NormalizedLibraryGeneratorOptions) { createProjectTsConfigs(tree, options); let fileNameImport = options.fileName; - if (options.bundler === 'vite') { + if ( + options.bundler === 'vite' || + (options.isUsingTsSolutionConfig && + ['esbuild', 'swc', 'tsc'].includes(options.bundler)) + ) { const tsConfig = readTsConfigFromTree( tree, join(options.projectRoot, 'tsconfig.lib.json') @@ -563,7 +565,9 @@ function createFiles(tree: Tree, options: NormalizedLibraryGeneratorOptions) { addSwcConfig( tree, options.projectRoot, - options.bundler === 'swc' ? 'commonjs' : 'es6' + options.bundler === 'swc' && !options.isUsingTsSolutionConfig + ? 'commonjs' + : 'es6' ); } else if (options.includeBabelRc) { addBabelRc(tree, options); @@ -1091,7 +1095,7 @@ function determineEntryFields( switch (options.bundler) { case 'tsc': return { - type: 'commonjs', + type: options.isUsingTsSolutionConfig ? 'module' : 'commonjs', main: options.isUsingTsSolutionConfig ? './dist/index.js' : './src/index.js', @@ -1101,7 +1105,7 @@ function determineEntryFields( }; case 'swc': return { - type: 'commonjs', + type: options.isUsingTsSolutionConfig ? 'module' : 'commonjs', main: options.isUsingTsSolutionConfig ? './dist/index.js' : './src/index.js', @@ -1131,11 +1135,10 @@ function determineEntryFields( : './index.d.ts', }; case 'esbuild': - // For libraries intended for Node, use CJS. return { - type: 'commonjs', + type: options.isUsingTsSolutionConfig ? 'module' : 'commonjs', main: options.isUsingTsSolutionConfig - ? './dist/index.cjs' + ? './dist/index.js' : './index.cjs', typings: options.isUsingTsSolutionConfig ? './dist/index.d.ts' diff --git a/packages/js/src/generators/setup-build/generator.ts b/packages/js/src/generators/setup-build/generator.ts index 9e9eda516a9ba..a5c7515003b6c 100644 --- a/packages/js/src/generators/setup-build/generator.ts +++ b/packages/js/src/generators/setup-build/generator.ts @@ -131,7 +131,7 @@ export async function setupBuildGenerator( project: options.project, skipFormat: true, skipValidation: true, - format: ['cjs'], + format: isTsSolutionSetup ? ['esm'] : ['cjs'], }); tasks.push(task); break; @@ -204,7 +204,7 @@ export async function setupBuildGenerator( updateProjectConfiguration(tree, options.project, project); tasks.push(addSwcDependencies(tree)); - addSwcConfig(tree, project.root, 'commonjs'); + addSwcConfig(tree, project.root, isTsSolutionSetup ? 'es6' : 'commonjs'); if (isTsSolutionSetup) { updatePackageJsonForSwc(tree, options, project); } diff --git a/packages/js/src/plugins/typescript/plugin.spec.ts b/packages/js/src/plugins/typescript/plugin.spec.ts index 47dd7b9c745de..95e19243022a4 100644 --- a/packages/js/src/plugins/typescript/plugin.spec.ts +++ b/packages/js/src/plugins/typescript/plugin.spec.ts @@ -485,6 +485,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^typecheck", ], "inputs": [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/src/**/*.ts", "!{projectRoot}/src/**/foo.ts", @@ -552,6 +553,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^typecheck", ], "inputs": [ + "{projectRoot}/package.json", "{workspaceRoot}/tsconfig.foo.json", "{workspaceRoot}/tsconfig.base.json", "{projectRoot}/tsconfig.json", @@ -628,6 +630,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^typecheck", ], "inputs": [ + "{projectRoot}/package.json", "{workspaceRoot}/tsconfig.foo.json", "{workspaceRoot}/tsconfig.base.json", "{projectRoot}/tsconfig.json", @@ -719,6 +722,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^typecheck", ], "inputs": [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.spec.json", @@ -771,6 +775,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^typecheck", ], "inputs": [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/lib/**/*.ts", "^production", @@ -833,6 +838,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.typecheck.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.spec.json", @@ -869,6 +875,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.typecheck.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.spec.json", @@ -905,6 +912,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.typecheck.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.spec.json", @@ -941,6 +949,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.typecheck.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.spec.json", @@ -980,6 +989,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.typecheck.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.spec.json", @@ -1432,6 +1442,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^typecheck", ], "inputs": [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.spec.json", @@ -2208,6 +2219,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^build", ], "inputs": [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/src/**/*.ts", "!{projectRoot}/src/**/*.spec.ts", @@ -2283,6 +2295,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^build", ], "inputs": [ + "{projectRoot}/package.json", "{workspaceRoot}/tsconfig.foo.json", "{workspaceRoot}/tsconfig.base.json", "{projectRoot}/tsconfig.lib.json", @@ -2367,6 +2380,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^build", ], "inputs": [ + "{projectRoot}/package.json", "{workspaceRoot}/tsconfig.foo.json", "{workspaceRoot}/tsconfig.base.json", "{projectRoot}/tsconfig.lib.json", @@ -2448,6 +2462,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^build", ], "inputs": [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.other.json", "{projectRoot}/src/**/*.ts", @@ -2514,6 +2529,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.build.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.other.json", "{projectRoot}/src/**/*.ts", @@ -2549,6 +2565,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.build.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.other.json", "{projectRoot}/**/*.ts", @@ -2584,6 +2601,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.build.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.other.json", "{projectRoot}/src/**/*.ts", @@ -2619,6 +2637,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.build.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.other.json", "{projectRoot}/src/**/*.ts", @@ -2657,6 +2676,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { expect(result.projects['libs/my-lib'].targets.build.inputs) .toMatchInlineSnapshot(` [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.other.json", "{projectRoot}/src/**/*.ts", @@ -3012,6 +3032,7 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => { "^build", ], "inputs": [ + "{projectRoot}/package.json", "{projectRoot}/tsconfig.lib.json", "{projectRoot}/tsconfig.other.json", "{projectRoot}/other/**/*.ts", diff --git a/packages/js/src/plugins/typescript/plugin.ts b/packages/js/src/plugins/typescript/plugin.ts index 630dd17539cd8..83f7f40d1383d 100644 --- a/packages/js/src/plugins/typescript/plugin.ts +++ b/packages/js/src/plugins/typescript/plugin.ts @@ -436,6 +436,9 @@ function getInputs( const inputs: TargetConfiguration['inputs'] = []; if (includePaths.size) { + if (existsSync(join(workspaceRoot, projectRoot, 'package.json'))) { + inputs.push('{projectRoot}/package.json'); + } inputs.push( ...Array.from(configFiles).map((p: string) => pathToInputOrOutput(p, workspaceRoot, projectRoot) diff --git a/packages/js/src/utils/swc/compile-swc.ts b/packages/js/src/utils/swc/compile-swc.ts index 6fbc07b0e3ab5..e8c83cb48b443 100644 --- a/packages/js/src/utils/swc/compile-swc.ts +++ b/packages/js/src/utils/swc/compile-swc.ts @@ -68,6 +68,10 @@ function getTypeCheckOptions(normalizedOptions: NormalizedSwcExecutorOptions) { typeCheckOptions.cacheDir = cacheDir; } + if (normalizedOptions.isTsSolutionSetup && normalizedOptions.skipTypeCheck) { + typeCheckOptions.ignoreDiagnostics = true; + } + return typeCheckOptions; } @@ -90,7 +94,7 @@ export async function compileSwc( logger.log(swcCmdLog.replace(/\n/, '')); const isCompileSuccess = swcCmdLog.includes('Successfully compiled'); - if (normalizedOptions.skipTypeCheck || normalizedOptions.isTsSolutionSetup) { + if (normalizedOptions.skipTypeCheck && !normalizedOptions.isTsSolutionSetup) { await postCompilationCallback(); return { success: isCompileSuccess }; } diff --git a/packages/js/src/utils/typescript/run-type-check.ts b/packages/js/src/utils/typescript/run-type-check.ts index 79c57b73efd3a..0c5b4ebaf2ff3 100644 --- a/packages/js/src/utils/typescript/run-type-check.ts +++ b/packages/js/src/utils/typescript/run-type-check.ts @@ -22,6 +22,7 @@ interface BaseTypeCheckOptions { incremental?: boolean; rootDir?: string; projectRoot?: string; + ignoreDiagnostics?: boolean; } type Mode = NoEmitMode | EmitDeclarationOnlyMode; @@ -66,7 +67,9 @@ export async function runTypeCheckWatch( const watchProgram = ts.createWatchProgram(host); const program = watchProgram.getProgram().getProgram(); - const diagnostics = ts.getPreEmitDiagnostics(program); + const diagnostics = options.ignoreDiagnostics + ? [] + : ts.getPreEmitDiagnostics(program); return { close: watchProgram.close.bind(watchProgram), @@ -103,9 +106,9 @@ export async function runTypeCheck( const result = program.emit(); - const allDiagnostics = ts - .getPreEmitDiagnostics(program as Program) - .concat(result.diagnostics); + const allDiagnostics = options.ignoreDiagnostics + ? [] + : ts.getPreEmitDiagnostics(program as Program).concat(result.diagnostics); return getTypeCheckResult( ts, diff --git a/packages/node/src/generators/library/library.spec.ts b/packages/node/src/generators/library/library.spec.ts index b4e5a051cf347..65d884a80f775 100644 --- a/packages/node/src/generators/library/library.spec.ts +++ b/packages/node/src/generators/library/library.spec.ts @@ -671,7 +671,7 @@ describe('lib', () => { }, }, "private": true, - "type": "commonjs", + "type": "module", "typings": "./dist/index.d.ts", "version": "0.0.1", }