From e63aa9b3f43dd0f3babc0751a815d4c31e992d33 Mon Sep 17 00:00:00 2001 From: Swashata Ghosh Date: Thu, 18 Apr 2019 12:34:59 +0530 Subject: [PATCH] feat(scripts): improve typechecking performance Explicitly add some options in project config so that it can be improved from userland. See #447 --- examples/plugin/src/ts/main.ts | 2 + examples/plugin/wpackio.project.js | 5 ++ packages/scripts/src/bin/utils.ts | 4 ++ .../scripts/src/config/WebpackConfigHelper.ts | 10 +++- .../src/config/project.config.default.ts | 2 + site/docs/apis/project-configuration.md | 38 ++++++++++++-- site/docs/tutorials/adding-typescript.md | 52 +++++++++++++++++++ 7 files changed, 109 insertions(+), 4 deletions(-) diff --git a/examples/plugin/src/ts/main.ts b/examples/plugin/src/ts/main.ts index 958b2f13a..e81a0852f 100644 --- a/examples/plugin/src/ts/main.ts +++ b/examples/plugin/src/ts/main.ts @@ -7,6 +7,8 @@ console.log('Hello from typescript, I am gonna say foo 30 times'); console.log(strRepeat('foo', 10)); console.log(strRepeat('foo', 10)); console.log(strRepeat('foo', 10)); +console.log(strRepeat('10', 20)); +console.log(strRepeat('[]', 20)); if (module.hot) { module.hot.accept('./module.ts', () => { diff --git a/examples/plugin/wpackio.project.js b/examples/plugin/wpackio.project.js index 9d38c7b39..1de44cae7 100644 --- a/examples/plugin/wpackio.project.js +++ b/examples/plugin/wpackio.project.js @@ -35,6 +35,7 @@ module.exports = { main: ['./src/app/index.js'], mobile: ['./src/app/mobile.js'], }, + hasTypeScript: false, // Extra webpack config to be passed directly webpackConfig: (config, merge, appDir, isDev) => { const svgoLoader = { @@ -98,6 +99,7 @@ module.exports = { entry: { main: ['./src/foo/foo.js'], }, + hasTypeScript: false, // Extra webpack config to be passed directly webpackConfig: undefined, }, @@ -108,6 +110,7 @@ module.exports = { entry: { main: ['./src/reactapp/index.jsx'], }, + hasTypeScript: false, webpackConfig: (config, merge, appDir, isDev) => { const customRules = { module: { @@ -168,6 +171,8 @@ module.exports = { }, { name: 'tsapp', + // hasTypeScript: true, + typeWatchFiles: ['src/ts/*.{ts,tsx}', 'src/ts/**/*.{ts,tsx}'], entry: { main: ['./src/ts/main.ts'], }, diff --git a/packages/scripts/src/bin/utils.ts b/packages/scripts/src/bin/utils.ts index 2d162206b..59d13aa3d 100644 --- a/packages/scripts/src/bin/utils.ts +++ b/packages/scripts/src/bin/utils.ts @@ -71,6 +71,10 @@ export function printFailedCompileMEssage() { ); } +export function printGeneralInfoMessage(msg: string) { + console.info(addTimeStampToLog(`${logSymbols.info} ${msg}`)); +} + export const bulletSymbol = chalk.magenta(figures.pointer); export const wpackLogoSmall = gradient.instagram('wpack.io'); diff --git a/packages/scripts/src/config/WebpackConfigHelper.ts b/packages/scripts/src/config/WebpackConfigHelper.ts index ed080de01..909400ed5 100644 --- a/packages/scripts/src/config/WebpackConfigHelper.ts +++ b/packages/scripts/src/config/WebpackConfigHelper.ts @@ -22,6 +22,7 @@ import { } from './project.config.default'; import { ServerConfig } from './server.config.default'; import { getFileLoaderForJsAndStyleAssets } from './fileLoader'; +import { printGeneralInfoMessage } from '../bin/utils'; interface NormalizedEntry { [x: string]: string[]; @@ -282,7 +283,10 @@ export class WebpackConfigHelper { ]; // Add ts checker plugin if project has tsconfig.json const tsconfigPath = path.resolve(this.cwd, './tsconfig.json'); - if (this.fileExists(tsconfigPath)) { + if ( + this.fileExists(tsconfigPath) && + this.file.hasTypeScript !== false + ) { // dynamic require forktschecker otherwise it will throw error try { // eslint-disable-next-line import/no-extraneous-dependencies, global-require, @typescript-eslint/no-var-requires @@ -297,6 +301,10 @@ export class WebpackConfigHelper { formatterOptions: { highlightCode: true, }, + useTypescriptIncrementalApi: false, + reportFiles: this.file.typeWatchFiles + ? this.file.typeWatchFiles + : [], }) ); } catch (e) { diff --git a/packages/scripts/src/config/project.config.default.ts b/packages/scripts/src/config/project.config.default.ts index 46066756b..35a003c72 100644 --- a/packages/scripts/src/config/project.config.default.ts +++ b/packages/scripts/src/config/project.config.default.ts @@ -31,6 +31,8 @@ export interface EntryConfig { export interface FileConfig { name: string; entry: EntryConfig; + typeWatchFiles?: string[]; + hasTypeScript?: boolean; webpackConfig?: | webpack.Configuration | (( diff --git a/site/docs/apis/project-configuration.md b/site/docs/apis/project-configuration.md index 30227a686..46ec619f8 100644 --- a/site/docs/apis/project-configuration.md +++ b/site/docs/apis/project-configuration.md @@ -184,15 +184,37 @@ under `entry`, then also (if needed) chunk-splitting will be applied. If we were to pass multiple file object, then webpack would run in [multi-compiler](https://webpack.js.org/api/node/#multicompiler) mode, separating dependency tree from each of the file object. -Each file object has three properties: +Each file object has two required and three optional properties. Here's the +interface. -#### `name` (`string`): +```ts +interface EntryConfig { + [x: string]: string[] | string; +} + +interface FileConfig { + name: string; + entry: EntryConfig; + typeWatchFiles?: string[]; + hasTypeScript?: boolean; + webpackConfig?: + | webpack.Configuration + | (( + config: webpack.Configuration, + api: merge, + appDir: string, + isDev: boolean + ) => webpack.Configuration); +} +``` + +#### `name` (`string`) **required**: A unique name of this file entry. If you are using more than one file entry, then make sure to give different names, otherwise the compiler might not work in development mode. -#### `entry` (`object`): +#### `entry` (`object`) **required**: This is the path (relative to project root) of files you would like to compile. @@ -245,6 +267,16 @@ Directory inside `outputPath` where all the assets are to be emitted. Whether the operation is going for development mode or production build. +#### `typeWatchFiles` (`string[]`) + +Array of glob pattern for which typescript reports are to be notified. + +#### `hasTypeScript` (`boolean` | `undefined`) + +Explicitly disable typescript type assertions. + +> More information about typescript related options can be found [here](/tutorials/adding-typescript/). + ## `outputPath` (`string`): Name of the directory (relative) where we would put the bundled and manifest diff --git a/site/docs/tutorials/adding-typescript.md b/site/docs/tutorials/adding-typescript.md index 7949c45c4..f0388da67 100644 --- a/site/docs/tutorials/adding-typescript.md +++ b/site/docs/tutorials/adding-typescript.md @@ -83,3 +83,55 @@ Now you are good to go. The compiler will also show any `ts` error you might hav > **NOTE** - Internally wpack.io depends on [`fork-ts-checker-webpack-plugin`](https://github.com/Realytics/fork-ts-checker-webpack-plugin) > to show type errors during build time. So make sure you install it, otherwise > it will not work. + +## Optimization + +By default `@wpackio/scripts` will create an instance of `fork-ts-checker-webpack-plugin` +if a `tsconfig.json` is found in the current project root. + +The same plugin would go into all multi-entry compiler instances and would enable +typechecking for all entries. + +Sometimes, this could not be the desired feature. For instance, you might have +a plain JS app, alongside a TS app and you don't want the typechecker for the JS +app. Luckily it is not possible to explicitly disable typechecking for individual +file entry using `hasTypeScript`. + +Furthermore, due to the nature of TypeScript, you might notice duplicate error +reports across multiple files entry. This can also be remedied using `typeWatchFiles` +config variable. + +Under your [`FileConfig`](/apis/project-configuration/#files-array) add the +`hasTypeScript` option. Below is an example of two apps, one explicitly disabling +the typecheck. + +**wpackio.project.js** + +```js +module.exports = { + // ... + files: [ + // Only JavaScript App + { + name: 'jsapp', + entry: { + main: './src/jsapp/index.js', + }, + // disable typechecking for this + hasTypeScript: false, + }, + // TypeScript App + { + name: 'tsapp', + entry: { + main: './src/tsapp/index.ts', + }, + // (optional) enable typechecking for this + hasTypeScript: true, + // (optional but recommended) mention files to report + // through glob pattern + typeWatchFiles: ['src/tsapp/*.{ts,tsx}', 'src/tsapp/**/*.{ts,tsx}'], + }, + ], +}; +```