5.0.8-beta.0 ā€¢ Published 4 years ago

@ravelin/fork-ts-checker-webpack-plugin v5.0.8-beta.0

Weekly downloads
1
License
MIT
Repository
github
Last release
4 years ago

npm version build status downloads commitizen friendly code style: prettier semantic-release

Features

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.
# 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)

// 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()]
};

If you are using TypeScript >= 3.8.0, it's recommended to set "importsNotUsedAsValues": "preserve" compiler option in the tsconfig.json. Here is an explanation.

You can find examples how to configure it with babel-loader, ts-loader, eslint and Visual Studio Code in the 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. For example if you set files: ['./src/index.ts'] in tsconfig.json, this plugin will check only index.ts for errors.

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:

# 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:

// 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:

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. 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).

NameTypeDefault valueDescription
asyncbooleancompiler.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.
typescriptobject or booleantrueIf a boolean, it enables/disables TypeScript checker. If an object, see TypeScript options.
eslintobjectundefinedIf undefined, it disables ESLint linter. If an object, see ESLint options.
issueobject{}See Issues options.
formatterstring or objectcodeframeAvailable formatters are basic and codeframe. To configure codeframe formatter, pass object: { type: 'codeframe', options: { <coderame options> } }.
loggerobject{ infrastructure: 'silent', issues: 'console' }Available loggers are silent, console, and webpack-infrastructure. Infrastructure logger prints additional information, issue logger prints issues in the async mode.

TypeScript options

Options for the TypeScript checker (typescript option object).

NameTypeDefault valueDescription
enabledbooleantrueIf true, it enables TypeScript checker.
memoryLimitnumber2048Memory limit for the checker process in MB. If the process exits with the allocation failed error, try to increase this number.
configFilestring'tsconfig.json'Path to the tsconfig.json file (path relative to the compiler.options.context or absolute path)
configOverwriteobject{ 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.
contextstringdirname(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.
buildbooleanfalseThe equivalent of the --build flag for the tsc command.
mode'readonly' or 'write-tsbuildinfo' 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.
diagnosticOptionsobject{ syntactic: false, semantic: true, declaration: false, global: false }Settings to select which diagnostics do we want to perform.
extensionsobject{}See TypeScript extensions options.
profilebooleanfalseMeasures and prints timings related to the TypeScript performance.

TypeScript extensions options

Options for the TypeScript checker extensions (typescript.extensions option object).

NameTypeDefault valueDescription
vueobject or booleanfalseIf true, it enables Vue Single File Component support.
vue.enabledbooleanfalseSame as the vue option
vue.compilerstring'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).

NameTypeDefault valueDescription
enabledbooleanfalseIf true, it enables ESLint linter. If you set the files option, it will be true by default.
filesstring or string[]This value is requiredOne or more glob patterns to the files that should be linted. Works the same as the eslint command.
memoryLimitnumber2048Memory limit for the linter process in MB. If the process exits with the allocation failed error, try to increase this number.
optionsobject{}Options that can be used to initialize ESLint.

Issues options

Options for the issues filtering (issues option object).

NameTypeDefault valueDescription
includeobject or function or arrayundefinedIf object, defines issue properties that should be matched. If function, acts as a predicate where issue is an argument.
excludeobject or function or arrayundefinedSame as include but issues that match this predicate will be excluded.
scope'all' or 'webpack''webpack'Defines issues scope to be reported. If 'webpack', reports errors only related to the webpack compilation. Reports all errors otherwise (like tsc and eslint command).

Vue.js

āš ļø There are additional constraints regarding Vue.js Single File Component support: āš ļø

  • It requires TypeScript >= 3.8.0 and "importsNotUsedAsValues": "preserve" option in the tsconfig.json (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:

  1. Ensure you have all required packages installed:
# 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 
  1. Add tsconfig.json configuration:
{
  "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"
  ]
}
  1. Add webpack.config.js configuration:
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
        }
      }
    })
  ]
};
  1. Add src/types/vue.d.ts file to shim .vue modules:
declare module "*.vue" {
  import Vue from "vue";
  export default Vue;
}
  1. If you are working in VSCode, you can get the Vetur extension to complete the developer workflow.

Type-Only modules watching

At present there is an issue with the transpileOnly mode regarding the triggering of type-checking when a change is made in a source file that will not emit js. If you have a file that contains only interfaces and/or types then, by default, changes to it will not trigger the type checker whilst in watch mode.

If you use TypeScript >=3.8.0, you can fix it by passing "importsNotUsedAsValues": "preserve" option to the compiler options in the tsconfig.json.

Plugin hooks

This plugin provides some custom webpack hooks:

Hook keyTypeParamsDescription
startAsyncSeriesWaterfallHookchange, compilationStarts 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.
waitingSyncHookcompilationWaiting for the issues checking.
canceledSyncHookcompilationIssues checking for the compilation has been canceled.
errorSyncHookcompilationAn error occurred during issues checking.
issuesSyncWaterfallHookissues, compilationIssues 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.

const webpack = require('webpack');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

const compiler = webpack({
  // ... webpack config
});

// optionally add the plugin to the compiler
// **don't do this if already added through configuration**
new ForkTsCheckerWebpackPlugin().apply(compiler);

// now get the plugin hooks from compiler
const hooks = ForkTsCheckerWebpackPlugin.getCompilerHooks(compiler);

// say we want to show some message when plugin is waiting for issues results
hooks.waiting.tap('yourListenerName', () => {
  console.log('waiting for issues');
});

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 šŸ˜‰

# with npm
npm install --save-dev @types/webpack

# with yarn
yarn add --dev @types/webpack

Related projects

Credits

This plugin was created in Realytics in 2017. Thank you for supporting Open Source.

License

MIT License