Typescript with react-hot-loader errors with cannot find name __REACT_HOT_LOADER__ - javascript

I'm new to typescript and I'm attempting to configure a small app with webpack 3, react-hot-loader, and awesome-typescript-loader. So far I'm receiving two errors that I can't seem to figure out.
The first error is: TS2304: Cannot find name '__REACT_HOT_LOADER__'
The second error is TS2304: Cannot find name '__webpack_exports__'
Here's my .tsconfig:
{
"compilerOptions": {
"outDir": "./public/",
"strictNullChecks": true,
"module": "es6",
"jsx": "react",
"target": "es5",
"allowJs": true,
"moduleResolution": "node"
},
"include": [
"./src/"
]
}
and here's my webpack.config.js
require('dotenv').config();
var webpack = require('webpack');
var path = require('path');
var srcPath = path.join(__dirname, '/src')
var distPath = path.join(__dirname, '/public');
const config = {
output: {
path: distPath,
publicPath: '/public',
filename: 'bundle.js'
},
resolve: {
extensions: ['.js', '.ts', '.tsx']
},
module: {
rules: [
{
test: /\.(j|t)sx?$/,
exclude: /node_modules/,
use: 'awesome-typescript-loader'
},
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
}
]
},
context: srcPath,
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.EnvironmentPlugin(['NODE_ENV'])
]
};
// Development Environment
if (process.env.NODE_ENV === 'development') {
config.entry = [
'react-hot-loader/patch',
'webpack-hot-middleware/client?noInfo=false',
path.join(srcPath, '/index.tsx')
]
config.module.rules.push(
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: 'react-hot-loader/webpack'
}
)
config.plugins.push(
new webpack.HotModuleReplacementPlugin()
)
}
// Production Environment
if (process.env.NODE_ENV === 'production') {
config.entry = [
path.join(srcPath, '/index.tsx')
];
config.plugins.push(
new webpack.optimize.UglifyJsPlugin()
)
}
module.exports = config;
I've tried endless different configurations and even dug into the source code for both react-hot-loader and webpack and can't seem to figure out why it's not recognizing those variables. I also have 0 issues with it if i switch my environment to production and bypass the hot reloading so it makes me think the second error is related to the first.
What am I missing? (I'm sure it's right in front of me and I'm just not seeing it)

You must add 'react-hot-loader/webpack' as first loader for ts, js, tsx, jsx files. So edit your webpack.config.js file and replace following lines:
{
test: /\.(j|t)sx?$/,
exclude: /node_modules/,
use: 'awesome-typescript-loader'
}
with following lines:
{
test: /\.(j|t)sx?$/,
exclude: /node_modules/,
loaders: ['react-hot-loader/webpack','awesome-typescript-loader']
}

Related

Webpack debuging tools

I build my project using webpack and want to be able to look at the code in browser but webpack devtools doesn't appear in browser.
I wonder why? I did everything like they say in a book.
Here is my webpack.config file
var path = require('path');
module.exports = {
entry: "./src/App.js",
output: {
path: path.join(__dirname, "dist", "assets"),
filename: 'bundle.js',
sourceMapFilename: 'bundle.map'
},
devtool: "#source-map",
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"]
}
}
}
]
}
}
And here is devtools in browser without webpack in it
Why doesn't it appear in the browser devtools?
You havent set the mode, which defaults to production. See here: https://webpack.js.org/configuration/mode/
And it should be source-map, without the #. Also added sourceMap to the module options, see if that helps.
var path = require('path');
module.exports = {
mode: 'development', // This
entry: "./src/App.js",
output: {
path: path.join(__dirname, "dist", "assets"),
filename: 'bundle.js',
sourceMapFilename: 'bundle.map'
},
devtool: "source-map", // This
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["#babel/preset-env", "#babel/preset-react"]
sourceMap: true, // This
}
}
}
]
}
}

Using Imports with .Net, React.Js, and Url.Content

I am using a .Net MVC framework, and trying to render a jsx (React) file that has imports. I am including this file in the razor page (cshtml) through the standard Url.Content injection as follows:
<script src="#Url.Content("~/js/queue/QueueIndex.js")"></script>
<script>
ReactDOM.render(React.createElement(QueueIndex), document.getElementById("queue-index"));
jQuery(window).on("load scroll", function () {
'use strict'; // Start of use strict
// Loader
$("#dvLoading").fadeOut("fast");
});
</script>
If I do not have an import at the top of my React file (QueueIndex.jsx) the page loads just fine. However, I would like to import the react-table package, but if include any imports in my QueueIndex.jsx file, the page breaks.
The error I'm getting is require is not defined.
I think the solution is somewhere in the use of webpack, here is my config:
const webpack = require("webpack");
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
nhqueue: './wwwroot/js/queue/QueueIndex.jsx'
},
output: {
path: __dirname + '/wwwroot/js/',
publicPath: '/wwwroot/js/',
filename: '[name].bundle.js'
},
module: {
preLoaders: [
],
loaders: [
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{ test: /\.tsx?$/, loaders: ['babel', 'ts'] },
{ test: /\.json$ /, loader: "json-loader" },
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: "babel",
query:
{
presets: ['react']
}
}
],
externals: {
"moment": "moment",
},
},
devtool: 'source-map',
target: 'web',
plugins: [
new CleanWebpackPlugin(['./wwwroot/js/*.js'], {
root: __dirname,
verbose: true,
dry: false
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
new webpack.optimize.UglifyJsPlugin()
],
resolve: {
extensions: ['', '.jsx', '.js', '.tsx', '.ts']
},
node: {
fs: "empty",
child_process: "empty"
}
}
Unfortunately, I have had no luck there. Please let me know if you have any ideas of how to resolve this issue. Thanks!
Also, Here is the Babel configuration:
{"presets" : ["es2015", "react"]}

"Unexpected token import" angular 2 external module

I'm using the ngx-magicsearch module in my project with. However, I get the following error:
Uncaught SyntaxError: Unexpected token import.
I am using the version of Angular 4.2.5, Webpack version 1.15.0 and Typescript 2.3.4
Here is my Webpack file:
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
'app': './app/app.module.ts',
'vendor': './app/vendor/vendor.ts'
},
resolve: {
extensions: ['', '.ts', '.js', '.css', '.html'],
modulesDirectories: ["node_modules", "assets\\js"]
},
output: {
filename: '[name].bundle.js',
},
module: {
noParse: [/jszip.js$/],
loaders: [{
test: /\.ts$/,
loaders: [
'awesome-typescript-loader',
'angular2-router-loader'
]
},
{
test: /\.html$/,
loader: 'html'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\?.*$|$)/,
loader: 'file?name=assets/[name].[hash].[ext]'
},
{
test: /\.css$/,
exclude: './app',
loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
},
{
test: /\.css$/,
include: './app',
loader: 'raw'
},
{
test: /[\\\/]assets[\\\/]js[\\\/]modernizr\.min\.js$/,
loader: "imports?this=>window!exports?window.Modernizr"
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
KJUR: "jsrsasign-latest-all-min",
b64utoutf8: "base64x",
dateFormat: "dateformat",
moment: "moment"
}),
new ExtractTextPlugin('[name].bundle.css'),
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor']
})
],
devServer: {
historyApiFallback: true,
stats: 'minimal'
}
};
tsconfig.js:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noEmitHelpers": false,
"sourceMap": true,
"preserveConstEnums": true,
"alwaysStrict": true
},
"exclude": [
"node_modules"
],
"compileOnSave": false,
"buildOnSave": false
}
And the errors:
The entry point of ngx-magicsearch uses ES modules. You would need to transpile them with babel to use it. Usually the packages publish a transpiled version, although many of them now also publish a version with ES modules that can be used by bundling tools that support them. ES modules are supported out of the box, since webpack 2.
It is highly recommended to upgrade webpack. You'll have to adapt your config a little. For details have a look at the official migration guide.

WebPack optimization with Awesome-Typescript-Loader not seeing much improvement

I'm trying to improve my WebPack performance so I switched out TS-Loader for Awesome-TypeScript-Loader, and my compile times only increased a tiny bit. I had heard ATL is supposed to be much faster, but I only shaved off maybe a few 100ms.
Here's my webpack.config.js:
'use strict';
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
const CleanWebpackPlugin = require('clean-webpack-plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const WebpackNotifierPlugin = require('webpack-notifier');
const { CheckerPlugin, TsConfigPathsPlugin } = require('awesome-typescript-loader')
// const ExtractTextPlugin = require('extract-text-webpack-plugin')
// borrowed from the ng2 seed
const entryPoints = ['inline', 'polyfills', 'sw-register', 'styles', 'vendor', 'app'];
const htmlConfig = {
template: 'client/_index.html',
filename: 'index.html',
// borrowed from the ng2 seed
chunksSortMode: (left, right) => {
const leftIndex = entryPoints.indexOf(left.names[0]);
const rightIndex = entryPoints.indexOf(right.names[0]);
if (leftIndex > rightIndex) {
return 1;
} else if (leftIndex < rightIndex) {
return -1;
} else {
return 0;
}
}
};
function isExternal(module) {
const match = typeof module.userRequest === 'string' &&
/node_modules/.test(module.userRequest.split('!').pop());
return match;
}
// const extractCSS = new ExtractTextPlugin({ filename: '[name].[hash].css', allChunks: true })
// const extractJS = new ExtractTextPlugin({ filename: '[name].[hash].js', allChunks: true })
module.exports = {
cache: true,
entry: {
polyfills: './client/app/polyfills.js',
// base: './client/base.js',
app: './client/app/app.ts'
},
output: {
// Absolute output directory
path: path.join(__dirname, '/dist/'),
// Output path from the view of the page
// Uses webpack-dev-server in development
publicPath: '/',
// Filename for entry points
// Only adds hash in build mode
filename: '[name].[hash].js',
// Filename for non-entry points
// Only adds hash in build mode
chunkFilename: '[name].[hash].js'
},
resolve: {
modules: [
path.resolve(__dirname, 'client'),
'node_modules'
],
extensions: ['.ts', '.js'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'vue-router$': 'vue-router/dist/vue-router.esm.js',
'vuex$': 'vuex/dist/vuex.esm.js',
'vuex-class$': 'vuex-class/dist/vuex-class.cjs.js',
'styles': path.resolve(__dirname, 'client/app/styles'),
'core': path.resolve(__dirname, 'client/app/core'),
'components': path.resolve(__dirname, 'client/app/components'),
'containers': path.resolve(__dirname, 'client/app/containers'),
'assets': path.resolve(__dirname, 'client/assets'),
'config': path.resolve(__dirname, 'client/config')
}
},
// Use 'source-map' for more accurate source mapping
// Use 'cheap-module-eval-source-map' for faster rebuilding
devtool: 'cheap-module-eval-source-map',
module: {
rules: [
{
// ES LINT LOADER
// Reference: https://github.com/MoOx/eslint-loader
// Lint ECMAScript
enforce: 'pre',
test: /\.js$/,
use: [
{ loader: 'eslint-loader', options: { cache: true } }
],
include: [path.resolve(__dirname, 'client')]
},
{
// TS LINT LOADER
// Reference: https://github.com/wbuchwalter/tslint-loader
// Lint TypeScript
enforce: 'pre',
test: /\.ts$/,
use: ['tslint-loader'],
include: [path.resolve(__dirname, 'client')]
},
{
// SOURCE MAP LOADER
// Reference: https://github.com/webpack-contrib/source-map-loader
// Extracts SourceMaps for source files that as added as sourceMappingURL comment
enforce: 'pre',
test: /\.(j|t|s?(a|c)s)s$/, // ts or js or css or scss or sass (or ass)
use: ['source-map-loader'],
exclude: [path.resolve(__dirname, 'node_modules/css-loader/lib/convert-source-map.js')] // There is a sourceMappingURL example in this file that triggers a warning
},
{
// JS LOADER
// Reference: https://github.com/babel/babel-loader
// Transpile .js files using babel-loader
// Compiles ES6 and ES7 into ES5 code
test: /\.js$/,
use: [
{ loader: 'babel-loader', options: { sourceMap: true, cacheDirectory: true } }
],
exclude: [path.resolve(__dirname, 'node_modules')]
},
{
// AWESOME TYPESCRIPT LOADER
// Reference: https://github.com/s-panferov/awesome-typescript-loader
// Transpile .ts files using awesome-typescript-loader
// Compiles TS into ES6 code
test: /\.ts$/,
use: [
// { loader: 'babel-loader', options: { sourceMap: true, cacheDirectory: true } },
// { loader: 'ts-loader' }
{ loader: 'awesome-typescript-loader', options: { sourceMap: true, useCache: true, useBabel: true, useTranspileModule: true } }
],
exclude: [path.resolve(__dirname, 'node_modules')]
},
{
// ASSET LOADER
// Reference: https://github.com/webpack/url-loader
// Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to output
// Rename the file using the asset hash
// Pass along the updated reference to your code
// You can add here any file extension you want to get copied to your output
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|mp4)([?]?.*)$/,
use: [
{ loader: 'file-loader', options: { name: 'assets/[name].[hash].[ext]' } }
]
},
{
// HTML LOADER
// Reference: https://github.com/webpack/html-loader
// Allow loading html through js
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: {
sourceMap: true,
exportAsEs6Default: true,
root: path.resolve(__dirname, 'client'),
// Look for and process the following tag:attr on html elements
attrs: [
'img:src',
'video:src'
]
}
}
]
},
{
// CSS LOADER
// Reference: https://github.com/webpack-contrib/css-loader
test: /\.css$/,
use: [
'style-loader',
{ loader: 'css-loader', options: { sourceMap: true, importLoaders: 1 } },
{ loader: 'postcss-loader', options: { sourceMap: true } }
]
},
{
// SASS LOADER
// Reference: https://github.com/jtangelder/sass-loader
test: /\.s(a|c)ss$/,
use: [
'style-loader',
{ loader: 'css-loader', options: { sourceMap: true, importLoaders: 2 } },
{ loader: 'postcss-loader', options: { sourceMap: true } },
{ loader: 'sass-loader', options: { sourceMap: true } }
]
}
]
},
plugins: [
new webpack.LoaderOptionsPlugin({
cache: true,
debug: true,
minimize: false
}),
new webpack.NamedModulesPlugin(),
new WebpackNotifierPlugin(),
new TsConfigPathsPlugin(),
new CheckerPlugin(),
new StyleLintPlugin({
files: ['./client/**/*.s?(a|c)ss']
}),
// Remove dist and build directories before building
new CleanWebpackPlugin(['dist']),
// extractCSS,
new CommonsChunkPlugin({
name: 'vendor',
// Only analyze the app entry point, we don't want to change the others
chunks: ['app'],
// Check if module is in node_modules
minChunks: (module) => {
return isExternal(module);
}
}),
new HtmlWebpackPlugin(htmlConfig)
],
devServer: {
historyApiFallback: true,
compress: false,
inline: true,
hot: true
}
};
And my tsconfig.json:
{
"compilerOptions": {
"allowJs": true,
"target": "ES2017",
"module": "ES2015",
"moduleResolution": "Node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"noEmitHelpers": true,
"importHelpers": true,
"pretty": true,
"alwaysStrict": true,
"lib": [
"DOM",
"ES2017",
"DOM.Iterable",
"ScriptHost"
],
"baseUrl": ".",
"paths": {
"styles/*": ["./client/app/styles/*"],
"core/*": ["./client/app/core/*"],
"components/*": ["./client/app/components/*"],
"containers/*": ["./client/app/containers/*"],
"assets/*": ["./client/assets/*"],
"config/*": ["./client/config/*"]
}
}
}
And the .babelrc file:
{
"presets": [
[
"env", {
"modules": false,
"useBuiltIns": true,
"debug": true,
"targets": {
"browsers": [
"last 1 Chrome version"
]
}
}]
]
}
I'm targeting ES2017 from TS and leaving it up to Babel to compile for our target browser; as in development we want the extra performance of native code, and less difference of the transpiled coutput.
It seems to be hung up on Babel, especially, as it gets bogged down in the "asset optimization" stage.
TS-loader + Babel: ~1500ms
ATL + Babel: ~1100ms
ATL - Babel: ~800ms
Also, I don't see any performance difference with ATL between useCache: true/false nor useTranspileModule: true/false. But I do see it making a TON of files in the .awcache folder, every time it recompiles (wondering if something is cache busting).
Running webpack-dev-server with params:
webpack-dev-server --watch --hot --progress --open
Using the latest versions of all packages, loaders, and tools as of this post.
Any help would be greatly appreciated!
Thanks!

Webpack2 + babel all but one js file are converted to es5

I'm using webpack and babel to convert my js and vue2 files to es5 and compile into a single build.js
This is my .babelrc
{
"presets": ["latest", 'stage-1'],
"plugins": [
"transform-runtime",
"transform-es2015-arrow-functions"
],
"comments": false
}
and webpack.config.js
var path = require('path'),
webpack = require('webpack');
require("babel-polyfill");
module.exports = {
entry: ['babel-polyfill', './src'],
output: {
path: './dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
scss: 'style-loader!css-loader!sass-loader',
styl: 'style-loader!css-loader!stylus-loader'
}
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.styl$/,
use: [
'style-loader',
'css-loader',
{
loader: 'stylus-loader',
},
],
}
]
},
resolve: {
modules: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules')
],
alias: {
vue: 'vue/dist/vue.common.js'
},
extensions: ['.js', '.vue']
},
plugins: [
// new webpack.DefinePlugin({
// 'process.env': {
// 'NODE_ENV': JSON.stringify('production')
// }
// })
]
}
Running the following command, successfuly compiles all js and vue files including the imported ones into build.js
./node_modules/webpack/bin/webpack.js --progress --watch --display-error-details
All es6 compatible codes are converted to es5 except for BaseModal.js in https://github.com/vue-bulma/modal/
BaseModal.js resides in node_modules/vue-bulma-modal/src/ and is imported by Modal.vue in the same package
I import Modal over index.js of the same package by
import {Modal} from 'vue-bulma-modal'
and BaseModal.js ends up in build.js as it is, without being converted to es5.
But if i copy Modal.vue and BaseModal.js directly into my code and update the import paths accordingly , it is converted to es5 just fine without any problems.
What is it that I'm doing wrong in my webpack.config.js?

Categories

Resources