diff --git a/README.md b/README.md index c7a83279..cac0481b 100644 --- a/README.md +++ b/README.md @@ -86,41 +86,41 @@ you can place your configuration in the: Options passed to the plugin constructor will overwrite options from the cosmiconfig (using [deepmerge](https://github.com/TehShrike/deepmerge)). -| Name | Type | Default value | Description | -| ----------------- | ------------------------------------ | ----------------------------------------- | ----------- | -| `async` | `boolean` | `compiler.options.mode === 'development'` | If `true`, reports issues **after** webpack's compilation is done. Thanks to that it doesn't block the compilation. Used only in the `watch` mode. | -| `typescript` | `object` | `{}` | See [TypeScript options](#typescript-options). | -| `issue` | `object` | `{}` | See [Issues options](#issues-options). | -| `formatter` | `string` or `object` or `function` | `codeframe` | Available formatters are `basic`, `codeframe` and a custom `function`. To [configure](https://babeljs.io/docs/en/babel-code-frame#options) `codeframe` formatter, pass object: `{ type: 'codeframe', options: { } }`. | -| `logger` | `{ log: function, error: function }` | `console` | Console-like object to print issues in `async` mode. | -| `devServer` | `boolean` | `true` | If set to `false`, errors will not be reported to Webpack Dev Server. | +| Name | Type | Default value | Description | +|--------------|--------------------------------------|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `async` | `boolean` | `compiler.options.mode === 'development'` | If `true`, reports issues **after** webpack's compilation is done. Thanks to that it doesn't block the compilation. Used only in the `watch` mode. | +| `typescript` | `object` | `{}` | See [TypeScript options](#typescript-options). | +| `issue` | `object` | `{}` | See [Issues options](#issues-options). | +| `formatter` | `string` or `object` or `function` | `codeframe` | Available formatters are `basic`, `codeframe` and a custom `function`. To [configure](https://babeljs.io/docs/en/babel-code-frame#options) `codeframe` formatter, pass object: `{ type: 'codeframe', options: { } }`. | +| `logger` | `{ log: function, error: function }` | `console` | Console-like object to print issues in `async` mode. | +| `devServer` | `boolean` | `true` | If set to `false`, errors will not be reported to Webpack Dev Server. | ### TypeScript options Options for the TypeScript checker (`typescript` option object). -| Name | Type | Default value | Description | -| -------------------- | --------- | -------------------------------------------------------------------------------------------------------------- | ----------- | -| `memoryLimit` | `number` | `2048` | Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number. | -| `configFile` | `string` | `'tsconfig.json'` | Path to the `tsconfig.json` file (path relative to the `compiler.options.context` or absolute path) | -| `configOverwrite` | `object` | `{ compilerOptions: { skipLibCheck: true, sourceMap: false, inlineSourceMap: false, declarationMap: false } }` | This configuration will overwrite configuration from the `tsconfig.json` file. Supported fields are: `extends`, `compilerOptions`, `include`, `exclude`, `files`, and `references`. | -| `context` | `string` | `dirname(configuration.configFile)` | The base path for finding files specified in the `tsconfig.json`. Same as the `context` option from the [ts-loader](https://github.com/TypeStrong/ts-loader#context). Useful if you want to keep your `tsconfig.json` in an external package. Keep in mind that **not** having a `tsconfig.json` in your project root can cause different behaviour between `fork-ts-checker-webpack-plugin` and `tsc`. When using editors like `VS Code` it is advised to add a `tsconfig.json` file to the root of the project and extend the config file referenced in option `configFile`. | -| `build` | `boolean` | `false` | The equivalent of the `--build` flag for the `tsc` command. | -| `mode` | `'readonly'` or `'write-tsbuildinfo'` or `'write-dts'` or `'write-references'` | `'write-tsbuildinfo'` | If you use the `babel-loader`, it's recommended to use `write-references` mode to improve initial compilation time. If you use `ts-loader`, it's recommended to use `write-tsbuildinfo` mode to not overwrite files emitted by the `ts-loader`. If you use `ts-loader` with `transpileOnly` flag set to `true`, use `'write-dts` to emit the type definition files. | -| `diagnosticOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. | -| `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). | -| `profile` | `boolean` | `false` | Measures and prints timings related to the TypeScript performance. | -| `typescriptPath` | `string` | `require.resolve('typescript')` | If supplied this is a custom path where TypeScript can be found. | +| Name | Type | Default value | Description | +|---------------------|--------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `memoryLimit` | `number` | `2048` | Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number. | +| `configFile` | `string` | `'tsconfig.json'` | Path to the `tsconfig.json` file (path relative to the `compiler.options.context` or absolute path) | +| `configOverwrite` | `object` | `{ compilerOptions: { skipLibCheck: true, sourceMap: false, inlineSourceMap: false, declarationMap: false } }` | This configuration will overwrite configuration from the `tsconfig.json` file. Supported fields are: `extends`, `compilerOptions`, `include`, `exclude`, `files`, and `references`. | +| `context` | `string` | `dirname(configuration.configFile)` | The base path for finding files specified in the `tsconfig.json`. Same as the `context` option from the [ts-loader](https://github.com/TypeStrong/ts-loader#context). Useful if you want to keep your `tsconfig.json` in an external package. Keep in mind that **not** having a `tsconfig.json` in your project root can cause different behaviour between `fork-ts-checker-webpack-plugin` and `tsc`. When using editors like `VS Code` it is advised to add a `tsconfig.json` file to the root of the project and extend the config file referenced in option `configFile`. | +| `build` | `boolean` | `false` | The equivalent of the `--build` flag for the `tsc` command. | +| `mode` | `'readonly'` or `'write-dts'` or `'write-tsbuildinfo'` or `'write-references'` | `build === true ? 'write-tsbuildinfo' ? 'readonly'` | Use `readonly` if you don't want to write anything on the disk, `write-dts` to write only `.d.ts` files, `write-tsbuildinfo` to write only `.tsbuildinfo` files, `write-references` to write both `.js` and `.d.ts` files of project references (last 2 modes requires `build: true`). | +| `diagnosticOptions` | `object` | `{ syntactic: false, semantic: true, declaration: false, global: false }` | Settings to select which diagnostics do we want to perform. | +| `extensions` | `object` | `{}` | See [TypeScript extensions options](#typescript-extensions-options). | +| `profile` | `boolean` | `false` | Measures and prints timings related to the TypeScript performance. | +| `typescriptPath` | `string` | `require.resolve('typescript')` | If supplied this is a custom path where TypeScript can be found. | #### TypeScript extensions options Options for the TypeScript checker extensions (`typescript.extensions` option object). -| Name | Type | Default value | Description | -| -------------------- | --------------------- | ------------------------- | ----------- | -| `vue` | `object` or `boolean` | `false` | If `true`, it enables Vue [Single File Component](https://vuejs.org/v2/guide/single-file-components.html) support. | -| `vue.enabled` | `boolean` | `false` | Same as the `vue` option | -| `vue.compiler` | `string` | `'vue-template-compiler'` | The package name of the compiler that will be used to parse `.vue` files. You can use `'nativescript-vue-template-compiler'` if you use [nativescript-vue](https://github.com/nativescript-vue/nativescript-vue) | +| Name | Type | Default value | Description | +|----------------|-----------------------|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `vue` | `object` or `boolean` | `false` | If `true`, it enables Vue [Single File Component](https://vuejs.org/v2/guide/single-file-components.html) support. | +| `vue.enabled` | `boolean` | `false` | Same as the `vue` option | +| `vue.compiler` | `string` | `'vue-template-compiler'` | The package name of the compiler that will be used to parse `.vue` files. You can use `'nativescript-vue-template-compiler'` if you use [nativescript-vue](https://github.com/nativescript-vue/nativescript-vue) | ### Issues options @@ -139,10 +139,10 @@ type IssuePredicate = (issue: Issue) => boolean; type IssueFilter = IssueMatch | IssuePredicate | (IssueMatch | IssuePredicate)[]; ``` -| Name | Type | Default value | Description | -| --------- | ------------- | ------------- | ----------- | +| Name | Type | Default value | Description | +|-----------|---------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| | `include` | `IssueFilter` | `undefined` | If `object`, defines issue properties that should be [matched](src/issue/issue-match.ts). If `function`, acts as a predicate where `issue` is an argument. | -| `exclude` | `IssueFilter` | `undefined` | Same as `include` but issues that match this predicate will be excluded. | +| `exclude` | `IssueFilter` | `undefined` | Same as `include` but issues that match this predicate will be excluded. |
Expand example @@ -286,13 +286,13 @@ declare module "*.vue" { This plugin provides some custom webpack hooks: -| Hook key | Type | Params | Description | -| ---------- | -------------------------- | --------------------- | ----------- | +| Hook key | Type | Params | Description | +|------------|----------------------------|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `start` | `AsyncSeriesWaterfallHook` | `change, compilation` | Starts issues checking for a compilation. It's an async waterfall hook, so you can modify the list of changed and removed files or delay the start of the service. | -| `waiting` | `SyncHook` | `compilation` | Waiting for the issues checking. | -| `canceled` | `SyncHook` | `compilation` | Issues checking for the compilation has been canceled. | -| `error` | `SyncHook` | `compilation` | An error occurred during issues checking. | -| `issues` | `SyncWaterfallHook` | `issues, compilation` | Issues have been received and will be reported. It's a waterfall hook, so you can modify the list of received issues. | +| `waiting` | `SyncHook` | `compilation` | Waiting for the issues checking. | +| `canceled` | `SyncHook` | `compilation` | Issues checking for the compilation has been canceled. | +| `error` | `SyncHook` | `compilation` | An error occurred during issues checking. | +| `issues` | `SyncWaterfallHook` | `issues, compilation` | Issues have been received and will be reported. It's a waterfall hook, so you can modify the list of received issues. | To access plugin hooks and tap into the event, we need to use the `getCompilerHooks` static method. When we call this method with a [webpack compiler instance](https://webpack.js.org/api/node/), it returns the object with @@ -373,3 +373,4 @@ This plugin was created in [Realytics](https://www.realytics.io/) in 2017. Thank ## License MIT License + diff --git a/src/typescript/type-script-worker-config.ts b/src/typescript/type-script-worker-config.ts index 199fcf58..dae89888 100644 --- a/src/typescript/type-script-worker-config.ts +++ b/src/typescript/type-script-worker-config.ts @@ -1,6 +1,5 @@ import path from 'path'; -import semver from 'semver'; import type webpack from 'webpack'; import type { TypeScriptVueExtensionConfig } from './extension/vue/type-script-vue-extension-config'; @@ -16,7 +15,7 @@ interface TypeScriptWorkerConfig { configOverwrite: TypeScriptConfigOverwrite; build: boolean; context: string; - mode: 'readonly' | 'write-tsbuildinfo' | 'write-dts' | 'write-references'; + mode: 'readonly' | 'write-dts' | 'write-tsbuildinfo' | 'write-references'; diagnosticOptions: TypeScriptDiagnosticsOptions; extensions: { vue: TypeScriptVueExtensionConfig; @@ -44,31 +43,15 @@ function createTypeScriptWorkerConfig( const typescriptPath = optionsAsObject.typescriptPath || require.resolve('typescript'); - const defaultCompilerOptions: Record = { - skipLibCheck: true, - sourceMap: false, - inlineSourceMap: false, - }; - // eslint-disable-next-line @typescript-eslint/no-var-requires - if (semver.gte(require(typescriptPath).version, '2.9.0')) { - defaultCompilerOptions.declarationMap = false; - } - return { enabled: options !== false, memoryLimit: 2048, build: false, - mode: 'write-tsbuildinfo', + mode: optionsAsObject.build ? 'write-tsbuildinfo' : 'readonly', profile: false, ...optionsAsObject, configFile: configFile, - configOverwrite: { - ...(optionsAsObject.configOverwrite || {}), - compilerOptions: { - ...defaultCompilerOptions, - ...((optionsAsObject.configOverwrite || {}).compilerOptions || {}), - }, - }, + configOverwrite: optionsAsObject.configOverwrite || {}, context: optionsAsObject.context || path.dirname(configFile), extensions: { vue: createTypeScriptVueExtensionConfig( diff --git a/src/typescript/worker/lib/config.ts b/src/typescript/worker/lib/config.ts index da7d760c..18a4998d 100644 --- a/src/typescript/worker/lib/config.ts +++ b/src/typescript/worker/lib/config.ts @@ -29,28 +29,83 @@ for (const extension of extensions) { } } +function getUserProvidedConfigOverwrite(): TypeScriptConfigOverwrite { + return config.configOverwrite || {}; +} + +function getImplicitConfigOverwrite(): TypeScriptConfigOverwrite { + const baseCompilerOptionsOverwrite = { + skipLibCheck: true, + sourceMap: false, + inlineSourceMap: false, + }; + + switch (config.mode) { + case 'write-dts': + return { + compilerOptions: { + ...baseCompilerOptionsOverwrite, + declaration: true, + emitDeclarationOnly: true, + noEmit: false, + }, + }; + case 'write-tsbuildinfo': + case 'write-references': + return { + compilerOptions: { + ...baseCompilerOptionsOverwrite, + declaration: true, + emitDeclarationOnly: false, + noEmit: false, + }, + }; + } + + return { + compilerOptions: baseCompilerOptionsOverwrite, + }; +} + +function applyConfigOverwrite( + baseConfig: TypeScriptConfigOverwrite, + ...overwriteConfigs: TypeScriptConfigOverwrite[] +): TypeScriptConfigOverwrite { + let config = baseConfig; + + for (const overwriteConfig of overwriteConfigs) { + config = { + ...(config || {}), + ...(overwriteConfig || {}), + compilerOptions: { + ...(config?.compilerOptions || {}), + ...(overwriteConfig?.compilerOptions || {}), + }, + }; + } + + return config; +} + export function parseConfig( configFileName: string, - configFileContext: string, - configOverwriteJSON: TypeScriptConfigOverwrite = {} + configFileContext: string ): ts.ParsedCommandLine { const configFilePath = forwardSlash(configFileName); - const parsedConfigFileJSON = typescript.readConfigFile( + + const { config: baseConfig, error: readConfigError } = typescript.readConfigFile( configFilePath, parseConfigFileHost.readFile ); - const overwrittenConfigFileJSON = { - ...(parsedConfigFileJSON.config || {}), - ...configOverwriteJSON, - compilerOptions: { - ...((parsedConfigFileJSON.config || {}).compilerOptions || {}), - ...(configOverwriteJSON.compilerOptions || {}), - }, - }; + const overwrittenConfig = applyConfigOverwrite( + baseConfig || {}, + getImplicitConfigOverwrite(), + getUserProvidedConfigOverwrite() + ); const parsedConfigFile = typescript.parseJsonConfigFileContent( - overwrittenConfigFileJSON, + overwrittenConfig, parseConfigFileHost, configFileContext ); @@ -61,7 +116,7 @@ export function parseConfig( ...parsedConfigFile.options, configFilePath: configFilePath, }, - errors: parsedConfigFileJSON.error ? [parsedConfigFileJSON.error] : parsedConfigFile.errors, + errors: readConfigError ? [readConfigError] : parsedConfigFile.errors, }; } @@ -79,36 +134,8 @@ export function getParseConfigIssues(): Issue[] { export function getParsedConfig(force = false) { if (!parsedConfig || force) { - parseConfigDiagnostics = []; - - parsedConfig = parseConfig(config.configFile, config.context, config.configOverwrite); - - const configFilePath = forwardSlash(config.configFile); - const parsedConfigFileJSON = typescript.readConfigFile( - configFilePath, - parseConfigFileHost.readFile - ); - const overwrittenConfigFileJSON = { - ...(parsedConfigFileJSON.config || {}), - ...config.configOverwrite, - compilerOptions: { - ...((parsedConfigFileJSON.config || {}).compilerOptions || {}), - ...(config.configOverwrite.compilerOptions || {}), - }, - }; - parsedConfig = typescript.parseJsonConfigFileContent( - overwrittenConfigFileJSON, - parseConfigFileHost, - config.context - ); - parsedConfig.options.configFilePath = configFilePath; - parsedConfig.errors = parsedConfigFileJSON.error - ? [parsedConfigFileJSON.error] - : parsedConfig.errors; - - if (parsedConfig.errors) { - parseConfigDiagnostics.push(...parsedConfig.errors); - } + parsedConfig = parseConfig(config.configFile, config.context); + parseConfigDiagnostics = parsedConfig.errors || []; } return parsedConfig; diff --git a/src/typescript/worker/lib/emit.ts b/src/typescript/worker/lib/emit.ts new file mode 100644 index 00000000..405d976a --- /dev/null +++ b/src/typescript/worker/lib/emit.ts @@ -0,0 +1,13 @@ +import type * as ts from 'typescript'; + +import { getParsedConfig } from './config'; +import { config } from './worker-config'; + +export function emitDtsIfNeeded(program: ts.Program | ts.BuilderProgram) { + const parsedConfig = getParsedConfig(); + + if (config.mode === 'write-dts' && parsedConfig.options.declaration) { + // emit .d.ts files only + program.emit(undefined, undefined, undefined, true); + } +} diff --git a/src/typescript/worker/lib/program/program.ts b/src/typescript/worker/lib/program/program.ts index 2475f1dd..db9457d7 100644 --- a/src/typescript/worker/lib/program/program.ts +++ b/src/typescript/worker/lib/program/program.ts @@ -2,6 +2,7 @@ import type * as ts from 'typescript'; import { getConfigFilePathFromProgram, getParsedConfig } from '../config'; import { updateDiagnostics, getDiagnosticsOfProgram } from '../diagnostics'; +import { emitDtsIfNeeded } from '../emit'; import { createCompilerHost } from '../host/compiler-host'; import { typescript } from '../typescript'; @@ -24,6 +25,7 @@ export function useProgram() { } updateDiagnostics(getConfigFilePathFromProgram(program), getDiagnosticsOfProgram(program)); + emitDtsIfNeeded(program); } export function invalidateProgram(withHost = false) { diff --git a/src/typescript/worker/lib/program/watch-program.ts b/src/typescript/worker/lib/program/watch-program.ts index 80df0600..757256b0 100644 --- a/src/typescript/worker/lib/program/watch-program.ts +++ b/src/typescript/worker/lib/program/watch-program.ts @@ -3,6 +3,7 @@ import type * as ts from 'typescript'; import { getConfigFilePathFromBuilderProgram, getParsedConfig } from '../config'; import { getDependencies } from '../dependencies'; import { updateDiagnostics, getDiagnosticsOfProgram } from '../diagnostics'; +import { emitDtsIfNeeded } from '../emit'; import { createWatchCompilerHost } from '../host/watch-compiler-host'; import { startTracingIfNeeded, stopTracingIfNeeded } from '../tracing'; import { emitTsBuildInfoIfNeeded } from '../tsbuildinfo'; @@ -49,6 +50,7 @@ export function useWatchProgram() { getConfigFilePathFromBuilderProgram(builderProgram), getDiagnosticsOfProgram(builderProgram) ); + emitDtsIfNeeded(builderProgram); emitTsBuildInfoIfNeeded(builderProgram); stopTracingIfNeeded(builderProgram); } diff --git a/test/e2e/type-script-solution-builder-api.spec.ts b/test/e2e/type-script-solution-builder-api.spec.ts index 0de0fea4..c8d7b608 100644 --- a/test/e2e/type-script-solution-builder-api.spec.ts +++ b/test/e2e/type-script-solution-builder-api.spec.ts @@ -129,6 +129,11 @@ describe('TypeScript SolutionBuilder API', () => { expect(await sandbox.exists('packages/client/lib/index.d.ts.map')).toEqual(true); expect(await sandbox.exists('packages/shared/lib/index.js')).toEqual(false); expect(await sandbox.exists('packages/client/lib/index.js')).toEqual(false); + expect(await sandbox.exists('packages/client/lib/nested/additional.d.ts')).toEqual(true); + expect(await sandbox.exists('packages/client/lib/nested/additional.d.ts.map')).toEqual( + true + ); + expect(await sandbox.exists('packages/client/lib/nested/additional.js')).toEqual(false); expect(await sandbox.read('packages/shared/lib/tsconfig.tsbuildinfo')).not.toEqual(''); expect(await sandbox.read('packages/client/lib/tsconfig.tsbuildinfo')).not.toEqual(''); diff --git a/test/e2e/type-script-watch-api.spec.ts b/test/e2e/type-script-watch-api.spec.ts index 7114b0af..5ce64aaa 100644 --- a/test/e2e/type-script-watch-api.spec.ts +++ b/test/e2e/type-script-watch-api.spec.ts @@ -412,4 +412,91 @@ describe('TypeScript Watch API', () => { new Error('Exceeded time on waiting for errors to appear.') ); }); + + it.each([{ async: false }, { async: true }])( + 'saves .d.ts files in watch mode with %p', + async ({ async }) => { + await sandbox.load(path.join(__dirname, 'fixtures/typescript-basic')); + await sandbox.install('yarn', {}); + await sandbox.patch( + 'webpack.config.js', + 'async: false,', + `async: ${JSON.stringify(async)}, typescript: { mode: 'write-dts' },` + ); + + const driver = createWebpackDevServerDriver( + sandbox.spawn('yarn webpack serve --mode=development'), + async + ); + + // first compilation is successful + await driver.waitForNoErrors(); + + // then we add a new file + await sandbox.write( + 'src/model/Organization.ts', + [ + 'interface Organization {', + ' id: number;', + ' name: string;', + '}', + '', + 'export { Organization }', + ].join('\n') + ); + + // this should not introduce an error - file is not used + await driver.waitForNoErrors(); + + // add organization name to the getUserName function + await sandbox.patch( + 'src/model/User.ts', + 'return [user.firstName, user.lastName]', + 'return [user.firstName, user.lastName, user.organization.name]' + ); + + expect(await driver.waitForErrors()).toEqual([ + [ + 'ERROR in ./src/model/User.ts 12:47-59', + "TS2339: Property 'organization' does not exist on type 'User'.", + ' 10 |', + ' 11 | function getUserName(user: User): string {', + " > 12 | return [user.firstName, user.lastName, user.organization.name].filter((name) => name !== undefined).join(' ');", + ' | ^^^^^^^^^^^^', + ' 13 | }', + ' 14 |', + ' 15 | export { User, getUserName };', + ].join('\n'), + ]); + + // fix the error + await sandbox.patch( + 'src/model/User.ts', + "import { Role } from './Role';", + ["import { Role } from './Role';", "import { Organization } from './Organization';"].join( + '\n' + ) + ); + await sandbox.patch( + 'src/model/User.ts', + ' role: Role;', + [' role: Role;', ' organization: Organization;'].join('\n') + ); + + // there should be no errors + await driver.waitForNoErrors(); + + // check if .d.ts files has been created + expect(await sandbox.exists('dist')).toEqual(true); + expect(await sandbox.exists('dist/index.d.ts')).toEqual(true); + expect(await sandbox.exists('dist/index.js')).toEqual(false); + expect(await sandbox.exists('dist/index.js.map')).toEqual(false); + expect(await sandbox.exists('dist/authenticate.d.ts')).toEqual(true); + expect(await sandbox.exists('dist/model/User.d.ts')).toEqual(true); + expect(await sandbox.exists('dist/model/Role.d.ts')).toEqual(true); + expect(await sandbox.exists('dist/model/Organization.d.ts')).toEqual(true); + + await sandbox.remove('dist'); + } + ); }); diff --git a/test/e2e/webpack-production-build.spec.ts b/test/e2e/webpack-production-build.spec.ts index fb9c6a8c..83803bb1 100644 --- a/test/e2e/webpack-production-build.spec.ts +++ b/test/e2e/webpack-production-build.spec.ts @@ -22,9 +22,45 @@ describe('Webpack Production Build', () => { const errors = extractWebpackErrors(result); expect(errors).toEqual([]); + + // check if files has been created + expect(await sandbox.exists('dist')).toEqual(true); + expect(await sandbox.exists('dist/index.d.ts')).toEqual(false); + expect(await sandbox.exists('dist/index.js')).toEqual(true); + expect(await sandbox.exists('dist/authenticate.d.ts')).toEqual(false); + expect(await sandbox.exists('dist/model/User.d.ts')).toEqual(false); + expect(await sandbox.exists('dist/model/Role.d.ts')).toEqual(false); + + await sandbox.remove('dist'); } ); + it('generates .d.ts files in write-dts mode', async () => { + await sandbox.load(path.join(__dirname, 'fixtures/typescript-basic')); + await sandbox.install('yarn', { webpack: '^5.11.0' }); + + await sandbox.patch( + 'webpack.config.js', + 'async: false,', + 'async: false, typescript: { mode: "write-dts" },' + ); + + const result = await sandbox.exec('yarn webpack --mode=production'); + const errors = extractWebpackErrors(result); + + expect(errors).toEqual([]); + + // check if files has been created + expect(await sandbox.exists('dist')).toEqual(true); + expect(await sandbox.exists('dist/index.d.ts')).toEqual(true); + expect(await sandbox.exists('dist/index.js')).toEqual(true); + expect(await sandbox.exists('dist/authenticate.d.ts')).toEqual(true); + expect(await sandbox.exists('dist/model/User.d.ts')).toEqual(true); + expect(await sandbox.exists('dist/model/Role.d.ts')).toEqual(true); + + await sandbox.remove('dist'); + }); + it.each([{ webpack: '5.11.0' }, { webpack: '^5.11.0' }])( 'exits with error on the project error with %p', async (dependencies) => { diff --git a/test/unit/typescript/type-script-worker-config.spec.ts b/test/unit/typescript/type-script-worker-config.spec.ts index 12e95884..feca0137 100644 --- a/test/unit/typescript/type-script-worker-config.spec.ts +++ b/test/unit/typescript/type-script-worker-config.spec.ts @@ -13,17 +13,10 @@ describe('typescript/type-scripts-worker-config', () => { enabled: true, memoryLimit: 2048, configFile: path.normalize(path.resolve(context, 'tsconfig.json')), - configOverwrite: { - compilerOptions: { - skipLibCheck: true, - sourceMap: false, - inlineSourceMap: false, - declarationMap: false, - }, - }, + configOverwrite: {}, context: path.normalize(path.dirname(path.resolve(context, 'tsconfig.json'))), build: false, - mode: 'write-tsbuildinfo', + mode: 'readonly', diagnosticOptions: { semantic: true, syntactic: false, @@ -72,7 +65,7 @@ describe('typescript/type-scripts-worker-config', () => { configFile: path.normalize(path.resolve(context, 'tsconfig.another.json')), }, ], - [{ build: true }, { ...configuration, build: true }], + [{ build: true }, { ...configuration, build: true, mode: 'write-tsbuildinfo' }], [{ mode: 'readonly' }, { ...configuration, mode: 'readonly' }], [{ mode: 'write-tsbuildinfo' }, { ...configuration, mode: 'write-tsbuildinfo' }], [{ mode: 'write-dts' }, { ...configuration, mode: 'write-dts' }], @@ -83,10 +76,6 @@ describe('typescript/type-scripts-worker-config', () => { ...configuration, configOverwrite: { compilerOptions: { - skipLibCheck: true, - sourceMap: false, - inlineSourceMap: false, - declarationMap: false, strict: true, }, include: ['src'],