Skip to content

Commit

Permalink
feat: add zero-config support for fork-ts-checker-webpack-plugin (#1451)
Browse files Browse the repository at this point in the history
* feat: add zero-config support for fork-ts-checker-webpack-plugin

* docs: update links to fork-ts-checker-webpack-plugin

* docs: update examples for fork-ts-checker-webpack-plugin

* docs: update README.md

* chore: minor bump of ts-loader version

* chore: update CHANGELOG.md

* docs: self review of README.md
  • Loading branch information
piotr-oles committed Apr 30, 2022
1 parent 4e00201 commit b943237
Show file tree
Hide file tree
Showing 16 changed files with 2,426 additions and 4,012 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog

## v9.3.0

* [simplify configuration for fork-ts-checker-webpack-plugin](https://github.com/TypeStrong/ts-loader/pull/1451) - thanks @piotr-oles

## v9.2.9

* [make v9 latest following v8 release](https://github.com/TypeStrong/ts-loader/pull/1447) - thanks @johnnyreilly
Expand Down
16 changes: 10 additions & 6 deletions README.md
Expand Up @@ -111,15 +111,17 @@ We have a number of example setups to accommodate different workflows. Our examp
We probably have more examples than we need. That said, here's a good way to get started:

- I want the simplest setup going. Use "[vanilla](examples/vanilla)" `ts-loader`
- I want the fastest compilation that's available. Use [fork-ts-checker-webpack-plugin](https://github.com/Realytics/fork-ts-checker-webpack-plugin). It performs type checking in a separate process with `ts-loader` just handling transpilation.
- I want the fastest compilation that's available. Use [fork-ts-checker-webpack-plugin](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin). It performs type checking in a separate process with `ts-loader` just handling transpilation.

### Faster Builds

As your project becomes bigger, compilation time increases linearly. It's because typescript's semantic checker has to inspect all files on every rebuild. The simple solution is to disable it by using the `transpileOnly: true` option, but doing so leaves you without type checking and *will not output declaration files*.
As your project becomes bigger, compilation time increases linearly. It's because typescript's semantic checker has to inspect all files on every rebuild.
The simple solution is to disable it by using the `transpileOnly: true` option, but doing so leaves you without type checking and *will not output declaration files*.

You probably don't want to give up type checking; that's rather the point of TypeScript. So what you can do is use the [fork-ts-checker-webpack-plugin](https://github.com/Realytics/fork-ts-checker-webpack-plugin). It runs the type checker on a separate process, so your build remains fast thanks to `transpileOnly: true` but you still have the type checking. Also, the plugin has several optimizations to make incremental type checking faster (AST cache, multiple workers).
You probably don't want to give up type checking; that's rather the point of TypeScript. So what you can do is use the [fork-ts-checker-webpack-plugin](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin).
It runs the type checker on a separate process, so your build remains fast thanks to `transpileOnly: true` but you still have the type checking.

If you'd like to see a simple setup take a look at [our simple example](examples/fork-ts-checker-webpack-plugin/). For a more complex setup take a look at our [more involved example](examples/react-babel-karma-gulp).
If you'd like to see a simple setup take a look at [our example](examples/fork-ts-checker-webpack-plugin/).

### Yarn Plug’n’Play

Expand Down Expand Up @@ -280,7 +282,9 @@ module.exports = {
If you want to speed up compilation significantly you can set this flag.
However, many of the benefits you get from static type checking between different dependencies in your application will be lost. `transpileOnly` will *not* speed up compilation of project references.

It's advisable to use `transpileOnly` alongside the [fork-ts-checker-webpack-plugin](https://github.com/Realytics/fork-ts-checker-webpack-plugin) to get full type checking again. To see what this looks like in practice then either take a look at [our simple example](examples/fork-ts-checker-webpack-plugin). For a more complex setup take a look at our [more involved example](examples/react-babel-karma-gulp).
It's advisable to use `transpileOnly` alongside the [fork-ts-checker-webpack-plugin](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin) to get full type checking again. To see what this looks like in practice then either take a look at [our example](examples/fork-ts-checker-webpack-plugin).

> Tip: When you add the [fork-ts-checker-webpack-plugin](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin) to your webpack config, the `transpileOnly` will default to `true`, so you can skip that option.
If you enable this option, webpack 4 will give you "export not found" warnings any time you re-export a type:

Expand Down Expand Up @@ -309,7 +313,7 @@ module.exports = {

If you're using [HappyPack](https://github.com/amireh/happypack) or [thread-loader](https://github.com/webpack-contrib/thread-loader) to parallelise your builds then you'll need to set this to `true`. This implicitly sets `*transpileOnly*` to `true` and **WARNING!** stops registering **_all_** errors to webpack.

It's advisable to use this with the [fork-ts-checker-webpack-plugin](https://github.com/Realytics/fork-ts-checker-webpack-plugin) to get full type checking again. **_IMPORTANT_**: If you are using fork-ts-checker-webpack-plugin alongside HappyPack or thread-loader then ensure you set the `syntactic` diagnostic option like so:
It's advisable to use this with the [fork-ts-checker-webpack-plugin](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin) to get full type checking again. **_IMPORTANT_**: If you are using fork-ts-checker-webpack-plugin alongside HappyPack or thread-loader then ensure you set the `syntactic` diagnostic option like so:

```javascript
new ForkTsCheckerWebpackPlugin({
Expand Down
65 changes: 9 additions & 56 deletions examples/fork-ts-checker-webpack-plugin/.eslintrc.js
@@ -1,60 +1,13 @@
// Useful references:
// https://www.npmjs.com/package/eslint-config-react-app
// https://github.com/facebook/create-react-app/blob/master/packages/eslint-config-react-app/index.js
// https://medium.com/@dors718/linting-your-react-typescript-project-with-eslint-and-prettier-2423170c3d42
// https://typescript-eslint.io/

const path = require('path');
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
plugins: [
'@typescript-eslint',
'react'
// 'prettier' commented as we don't want to run performance hog prettier through eslint as it's slow
],
env: {
browser: true,
jest: true
},
extends: [
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
// 'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
'prettier/react', // disables react-specific linting rules that conflict with prettier
// 'plugin:prettier/recommended' // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
],
parserOptions: {
project: path.resolve(__dirname, './tsconfig.json'),
tsconfigRootDir: __dirname,
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
ecmaFeatures: {
jsx: true // Allows for the parsing of JSX
}
},
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",
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-unused-vars': 'off',

// These rules don't add much value, are better covered by TypeScript and good definition files
'react/no-direct-mutation-state': 'off',
'react/no-deprecated': 'off',
'react/no-string-refs': 'off',
'react/require-render-return': 'off',

// we want to check ".tsx" files
'react/jsx-filename-extension': [
'warn',
{
extensions: ['.jsx', '.tsx']
}
],
'react/prop-types': 'off' // Is this incompatible with TS props type?
},
settings: {
react: {
version: 'detect' // Tells eslint-plugin-react to automatically detect the version of React to use
}
}
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
};
2 changes: 2 additions & 0 deletions examples/fork-ts-checker-webpack-plugin/.gitignore
@@ -0,0 +1,2 @@
/dist
/node_modules
7 changes: 0 additions & 7 deletions examples/fork-ts-checker-webpack-plugin/.prettierrc.js

This file was deleted.

58 changes: 24 additions & 34 deletions examples/fork-ts-checker-webpack-plugin/package.json
@@ -1,46 +1,36 @@
{
"name": "fork-ts-checker-webpack-plugin",
"version": "1.0.0",
"main": "index.js",
"main": "dist/main.js",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --progress --color --mode development --config webpack.config.development.js",
"start": "webpack serve --mode=development",
"prebuild": "rimraf ./dist/*",
"build": "webpack --color --mode production --config webpack.config.production.js",
"lint": "eslint ./",
"lint-rule-timings": "cross-env TIMING=1 yarn lint"
"build": "webpack --mode=production",
"lint": "eslint ./src"
},
"devDependencies": {
"@types/jest": "^24.0.0",
"@types/react": "^16.8.0",
"@types/react-dom": "^16.8.0",
"@types/react-router": "^5.0.0",
"@types/react-router-dom": "^4.0.5",
"@types/react-test-renderer": "^16.8.0",
"@types/react-transition-group": "^2.0.2",
"@typescript-eslint/eslint-plugin": "^1.11.0",
"@typescript-eslint/parser": "^1.11.0",
"cross-env": "^5.2.0",
"eslint": "^6.0.1",
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-react": "^7.14.2",
"fork-ts-checker-notifier-webpack-plugin": "^1.0.0",
"fork-ts-checker-webpack-plugin": "^1.4.0",
"html-webpack-plugin": "next",
"prettier": "1.18.2",
"rimraf": "^2.6.1",
"ts-loader": "^6.0.0",
"tslib": "^1.7.1",
"typescript": "^3.0.0",
"webpack": "^4.0.0",
"webpack-cli": "^3.0.0",
"webpack-dev-server": "^3.0.0"
"@types/react": "^18.0.8",
"@types/react-dom": "^18.0.3",
"@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0",
"eslint": "^8.14.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-react": "^7.29.4",
"fork-ts-checker-notifier-webpack-plugin": "^6.0.0",
"fork-ts-checker-webpack-plugin": "^7.2.8",
"html-webpack-plugin": "^5.5.0",
"prettier": "2.6.2",
"rimraf": "^3.0.2",
"ts-loader": "^9.2.9",
"tslib": "^2.4.0",
"typescript": "^4.6.4",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.8.1"
},
"dependencies": {
"core-js": "^3.0.0",
"react": "^16.8.0",
"react-dom": "^16.8.0",
"whatwg-fetch": "^3.0.0"
"react": "^18.1.0",
"react-dom": "^18.1.0"
}
}
8 changes: 4 additions & 4 deletions examples/fork-ts-checker-webpack-plugin/src/app.tsx
@@ -1,8 +1,8 @@
import * as React from 'react';
import { Layout } from './components/layout';

export const App: React.SFC = _props => (
<div className="ui container">
<Layout />
</div>
export const App: React.FC = () => (
<div className="ui container">
<Layout />
</div>
);
@@ -1,3 +1,3 @@
import * as React from 'react';

export const Layout: React.SFC = _props => <h1>Heya, heya, heya!!</h1>;
export const Layout: React.FC = () => <h1>Heya, heya, heya!!</h1>;
23 changes: 5 additions & 18 deletions examples/fork-ts-checker-webpack-plugin/tsconfig.json
@@ -1,26 +1,13 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": false,
"target": "es5",
"downlevelIteration": true,
"importHelpers": true,
"sourceMap": true,
"lib": ["es6", "dom"],
"module": "esnext",
"moduleResolution": "node",
"jsx": "react",
"allowJs": false,
"checkJs": false,
"lib": ["dom", "es2015", "es2016", "es2017", "esnext"],
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true,
"noImplicitAny": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"skipLibCheck": true,
"strictNullChecks": false,
"suppressImplicitAnyIndexErrors": true,
"types": ["jest"]
"sourceMap": true,
"strict": true,
"importHelpers": true,
"skipLibCheck": true
}
}

This file was deleted.

37 changes: 37 additions & 0 deletions examples/fork-ts-checker-webpack-plugin/webpack.config.js
@@ -0,0 +1,37 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const ForkTsCheckerNotifierWebpackPlugin = require('fork-ts-checker-notifier-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
context: __dirname, // to automatically find tsconfig.json
entry: {
main: './src/index.tsx',
},
output: {
path: path.resolve(__dirname, 'dist'),
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
module: {
rules: [
{
test: /.tsx?$/,
loader: 'ts-loader',
},
],
},
plugins: [
new ForkTsCheckerWebpackPlugin(),
new ForkTsCheckerNotifierWebpackPlugin({
title: 'TypeScript',
excludeWarnings: false,
}),
new HtmlWebpackPlugin({
inject: true,
template: 'src/index.html',
}),
],
};

0 comments on commit b943237

Please sign in to comment.