s-panferov / awesome-typescript-loader

Awesome TypeScript loader for webpack
Other
2.35k stars 181 forks source link

Cannot read property '_tsInstances' of undefined #560

Open alveshelio opened 6 years ago

alveshelio commented 6 years ago

Hi guys,

I'm having issues with awesome-typescript-loader on both versions 3.5.0 and 4.0.1 on a project I have a project that I'm trying to upgrade to Webpack 4.0.2.

Whenever I make a change to a file and Webpack recompiles I get this error: /myproject/node_modules/awesome-typescript-loader/src/instance.ts:73 if (!compiler._tsInstances) { ^ TypeError: Cannot read property '_tsInstances' of undefined

TypeError: Cannot read property '_tsInstances' of undefined
    at resolveInstance (/myproject/node_modules/awesome-typescript-loader/src/instance.ts:73:16)
    at /myproject/node_modules/awesome-typescript-loader/src/instance.ts:368:20
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/myproject/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:25:1)
    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/myproject/node_modules/webpack/node_modules/tapable/lib/Hook.js:35:21)
    at Watching._go (/myproject/node_modules/webpack/lib/Watching.js:40:32)
    at Watching._invalidate (/myproject/node_modules/webpack/lib/Watching.js:164:9)
    at watcher.compiler.watchFileSystem.watch (/myproject/node_modules/webpack/lib/Watching.js:135:10)
    at Watchpack.watcher.once (/myproject/node_modules/webpack/lib/node/NodeWatchFileSystem.js:43:4)
    at Object.onceWrapper (events.js:317:30)
    at emitTwo (events.js:126:13)
    at Watchpack.emit (events.js:214:7)
    at Watchpack._onTimeout (/myproject/node_modules/watchpack/lib/watchpack.js:142:7)
    at ontimeout (timers.js:475:11)
    at tryOnTimeout (timers.js:310:5)
    at Timer.listOnTimeout (timers.js:270:5)

This is my webpack.config.js file:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const autoprefixer = require('autoprefixer');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    entry: {
        main: path.resolve(__dirname, 'src/index.tsx'),
    },
    output: {
        path: path.resolve(__dirname, './build'),
        filename: 'static/js/[name].[hash].js',
        chunkFilename: 'static/js/[name].[hash].chunk.js',
    },
    devtool: 'cheap-module-eval-source-map',
    cache: true,
    watch: true,
    resolve: {
        extensions: [
            '.web.ts',
            '.ts',
            '.web.tsx',
            '.tsx',
            '.web.js',
            '.js',
            '.json',
            '.web.jsx',
            '.jsx',
        ],
        alias: {
            actions: path.resolve(__dirname, './src/store/actions'),
            api: path.resolve(__dirname, './src/api'),
            data: path.resolve(__dirname, './src/data'),
            reducers: path.resolve(__dirname, './src/store/reducers'),
            components: path.resolve(__dirname, './src/components'),
            containers: path.resolve(__dirname, './src/containers'),
            instances: path.resolve(__dirname, './src/instances'),
            i18n: path.resolve(__dirname, './src/i18n'),
            shared: path.resolve(__dirname, './src/shared'),
            models: path.resolve(__dirname, './src/models'),
            config: path.resolve(__dirname, './src/config'),
            // Support React Native Web
            // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
            'react-native': 'react-native-web',
        },
    },
    devServer: {
        contentBase: path.resolve(__dirname, './public'),
        publicPath: '/',
        port: 3000,
        hot: true,
        overlay: true,
        historyApiFallback: true,
    },

    module: {
        rules: [
            // First, run the linter.
            // It's important to do this before Babel processes the JS.
            {
                test: /\.(ts|tsx)$/,
                loader: 'tslint-loader',
                enforce: 'pre',
                include: path.resolve(__dirname, './src.index.tsx'),
            },
            {
                test: /\.js$/,
                loader: 'source-map-loader',
                enforce: 'pre',
                include: path.resolve(__dirname, './src'),
            },
            {
                // "oneOf" will traverse all following loaders until one will
                // match the requirements. When no loader matches it will fall
                // back to the "file" loader at the end of the loader list.
                oneOf: [
                    // "url" loader works like "file" loader except that it embeds assets
                    // smaller than specified limit in bytes as data URLs to avoid requests.
                    // A missing `test` is equivalent to a match.
                    {
                        test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
                        loader: require.resolve('url-loader'),
                        options: {
                            limit: 10000,
                            name: 'static/media/[name].[hash:8].[ext]',
                        },
                    },
                    // Compile .tsx?
                    {
                        test: /\.(ts|tsx)$/,
                        include: path.resolve(__dirname, './src'),
                        loader: 'awesome-typescript-loader',
                        options: {
                            useCache: true,
                            forceIsolatedModules: true,
                            reportFiles: ['src/!**!/!*.{ts,tsx}'],
                        },
                    },
                    // "postcss" loader applies autoprefixer to our CSS.
                    // "css" loader resolves paths in CSS and adds assets as dependencies.
                    // "style" loader turns CSS into JS modules that inject <style> tags.
                    // In production, we use a plugin to extract that CSS to a file, but
                    // in development "style" loader enables hot editing of CSS.
                    {
                        test: /\.css$/,
                        use: [
                            require.resolve('style-loader'),
                            {
                                loader: require.resolve('css-loader'),
                                options: {
                                    importLoaders: 1,
                                    modules: true,
                                    localIdentName: '[name]__[local]__[hash:base64:5]',
                                },
                            },
                            {
                                loader: require.resolve('postcss-loader'),
                                options: {
                                    // Necessary for external CSS imports to work
                                    // https://github.com/facebookincubator/create-react-app/issues/2677
                                    ident: 'postcss',
                                    plugins: () => [
                                        require('postcss-flexbugs-fixes'),
                                        autoprefixer({
                                            browsers: [
                                                '>1%',
                                                'last 4 versions',
                                                'Firefox ESR',
                                                'not ie < 9', // React doesn't support IE8 anyway
                                            ],
                                            flexbox: 'no-2009',
                                        }),
                                    ],
                                },
                            },
                        ],
                        exclude: /node_modules/,
                    },
                    {
                        test: /\.html$/,
                        use: [
                            {
                                loader: 'html-loader',
                                options: {
                                    minimize: true,
                                },
                            },
                        ]
                    },
                    {
                        test: /\.css$/,
                        use: [MiniCssExtractPlugin.loader, 'css-loader']
                    },
                    {
                        // Exclude `js` files to keep "css" loader working as it injects
                        // it's runtime that would otherwise processed through "file" loader.
                        // Also exclude `html` and `json` extensions so they get processed
                        // by webpacks internal loaders.
                        exclude: [/\.js$/, /\.html$/, /\.json$/],
                        loader: require.resolve('file-loader'),
                        options: {
                            name: 'static/media/[name].[hash:8].[ext]',
                        },
                    },
                ],
            },
            // ** STOP ** Are you adding a new loader?
            // Make sure to add the new loader(s) before the "file" loader.
        ],
    },
    plugins: [
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            scripts: ['/config/config.js'],
            hash: true,
            title: 'My App',
            inject: true,
            template: path.resolve(__dirname, './public/index.html'),
            filename: 'index.html',
        }),
        new MiniCssExtractPlugin({
            filename: '[name].css',
            chunkFilename: '[id].css',
        }),
        new CopyWebpackPlugin([
            {
                from: path.resolve(__dirname, './public/config'),
                to: path.resolve(__dirname, './build/config'),
            },
            {
                from: path.resolve(__dirname, './public/manifest.json'),
                to: path.resolve(__dirname, './build/manifest.json'),
            },
            {
                from: path.resolve(__dirname, './public/favicon.ico'),
                to: path.resolve(__dirname, './build/favicon.ico'),
            },
        ]),
    ],
};

The part oneOf: [...] was taken from create-react-app webpack.config.dev.js file

I don't know if it's a problem with awesome-typescript-loader or with my webpack.settings.js file. I've tested with ts-linter 4.0.1 and it recompiles with no problem when I make modifications to a file.

serbanghita commented 6 years ago

It's a known issue:

https://github.com/s-panferov/awesome-typescript-loader/issues/534 https://github.com/s-panferov/awesome-typescript-loader/issues/541

serbanghita commented 6 years ago

@alveshelio upgrading your package seems to fix the problem, beware that the fix is not stable: "awesome-typescript-loader": "^5.0.0-1",

riley-steele-parsons commented 6 years ago

@serbanghita upgrading to 5.0.0-1 does not work for me. ts-loader works great with hot reloading though.

serbanghita commented 6 years ago

@riley-steele-parsons good to know! I didn't want to switch the ts plugin. I'm not having issues with hot-reloading yet with this version, I'm using React with TypeScript.

maximgeerinck commented 6 years ago

Upgraded to 5.0.0.1-1 fixed this issue for me, it's faster than ts-loader on my end (even when ts-loader was used with cache and thread-loader)

samuelgoodell commented 6 years ago

@serbanghita You're a wizard, stable or not it's still working for me

tingtaox commented 5 years ago

@serbanghita Upgrading to "awesome-typescript-loader": "^5.2.0" works for me. I used to use awesome-typescript-loader v2.x.x and latest webpack version(v4.17.1) and I had this issue. I think you must have version of webpack and awesome-typescript-loader compatible.