rOACCT/node_modules/fork-ts-checker-webpack-plugin49c99f97fe9aissn4frontend
fork-ts-checker-webpack-plugin
README.md
<div align="center">
<h1>Fork TS Checker Webpack Plugin</h1> <p>Webpack plugin that runs TypeScript type checker on a separate process.</p>
![npm version](https://www.npmjs.com/package/fork-ts-checker-webpack-plugin) ![build status](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/actions?query=branch%3Amain+event%3Apush) ![downloads](https://npmjs.org/package/fork-ts-checker-webpack-plugin) ![commitizen friendly](http://commitizen.github.io/cz-cli/) ![code style: prettier](https://github.com/prettier/prettier) ![semantic-release](https://github.com/semantic-release/semantic-release)
</div>
- Features
- Speeds up TypeScript type checking and ESLint linting (by moving each to a separate process) ๐
- Supports modern TypeScript features like project references and incremental mode โจ
- Supports Vue Single File Component โ ย
- Displays nice error messages with the code frame formatter ๐
Installation
This plugin requires minimum Node.js 10, Webpack 4, TypeScript 2.7 and optionally ESLint 6
- If you depend on Webpack 2, Webpack 3, or TSLint 4, please use version 3 of the plugin.
- If you depend on TypeScript >= 2.1 and < 2.7 or you can't update to Node 10, please use version 4 of the plugin.
sh # with npm npm install --save-dev fork-ts-checker-webpack-plugin # with yarn yarn add --dev fork-ts-checker-webpack-plugin
The minimal webpack config (with ts-loader)
js // webpack.config.js const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); module.exports = { context: __dirname, // to automatically find tsconfig.json entry: './src/index.ts', resolve: { extensions: [".ts", ".tsx", ".js"], }, module: { rules: [ { test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/, options: { // disable type checker - we will use it in fork plugin transpileOnly: true } } ] }, plugins: [new ForkTsCheckerWebpackPlugin()] };
Examples how to configure it with babel-loader, ts-loader, eslint and Visual Studio Code are in the [examples](./examples) directory.
Modules resolution
It's very important to be aware that this plugin uses TypeScript's, not webpack's modules resolution. It means that you have to setup tsconfig.json correctly.
It's because of the performance - with TypeScript's module resolution we don't have to wait for webpack to compile files.
To debug TypeScript's modules resolution, you can use tsc --traceResolution command.
ESLint
If you'd like to use ESLint with the plugin, ensure you have the relevant dependencies installed:
sh # with npm npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin # with yarn yarn add --dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
Then set up ESLint in the plugin. This is the minimal configuration:
js // webpack.config.js const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); module.exports = { // ...the webpack configuration plugins: [ new ForkTsCheckerWebpackPlugin({ eslint: { files: './src/**/*.{ts,tsx,js,jsx}' // required - same as command `eslint ./src/**/*.{ts,tsx,js,jsx} --ext .ts,.tsx,.js,.jsx` } }) ] };
You should also have an ESLint configuration file in your root project directory. Here is a sample .eslintrc.js configuration for a TypeScript project:
js module.exports = { parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 2018, sourceType: 'module', }, extends: [ 'plugin:@typescript-eslint/recommended' ], rules: { // place to specify ESLint rules - can be used to overwrite rules specified from the extended configs // e.g. "@typescript-eslint/explicit-function-return-type": "off", } };
There's a good explanation on setting up TypeScript ESLint support by Robert Cooper.
Options
This plugin uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig). This means that besides the plugin constructor, you can place your configuration in the:
- "fork-ts-checker" field in the package.json
- .fork-ts-checkerrc file in JSON or YAML format
- fork-ts-checker.config.js file exporting a JS object
Options passed to the plugin constructor will overwrite options from the cosmiconfig (using 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 or boolean | true | If a boolean, it enables/disables TypeScript checker. If an object, see [TypeScript options](#typescript-options). |
eslint | object | undefined | If undefined, it disables ESLint linter. If an object, see [ESLint options](#eslint-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 codeframe formatter, pass object: { type: 'codeframe', options: { <coderame options> } }. |
logger | object | { infrastructure: 'silent', issues: 'console', devServer: true } | Available loggers are silent, console, and webpack-infrastructure. Infrastructure logger prints additional information, issue logger prints issues in the async mode. If devServer is 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 |
---|---|---|---|
enabled | boolean | true | If true, it enables TypeScript checker. |
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. 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. |
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 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 | |
ESLint options
Options for the ESLint linter (eslint option object).
Name | Type | Default value | Description |
---|---|---|---|
enabled | boolean | false | If true, it enables ESLint linter. If you set the files option, it will be true by default. |
files | string or string[] | This value is required | One or more glob patterns to the files that should be linted. Works the same as the eslint command. |
memoryLimit | number | 2048 | Memory limit for the linter process in MB. If the process exits with the allocation failed error, try to increase this number. |
options | object | {} | Options that can be used to initialize ESLint. |
Issues options
Options for the issues filtering (issue option object). I could write some plain text explanation of these options but I think code will explain it better:
typescript interface Issue { origin: 'typescript' | 'eslint'; severity: 'error' | 'warning'; code: string; file?: string; } type IssueMatch = Partial<Issue>; // file field supports glob matching type IssuePredicate = (issue: Issue) => boolean; type IssueFilter = IssueMatch | IssuePredicate | (IssueMatch | IssuePredicate)[];
Name | Type | Default value | Description |
---|---|---|---|
include | IssueFilter | undefined | If object, defines issue properties that should be [matched](./src/issue/IssueMatch.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. |
<details> <summary>Expand example</summary>
Include issues from the src directory, exclude eslint issues from .spec.ts files:
js module.exports = { // ...the webpack configuration plugins: [ new ForkTsCheckerWebpackPlugin({ issue: { include: [ { file: '**/src/**/*' } ], exclude: [ { origin: 'eslint', file: '**/*.spec.ts' } ] } }) ] };
</details>
Vue.js
โ ๏ธ There are additional constraints regarding Vue.js Single File Component support: โ ๏ธ
- It requires TypeScript >= 3.8.0 (it's a limitation of the transpileOnly mode from ts-loader)
- It doesn't work with the build mode (project references)
To enable Vue.js support, follow these steps:
<details> <summary>Expand Vue.js set up instruction</summary>
- Ensure you have all required packages installed:
sh # with npm npm install --save vue vue-class-component npm install --save-dev vue-loader ts-loader css-loader vue-template-compiler # with yarn yarn add vue vue-class-component yarn add --dev vue-loader ts-loader css-loader vue-template-compiler
- Add tsconfig.json configuration:
json { "compilerOptions": { "experimentalDecorators": true, "jsx": "preserve", "target": "ES5", "lib": ["ES6", "DOM"], "baseUrl": ".", "paths": { "@/*": ["src/*"], "~/*": ["src/*"] }, "sourceMap": true, "importsNotUsedAsValues": "preserve" }, "include": [ "src/**/*.ts", "src/**/*.vue" ], "exclude": [ "node_modules" ] }
- Add webpack.config.js configuration:
js const path = require('path'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); module.exports = { entry: './src/index.ts', output: { filename: 'index.js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader' }, { test: /\.ts$/, loader: 'ts-loader', exclude: /node_modules/, options: { appendTsSuffixTo: [/\.vue$/], transpileOnly: true } }, { test: /\.css$/, loader: 'css-loader' }, ], }, resolve: { extensions: ['.ts', '.js', '.vue', '.json'], alias: { '@': path.resolve(__dirname, './src'), '~': path.resolve(__dirname, './src'), } }, plugins: [ new VueLoaderPlugin(), new ForkTsCheckerWebpackPlugin({ typescript: { extensions: { vue: true } } }) ] };
- Add src/types/vue.d.ts file to shim .vue modules:
typescript declare module "*.vue" { import Vue from "vue"; export default Vue; }
- If you are working in VSCode, you can get the Vetur extension to complete the developer workflow.
</details>
Plugin hooks
This plugin provides some custom webpack hooks:
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. |
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, it returns the object with tapable hooks where you can pass in your callbacks.
js // ./src/webpack/MyWebpackPlugin.js const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); class MyWebpackPlugin { apply(compiler) { const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler); // log some message on waiting hooks.waiting.tap('MyPlugin', () => { console.log('waiting for issues'); }); // don't show warnings hooks.issues.tap('MyPlugin', (issues) => issues.filter((issue) => issue.severity === 'error') ); } } module.exports = MyWebpackPlugin; // webpack.config.js const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const MyWebpackPlugin = require('./src/webpack/MyWebpackPlugin'); module.exports = { /* ... */ plugins: [ new ForkTsCheckerWebpackPlugin(), new MyWebpackPlugin() ] };
Typings
To use the plugin typings, you have to install @types/webpack. It's not included by default to not collide with your existing typings (@types/webpack imports @types/node). It's an old TypeScript issue, the alternative is to set skipLibCheck: true in the compilerOptions ๐
sh # with npm npm install --save-dev @types/webpack # with yarn yarn add --dev @types/webpack
Profiling types resolution
Starting from TypeScript 4.1.0, you can profile long type checks by setting "generateTrace" compiler option. This is an instruction from microsoft/TypeScript#40063:
- Set "generateTrace": "{folderName}" in your tsconfig.json
- Look in the resulting folder. If you used build mode, there will be a legend.json telling you what went where. Otherwise, there will be trace.json file and types.json files.
- Navigate to [edge://tracing](edge://tracing) or [chrome://tracing](chrome://tracing) and load trace.json
- Expand Process 1 with the little triangle in the left sidebar
- Click on different blocks to see their payloads in the bottom pane
- Open types.json in an editor
- When you see a type ID in the tracing output, go-to-line {id} to find data about that type
- Related projects
- [ts-loader](https://github.com/TypeStrong/ts-loader) - TypeScript loader for webpack.
- [babel-loader](https://github.com/babel/babel-loader) - Alternative TypeScript loader for webpack.
- [fork-ts-checker-notifier-webpack-plugin](https://github.com/johnnyreilly/fork-ts-checker-notifier-webpack-plugin) - Notifies about build status using system notifications (similar to the webpack-notifier).
Credits
This plugin was created in Realytics in 2017. Thank you for supporting Open Source.
License
MIT License