Fork-ts-checker-webpack-plugin: this.compiler.applyPluginsAsync( is not a function

Created on 8 Sep 2018  路  21Comments  路  Source: TypeStrong/fork-ts-checker-webpack-plugin

After upgrading to the following setup:

"webpack": "^4.17.2",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.8"

fork-ts-checker-webpack-plugin fails at line 354 in index.ts
TypeError: _this.compiler.applyPluginsAsync is not a function

It seems that the compiler object passed to the constructor has a different format.
Also, I previously have disabled fork-ts-checker-notifier-webpack-plugin because of an unrecognized hook. Namely:

Error: Plugin could not be registered at 'fork-ts-checker-receive'. Hook was not found.
BREAKING CHANGE: There need to exist a hook at 'this.hooks'. To create a compatiblity layer for this hook, hook into 'this._pluginCompat'.

I can create a separate issue in that plugins page if you find that best.

Below adding my webpack.development


const path = require("path");
const webpack = require("webpack");
// const ForkTsCheckerNotifierWebpackPlugin = require("fork-ts-checker-notifier-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');


const shared = require("./shared");
const main = [
    "react-hot-loader/patch",
    "webpack-dev-server/client?http://localhost:8080",
    "webpack/hot/only-dev-server",
    "core-js",
    "whatwg-fetch",
    "./src/index.tsx"
];
const vendor = shared.makeVendorEntry({ mainModules: main, modulesToExclude: ["semantic-ui-css"] })

module.exports = {
    context: process.cwd(), // to automatically find tsconfig.json
    devtool: "inline-source-map",
    entry: {
        main: main,
        vendor: vendor
    },
    mode: "development",
    output: {
        path: path.resolve(__dirname, "dist"),
        devtoolLineToLine: true,
        filename: "bundle.js",
        sourceMapFilename: "bundle.js.map",
        publicPath: "/",
        chunkFilename: '[name].chunk.js'
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        // new ForkTsCheckerNotifierWebpackPlugin({ title: "TypeScript", excludeWarnings: false }),
        new ForkTsCheckerWebpackPlugin({
            tslint: true,
            checkSyntacticErrors: true,
            watch: ["./src"] // optional but improves performance (fewer stat calls)
        }),
        new webpack.NoEmitOnErrorsPlugin(),
        new HtmlWebpackPlugin({
            inject: true,
            template: "public/index.html",
            favicon: 'public/favicon.ico'
        }),
        new CleanWebpackPlugin(['dist']),
        new ExtractTextPlugin({ filename: "[name].[contenthash].css", allChunks: true }),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
        }),
    ],
    module: {
        rules: [
            {
                test: /.tsx?$/,
                use: [
                    { loader: "ts-loader", options: { happyPackMode: true } }
                ],
                exclude: path.resolve(process.cwd(), "node_modules"),
                include: path.resolve(process.cwd(), "src"),
            },
            {
                test: /\.(s?)css$/,
                use: ExtractTextPlugin.extract({
                    fallback: "style-loader",
                    use: [
                        {
                            loader: "css-loader",
                            query: {
                                modules: true,
                                localIdentName: "[name]__[local]___[hash:base64:5]",
                                minimize: true,
                            },
                        },
                        {
                            loader: "resolve-url-loader" // resolves url for sass-loader
                        },
                        {
                            loader: "sass-loader" // compiles Sass to CSS
                        },
                    ]
                })
            },
            {
                test: /\.(png|jp(e*)g|svg)$/,  
                use: [{
                    loader: "url-loader",
                    options: { 
                        limit: 8000, // Convert images < 8kb to base64 strings
                        name: "images/[hash]-[name].[ext]"
                    }
                }]
            }
        ]
    },
    resolve: {
        extensions: [".tsx", ".ts", ".js"],
        plugins: [
            new TsconfigPathsPlugin({ configFile: "./tsconfig.json" })
        ]
    },
    devServer: {
        hot: true,
        historyApiFallback: true,
        stats: "errors-only"
    }
};

UPDATE
After upgrading both:

"fork-ts-checker-notifier-webpack-plugin": "^0.4.0",
"fork-ts-checker-webpack-plugin": "^0.4.9",

I get

compiler.hooks.forkTsCheckerReceive.tap(
   'fork-ts-checker-notifier-webpack-plugin',
    this.compilationDone.bind(this)
);

Most helpful comment

PR accepted. Closing issue

All 21 comments

Could you share a repo that illustrates this please? Also what were you upgrading from? You should only see that if you're using webpack 2/3 so it's a little peculiar. Could you debug your setup a little please?

The repos private _(not the owner)_, however, maybe you could specify what you'd like to see from the configuration? Also, I've updated the initial comment.

Added my package.json below

{
  "name": "hot-module-reloading",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "webpack-dev-server --progress --color --config webpack/webpack.config.development.js --watch -d",
    "docker": "webpack-dev-server  --progress --color --config webpack/webpack.config.development.js --host=0.0.0.0",
    "prebuild": "rimraf ./dist/*",
    "build": "NODE_ENV=production webpack --color --config webpack/webpack.config.production.js",
    "test:watch": "jest --watchAll",
    "test": "jest --ci --runInBand",
    "deploy": "./deploy.sh"
  },
  "jest": {
    "globals": {
      "ts-jest": {
        "skipBabel": true
      }
    },
    "transform": {
      "^.+\\.tsx?$": "ts-jest"
    },
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "./__mocks__/fileMock.js",
      "\\.(s?css)$": "identity-obj-proxy"
    },
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ],
    "setupFiles": [
      "./test/testSetup.ts"
    ]
  },
  "devDependencies": {
    "@types/axios": "^0.14.0",
    "@types/enzyme": "^3.1.10",
    "@types/jest": "^23.1.0",
    "@types/lodash": "^4.14.104",
    "@types/puppeteer": "^1.3.4",
    "@types/react": "^16.0.0",
    "@types/react-dom": "^16.0.0",
    "@types/react-hot-loader": "^3.0.4",
    "@types/react-redux": "^5.0.14",
    "@types/react-router": "^4.0.12",
    "@types/react-router-dom": "^4.0.5",
    "@types/react-test-renderer": "^16.0.0",
    "@types/react-transition-group": "^2.0.2",
    "@types/redux-thunk": "^2.1.0",
    "axios": "^0.17.1",
    "clean-webpack-plugin": "^0.1.19",
    "css-loader": "^0.28.8",
    "enzyme": "^3.3.0",
    "enzyme-adapter-react-16": "^1.1.1",
    "enzyme-to-json": "^3.3.4",
    "file-loader": "^1.1.6",
    "fork-ts-checker-notifier-webpack-plugin": "^0.4.0",
    "fork-ts-checker-webpack-plugin": "^0.4.9",
    "html-webpack-plugin": "^3.2.0",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^23.1.0",
    "jest-junit": "^3.1.0",
    "mini-css-extract-plugin": "^0.4.2",
    "node-sass": "^4.7.2",
    "puppeteer": "^1.5.0",
    "react": "^16.4.2",
    "react-dom": "^16.2.0",
    "react-hot-loader": "^3.0.0",
    "react-redux": "^5.0.6",
    "react-router-dom": "^4.2.2",
    "react-test-renderer": "^16.4.1",
    "redux-thunk": "^2.2.0",
    "resolve-url-loader": "^2.2.1",
    "rimraf": "^2.6.1",
    "sass-loader": "^6.0.6",
    "source-map-loader": "^0.2.1",
    "style-loader": "^0.19.1",
    "ts-jest": "^22.4.6",
    "ts-loader": "^5.0.0",
    "tsconfig-paths-webpack-plugin": "^3.2.0",
    "tslib": "^1.7.1",
    "tslint": "^5.5.0",
    "tslint-react": "^3.2.0",
    "typescript": "^2.9.2",
    "uglifyjs-webpack-plugin": "^1.1.8",
    "url-loader": "^0.6.2",
    "webpack": "^4.17.2",
    "webpack-cli": "^3.1.0",
    "webpack-dev-server": "^3.1.8"
  },
  "dependencies": {
    "core-js": "^2.4.1",
    "lodash": "^4.17.5",
    "react": "^16.0.0",
    "react-dom": "^16.0.0",
    "whatwg-fetch": "^2.0.3"
  }
}

The thing I'm curious about is the delta. What did you update?

Without knowing what your "before" state was it's hard to advise much. Too many possibilities; please narrow it down!

It looks like this test in pluginCompile() is no longer working to detect webpack 4:

if ('hooks' in this.compiler) {

It might be worth cleaning out your node_modules just in case you've something stale in there.

screen shot 2018-09-08 at 11 57 57
screen shot 2018-09-08 at 11 58 06
screen shot 2018-09-08 at 11 58 13

Cleaning node_modules didn't help.

By the looks of it your setup is similar to this: https://github.com/TypeStrong/ts-loader/tree/master/examples/core-js

Could be worth contrasting the webpack bits with your setup. FWIW the webpack 3->4 was quite significant; real breaking changes.

Yes, actually it was initially taken from this example.
Anyhow, used these libraries from your setup. Still receive the tap of undefined issue from ForkTsCheckerNotifierWebpackPlugin, index.js:99~

"fork-ts-checker-webpack-plugin": "^0.4.1",
"html-webpack-plugin": "^3.0.0",
"webpack": "^4.0.0",
"webpack-cli": "^2.0.12",
"webpack-dev-server": "^3.0.0"

So if you use that specific example do you experience the issue? If you do there's something wrong with the example. If not then there's something wrong with your replication of it.

Also are you using yarn or npm?

The example will have been tested with yarn only

yarn. Will try copying your example and get back to you.

Cool - also check if you've got anything globally installed (webpack I'm thinking). Shouldn't conflict but it's a possibility I guess. Weird things happen

Sorry with the late response. I solved the issue. I hope this gives you some insights. Also, I'd like the following to be explicitly stated in the docs.


TL;DR;

The issue was caused because of a wrong order of ForkTsCheckerWebpackPlugin and ForkTsCheckerNotifierWebpackPlugin plugins. They should be in this exact order:
1) ForkTsCheckerWebpackPlugin
2) ForkTsCheckerNotifierWebpackPlugin


Now the lengthy part

The problem I got was that a certain hook was not present in the compiler.hooks object. Namely, forkTsCheckerReceive which caused the TypeError: Cannot read property 'tap' of undefined issue.

These are the hooks I got if ForkTsCheckerNotifierWebpackPlugin plugin would be ordered before ForkTsCheckerWebpackPlugin.

[ 'shouldEmit',
  'done',
  'additionalPass',
  'beforeRun',
  'run',
  'emit',
  'afterEmit',
  'thisCompilation',
  'compilation',
  'normalModuleFactory',
  'contextModuleFactory',
  'beforeCompile',
  'compile',
  'make',
  'afterCompile',
  'watchRun',
  'failed',
  'invalid',
  'watchClose',
  'environment',
  'afterEnvironment',
  'afterPlugins',
  'afterResolvers',
  'entryOption' ]

After reordering...

[ 'shouldEmit',
  'done',
  'additionalPass',
  'beforeRun',
  'run',
  'emit',
  'afterEmit',
  'thisCompilation',
  'compilation',
  'normalModuleFactory',
  'contextModuleFactory',
  'beforeCompile',
  'compile',
  'make',
  'afterCompile',
  'watchRun',
  'failed',
  'invalid',
  'watchClose',
  'environment',
  'afterEnvironment',
  'afterPlugins',
  'afterResolvers',
  'entryOption',
  'forkTsCheckerServiceBeforeStart',
  'forkTsCheckerCancel',
  'forkTsCheckerServiceStartError',
  'forkTsCheckerWaiting',
  'forkTsCheckerServiceStart',
  'forkTsCheckerReceive',
  'forkTsCheckerServiceOutOfMemory',
  'forkTsCheckerEmit',
  'forkTsCheckerDone' ]

Sure. I'll do it tomorrow, if that's ok with you

Also, now I noticed the comment about the order, however, I'd still prefer it to be more explicit. People _(like me)_ tend to overlook stuff that isn't highlighted 馃檪

How do I get permissions to push a branch?

Fork and do a pull request?

PR accepted. Closing issue

Was this page helpful?
0 / 5 - 0 ratings