diff --git a/docs/content/2.guide/1.concepts/6.typescript.md b/docs/content/2.guide/1.concepts/6.typescript.md index 2f1fa4606a..4538c86ad1 100644 --- a/docs/content/2.guide/1.concepts/6.typescript.md +++ b/docs/content/2.guide/1.concepts/6.typescript.md @@ -4,7 +4,7 @@ Nuxt 3 is fully typed and provides helpful shortcuts to ensure you have access t ## Type-checking -By default, Nuxt doesn't check types when you run `nuxi dev` or `nuxi build`, for performance reasons. However, you can [manually check your types with nuxi](/api/commands/typecheck). +By default, Nuxt doesn't check types when you run `nuxi dev` or `nuxi build`, for performance reasons. However, you can enable type-checking at build or development time with [the `typescript.typeCheck` option in your `nuxt.config` file](/api/configuration/nuxt.config#typescript), or [manually check your types with nuxi](/api/commands/typecheck). ```bash yarn nuxi typecheck diff --git a/docs/content/3.api/5.commands/typecheck.md b/docs/content/3.api/5.commands/typecheck.md index d8232ca219..8196eb3390 100644 --- a/docs/content/3.api/5.commands/typecheck.md +++ b/docs/content/3.api/5.commands/typecheck.md @@ -11,3 +11,7 @@ Option | Default | Description `rootDir` | `.` | The directory of the target application. This command sets `process.env.NODE_ENV` to `production`. To override, define `NODE_ENV` in a `.env` file or as command-line argument. + +::alert +You can also enable type-checking at build or development time with [the `typescript.typeCheck` option in your `nuxt.config` file](/api/configuration/nuxt.config#typescript). +:: diff --git a/packages/schema/src/config/typescript.ts b/packages/schema/src/config/typescript.ts index ce54e86d65..ae9d5dea77 100644 --- a/packages/schema/src/config/typescript.ts +++ b/packages/schema/src/config/typescript.ts @@ -7,12 +7,21 @@ export default { */ typescript: { /** - * TypeScript comes with certain checks to give you more safety and analysis of your program. - * Once you’ve converted your codebase to TypeScript, you can start enabling these checks for greater safety. - * [Read More](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html#getting-stricter-checks) - */ + * TypeScript comes with certain checks to give you more safety and analysis of your program. + * Once you’ve converted your codebase to TypeScript, you can start enabling these checks for greater safety. + * [Read More](https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html#getting-stricter-checks) + */ strict: false, + /** + * Enable build-time type checking. + * + * If set to true, this will type check in development. You can restrict this to build-time type checking by setting it to `build`. + * + * @type {boolean | 'build'} + */ + typeCheck: false, + /** * You can extend generated `.nuxt/tsconfig.json` using this option * @type {typeof import('pkg-types')['readPackageJSON']} diff --git a/packages/vite/package.json b/packages/vite/package.json index 5e5cbde5fe..18fc81103d 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -45,7 +45,8 @@ "ufo": "^0.8.3", "unplugin": "^0.6.2", "vite": "^2.9.5", - "vite-node": "^0.9.3" + "vite-node": "^0.9.3", + "vite-plugin-checker": "^0.4.6" }, "peerDependencies": { "vue": "3.2.33" diff --git a/packages/vite/src/server.ts b/packages/vite/src/server.ts index 18ae909345..2840aaac5d 100644 --- a/packages/vite/src/server.ts +++ b/packages/vite/src/server.ts @@ -80,6 +80,12 @@ export async function buildServer (ctx: ViteBuildContext) { ] } as ViteOptions) + // Add type-checking + if (ctx.nuxt.options.typescript.typeCheck === true || (ctx.nuxt.options.typescript.typeCheck === 'build' && !ctx.nuxt.options.dev)) { + const checker = await import('vite-plugin-checker').then(r => r.default) + ctx.config.plugins.push(checker({ typescript: true })) + } + await ctx.nuxt.callHook('vite:extendConfig', serverConfig, { isClient: false, isServer: true }) // TODO: Do we still need this? diff --git a/packages/webpack/package.json b/packages/webpack/package.json index 3ffe6de96b..b58bbb51fb 100644 --- a/packages/webpack/package.json +++ b/packages/webpack/package.json @@ -26,6 +26,7 @@ "esbuild-loader": "^2.18.0", "escape-string-regexp": "^5.0.0", "file-loader": "^6.2.0", + "fork-ts-checker-webpack-plugin": "^7.2.6", "fs-extra": "^10.0.1", "hash-sum": "^2.0.0", "lodash-es": "^4.17.21", diff --git a/packages/webpack/src/configs/server.ts b/packages/webpack/src/configs/server.ts index 96bbd2f7cf..2404649808 100644 --- a/packages/webpack/src/configs/server.ts +++ b/packages/webpack/src/configs/server.ts @@ -1,5 +1,7 @@ import { isAbsolute } from 'pathe' import webpack from 'webpack' +import ForkTSCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin' +import { logger } from '@nuxt/kit' import { WebpackConfigContext, applyPresets, getWebpackConfig } from '../utils/config' import { nuxt } from '../presets/nuxt' import { node } from '../presets/node' @@ -77,4 +79,9 @@ function serverPlugins (ctx: WebpackConfigContext) { URLSearchParams: [options.webpack.serverURLPolyfill, 'URLSearchParams'] })) } + + // Add type-checking + if (ctx.nuxt.options.typescript.typeCheck === true || (ctx.nuxt.options.typescript.typeCheck === 'build' && !ctx.nuxt.options.dev)) { + ctx.config.plugins.push(new ForkTSCheckerWebpackPlugin({ logger })) + } } diff --git a/yarn.lock b/yarn.lock index 757a3efdda..c0f442cf2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -31,7 +31,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.16.7": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7": version: 7.16.7 resolution: "@babel/code-frame@npm:7.16.7" dependencies: @@ -1659,6 +1659,7 @@ __metadata: unplugin: ^0.6.2 vite: ^2.9.5 vite-node: ^0.9.3 + vite-plugin-checker: ^0.4.6 vue: 3.2.33 peerDependencies: vue: 3.2.33 @@ -1685,6 +1686,7 @@ __metadata: esbuild-loader: ^2.18.0 escape-string-regexp: ^5.0.0 file-loader: ^6.2.0 + fork-ts-checker-webpack-plugin: ^7.2.6 fs-extra: ^10.0.1 hash-sum: ^2.0.0 lodash-es: ^4.17.21 @@ -3429,7 +3431,7 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^4.2.1": +"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" dependencies: @@ -4176,7 +4178,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.1": +"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -4507,7 +4509,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:8.3.0": +"commander@npm:8.3.0, commander@npm:^8.0.0": version: 8.3.0 resolution: "commander@npm:8.3.0" checksum: 0f82321821fc27b83bd409510bb9deeebcfa799ff0bf5d102128b500b7af22872c0c92cb6a0ebc5a4cf19c6b550fba9cedfa7329d18c6442a625f851377bacf0 @@ -4776,7 +4778,7 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^7.0.0": +"cosmiconfig@npm:^7.0.0, cosmiconfig@npm:^7.0.1": version: 7.0.1 resolution: "cosmiconfig@npm:7.0.1" dependencies: @@ -6811,7 +6813,7 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.5, fast-glob@npm:^3.2.9": +"fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.5, fast-glob@npm:^3.2.7, fast-glob@npm:^3.2.9": version: 3.2.11 resolution: "fast-glob@npm:3.2.11" dependencies: @@ -7047,6 +7049,32 @@ __metadata: languageName: node linkType: hard +"fork-ts-checker-webpack-plugin@npm:^7.2.6": + version: 7.2.6 + resolution: "fork-ts-checker-webpack-plugin@npm:7.2.6" + dependencies: + "@babel/code-frame": ^7.16.7 + chalk: ^4.1.2 + chokidar: ^3.5.3 + cosmiconfig: ^7.0.1 + deepmerge: ^4.2.2 + fs-extra: ^10.0.0 + memfs: ^3.4.1 + minimatch: ^3.0.4 + schema-utils: ^3.1.1 + semver: ^7.3.5 + tapable: ^2.2.1 + peerDependencies: + typescript: ">3.6.0" + vue-template-compiler: "*" + webpack: ^5.11.0 + peerDependenciesMeta: + vue-template-compiler: + optional: true + checksum: d74e8b22e3e4d5159061d93f519d7eb795bafac4b9a993b72eed952a714144d89c8a706414b231a89c69cabf29e00e1fb26d7060e3b5577c08cabb5a3d5a7697 + languageName: node + linkType: hard + "form-data@npm:~2.3.2": version: 2.3.3 resolution: "form-data@npm:2.3.3" @@ -8991,6 +9019,13 @@ __metadata: languageName: node linkType: hard +"lodash.debounce@npm:^4.0.8": + version: 4.0.8 + resolution: "lodash.debounce@npm:4.0.8" + checksum: a3f527d22c548f43ae31c861ada88b2637eb48ac6aa3eb56e82d44917971b8aa96fbb37aa60efea674dc4ee8c42074f90f7b1f772e9db375435f6c83a19b3bc6 + languageName: node + linkType: hard + "lodash.defaults@npm:^4.2.0": version: 4.2.0 resolution: "lodash.defaults@npm:4.2.0" @@ -9047,6 +9082,13 @@ __metadata: languageName: node linkType: hard +"lodash.pick@npm:^4.4.0": + version: 4.4.0 + resolution: "lodash.pick@npm:4.4.0" + checksum: 2c36cab7da6b999a20bd3373b40e31a3ef81fa264f34a6979c852c5bc8ac039379686b27380f0cb8e3781610844fafec6949c6fbbebc059c98f8fa8570e3675f + languageName: node + linkType: hard + "lodash.template@npm:^4.5.0": version: 4.5.0 resolution: "lodash.template@npm:4.5.0" @@ -13319,7 +13361,7 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.1.1, tapable@npm:^2.2.0": +"tapable@npm:^2.1.1, tapable@npm:^2.2.0, tapable@npm:^2.2.1": version: 2.2.1 resolution: "tapable@npm:2.2.1" checksum: 3b7a1b4d86fa940aad46d9e73d1e8739335efd4c48322cb37d073eb6f80f5281889bf0320c6d8ffcfa1a0dd5bfdbd0f9d037e252ef972aca595330538aac4d51 @@ -13517,6 +13559,13 @@ __metadata: languageName: node linkType: hard +"tiny-invariant@npm:^1.1.0": + version: 1.2.0 + resolution: "tiny-invariant@npm:1.2.0" + checksum: e09a718a7c4a499ba592cdac61f015d87427a0867ca07f50c11fd9b623f90cdba18937b515d4a5e4f43dac92370498d7bdaee0d0e7a377a61095e02c4a92eade + languageName: node + linkType: hard + "tinypool@npm:^0.1.2": version: 0.1.2 resolution: "tinypool@npm:0.1.2" @@ -14224,6 +14273,33 @@ __metadata: languageName: node linkType: hard +"vite-plugin-checker@npm:^0.4.6": + version: 0.4.6 + resolution: "vite-plugin-checker@npm:0.4.6" + dependencies: + "@babel/code-frame": ^7.12.13 + ansi-escapes: ^4.3.0 + chalk: ^4.1.1 + chokidar: ^3.5.1 + commander: ^8.0.0 + fast-glob: ^3.2.7 + lodash.debounce: ^4.0.8 + lodash.pick: ^4.4.0 + npm-run-path: ^4.0.1 + strip-ansi: ^6.0.0 + tiny-invariant: ^1.1.0 + vscode-languageclient: ^7.0.0 + vscode-languageserver: ^7.0.0 + vscode-languageserver-textdocument: ^1.0.1 + vscode-uri: ^3.0.2 + peerDependencies: + vite: ^2.0.0 + bin: + vite-plugin-checker-vls: bin/vls + checksum: c6eddc40393f8000a096b3084c0d1eb7e9a3ba6b89e11f003b01920a00939d02b13e731e060310fe58b28cf4c6362b8ed8f129d951cf7b7b13bf2fee15ebbaab + languageName: node + linkType: hard + "vite@npm:^2.9.5": version: 2.9.5 resolution: "vite@npm:2.9.5" @@ -14284,6 +14360,66 @@ __metadata: languageName: node linkType: hard +"vscode-jsonrpc@npm:6.0.0": + version: 6.0.0 + resolution: "vscode-jsonrpc@npm:6.0.0" + checksum: 3a67a56f287e8c449f2d9752eedf91e704dc7b9a326f47fb56ac07667631deb45ca52192e9bccb2ab108764e48409d70fa64b930d46fc3822f75270b111c5f53 + languageName: node + linkType: hard + +"vscode-languageclient@npm:^7.0.0": + version: 7.0.0 + resolution: "vscode-languageclient@npm:7.0.0" + dependencies: + minimatch: ^3.0.4 + semver: ^7.3.4 + vscode-languageserver-protocol: 3.16.0 + checksum: fde7122e96838f0de1940dba80fc4b6bb80717695dbfaff005b9d44eeea371b7f09daedefaebcbf0ff278f67446e37837ec0730ddbc7dbd82aca5d8567065594 + languageName: node + linkType: hard + +"vscode-languageserver-protocol@npm:3.16.0": + version: 3.16.0 + resolution: "vscode-languageserver-protocol@npm:3.16.0" + dependencies: + vscode-jsonrpc: 6.0.0 + vscode-languageserver-types: 3.16.0 + checksum: ac30cbe4b778344f7b93defbaa1332dcb5a5a3a0afda6b88618a9ed44093c1ae1d2f11548bdcff42a73bb46943df025d4fe721559144dd7bf25ae60663aabe06 + languageName: node + linkType: hard + +"vscode-languageserver-textdocument@npm:^1.0.1": + version: 1.0.4 + resolution: "vscode-languageserver-textdocument@npm:1.0.4" + checksum: d0b63abb9d22c1177c26df15807b028129fb966f0dfd01c9ae1d114f1c2a1262d8588bea3e6f6f2e400ada3836da844553d8bc21c64122242a212502ccf5f702 + languageName: node + linkType: hard + +"vscode-languageserver-types@npm:3.16.0": + version: 3.16.0 + resolution: "vscode-languageserver-types@npm:3.16.0" + checksum: 7a44fb10b9fbeb9529f832337b7f0430fc6275d62945b86851d425a950e22da3917ef5f6c552688191769dd1eae047c6ee9ec3d9f2280498353007c2dfe0725c + languageName: node + linkType: hard + +"vscode-languageserver@npm:^7.0.0": + version: 7.0.0 + resolution: "vscode-languageserver@npm:7.0.0" + dependencies: + vscode-languageserver-protocol: 3.16.0 + bin: + installServerIntoExtension: bin/installServerIntoExtension + checksum: 80cfbd5f8f0869c5369d1a61fe86b3210ee941cb646eb31b672045670ef3ce213dc1fd3bcd4cef6ef8bc7c5025f98e4a70dad645d97a0bd4708962bbd921683a + languageName: node + linkType: hard + +"vscode-uri@npm:^3.0.2": + version: 3.0.3 + resolution: "vscode-uri@npm:3.0.3" + checksum: 683bf9de835c3cef0b51c104a4949bf746148ded7c2287ebafcc506d20aa0e90b99385a972dba8132903420dba67fc33a5e146e30212c4a6b3ca5d74d1f95702 + languageName: node + linkType: hard + "vue-bundle-renderer@npm:^0.3.5": version: 0.3.5 resolution: "vue-bundle-renderer@npm:0.3.5"