awesome-typescript-loader icon indicating copy to clipboard operation
awesome-typescript-loader copied to clipboard

Cannot read property '_tsInstances' of undefined

Open alveshelio opened this issue 7 years ago • 7 comments

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.

alveshelio avatar Mar 26 '18 02:03 alveshelio

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 avatar Mar 26 '18 11:03 serbanghita

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

serbanghita avatar Mar 26 '18 11:03 serbanghita

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

riley-steele-parsons avatar Mar 28 '18 18:03 riley-steele-parsons

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

serbanghita avatar Mar 29 '18 09:03 serbanghita

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)

maximgeerinck avatar Mar 30 '18 12:03 maximgeerinck

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

samuelgoodell avatar Aug 10 '18 00:08 samuelgoodell

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

tingtaox avatar Aug 27 '18 18:08 tingtaox