Webpack plugin that runs TypeScript type checker on a separate process.
[](https://www.npmjs.com/package/fork-ts-checker-webpack-plugin) [](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/actions?query=branch%3Amain+event%3Apush) [](https://npmjs.org/package/fork-ts-checker-webpack-plugin) [](http://commitizen.github.io/cz-cli/) [](https://github.com/prettier/prettier) [](https://github.com/semantic-release/semantic-release)This plugin requires minimum Node.js 10, Webpack 4, TypeScript 2.7 and optionally ESLint 6
npm install --save-dev fork-ts-checker-webpack-plugin
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 directory.
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.
If you'd like to use ESLint with the plugin, ensure you have the relevant dependencies installed:
```sh
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
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.
This plugin uses 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. |
| eslint
| object
| undefined
| If undefined
, it disables ESLint linter. If an object
, see ESLint options. |
| issue
| object
| {}
| See 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. |
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. |
| 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. |
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 |
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. |
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
| Name | Type | Default value | Description |
| --------- | ------------- | ------------- | ----------- |
| include
| IssueFilter
| undefined
| If object
, defines issue properties that should be matched. 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. |
⚠️ 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:
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() ] }; ```
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
npm install --save-dev @types/webpack
yarn add --dev @types/webpack ```
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:
tsconfig.json
legend.json
telling you what went where.
Otherwise, there will be trace.json
file and types.json
files.trace.json
types.json
in an editorts-loader
- TypeScript loader for webpack.babel-loader
- Alternative TypeScript loader for webpack.fork-ts-checker-notifier-webpack-plugin
- Notifies about build status using system notifications (similar to the webpack-notifier).This plugin was created in Realytics in 2017. Thank you for supporting Open Source.
MIT License