Rspack plugin that runs TypeScript type checker on a separate process.
This plugin is forked from TypeStrong/fork-ts-checker-webpack-plugin, which is created by Piotr Oleś. See the original project's LICENSE.
Big thanks to fork-ts-checker-webpack-plugin
creators and contributors for their great work. ❤️
- Speeds up TypeScript type checking (by moving it to a separate process) 🏎
- Supports modern TypeScript features like project references and incremental mode ✨
- Displays nice error messages with the code frame formatter 🌈
💡 For Rsbuild projects, use @rsbuild/plugin-type-check to get out-of-the-box experience.
This plugin requires Node.js >=16.0.0+, Rspack ^1.0.0, TypeScript ^3.8.0
# with npm
npm install -D ts-checker-rspack-plugin
# with yarn
yarn add -D ts-checker-rspack-plugin
# with pnpm
pnpm add -D ts-checker-rspack-plugin
The minimal Rspack config with builtin:swc-loader.
// rspack.config.js
const { TsCheckerRspackPlugin } = require('ts-checker-rspack-plugin');
module.exports = {
context: __dirname, // to automatically find tsconfig.json
entry: './src/index.ts',
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: 'typescript',
},
},
},
},
],
},
plugins: [new TsCheckerRspackPlugin()],
watchOptions: {
// for some systems, watching many files can result in a lot of CPU or memory usage
// https://rspack.dev/config/watch#watchoptionsignored
// don't use this pattern, if you have a monorepo with linked packages
ignored: /node_modules/,
},
};
It's very important to be aware that this plugin uses TypeScript's, not
Rspack'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 Rspack to compile files.
To debug TypeScript's modules resolution, you can use
tsc --traceResolution
command.
Name | Type | Default value | Description |
---|---|---|---|
async |
boolean |
compiler.options.mode === 'development' |
If true , reports issues after Rspack's compilation is done. Thanks to that it doesn't block the compilation. Used only in the watch mode. |
typescript |
object |
{} |
See TypeScript 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: { type: 'codeframe', options: { <coderame options> } } . To use absolute file path, pass: { type: 'codeframe', pathType: 'absolute' } . |
logger |
{ log: function, error: function } or webpack-infrastructure |
console |
Console-like object to print issues in async mode. |
devServer |
boolean |
true |
If set to false , errors will not be reported to Dev Server. |
Options for the TypeScript checker (typescript
option object).
Name | Type | Default value | Description |
---|---|---|---|
memoryLimit |
number |
8192 |
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 ts-checker-rspack-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. |
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 issues filtering (issue
option object).
I could write some plain text explanation of these options but I think code will explain it better:
interface Issue {
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. 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. |
Expand example
Include issues from the src
directory, exclude issues from .spec.ts
files:
module.exports = {
// ...the Rspack configuration
plugins: [
new TsCheckerRspackPlugin({
issue: {
include: [{ file: '**/src/**/*' }],
exclude: [{ file: '**/*.spec.ts' }],
},
}),
],
};
This plugin provides some custom Rspack 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 Rspack compiler instance, it returns the object with
tapable hooks where you can pass in your callbacks.
// ./src/rspack/MyRspackPlugin.js
const { TsCheckerRspackPlugin } = require('ts-checker-rspack-plugin');
class MyRspackPlugin {
apply(compiler) {
const hooks = TsCheckerRspackPlugin.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 = MyRspackPlugin;
// rspack.config.js
const { TsCheckerRspackPlugin } = require('ts-checker-rspack-plugin');
const MyRspackPlugin = require('./src/rspack/MyRspackPlugin');
module.exports = {
/* ... */
plugins: [new TsCheckerRspackPlugin(), new MyRspackPlugin()],
};
When using TypeScript 4.3.0 or newer 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
(undercompilerOptions
) - Look in the resulting folder. If you used build mode, there will be a
legend.json
telling you what went where. Otherwise, there will betrace.json
file andtypes.json
files. - Navigate to edge://tracing or 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
You must both set "incremental": true in your tsconfig.json
(under compilerOptions
) and also specify mode: 'write-references' in TsCheckerRspackPlugin
settings.
MIT License