I've just started building a React.js app with webpack and while the code compiles fine, I get:
Uncaught TypeError: Cannot read property 'array' of undefined
at Object.<anonymous> (RoutingContext.js:28)
in the browser console. I don't even know where to start with where this issue could be.
The RoutingContext is in react-router's own code not mine, specifically this part:
var _React$PropTypes = _react2['default'].PropTypes;
var array = _React$PropTypes.array;
var func = _React$PropTypes.func;
var object = _React$PropTypes.object;
The code I think is causing the issue is:
render((
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="adverts" name="adverts" component={Adverts}></Route>
<Route path="ads" name="ads" component={Adverts}></Route>
</Route>
</Router>
), document.getElementById('root'));
webpack configuration:
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path = require('path');
module.exports = {
context: path.join(__dirname, "src"),
devtool: debug ? "inline-sourcemap" : null,
entry: ["babel-polyfill", "./index.js"],
module: {
rules: [
{ test: /\.json$/, loader: 'json-loader' }
],
loaders: [
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'],
}
},
{
test: /\.css$/,
include: /node_modules/,
loaders: ['style-loader', 'css-loader'],
}
]
},
output: {
path: __dirname + "/src/",
filename: "index.min.js"
},
plugins: debug ? [] : [
new webpack.IgnorePlugin(/(locale)/, /node_modules.+(momentjs)/),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
],
};
You're probably using an old version of react-router with a peer dependency of React 15 while using React 16 in your app. React 16 removed PropTypes from the main package, and it looks like react-router is expecting it. Update react-router.
Related
I'm trying to use Url params in react router 5.2.0, something like
<Switch>
<Route path="/home" component={ Home } />
<Route path="/user/:id" component={ User } />
</Switch >
It's working but when the I'm on a user's page (localhost:8080/user/1) and I refresh the page it'll trigger a 404.
I think the issue may come from my webpack config.
If I add publicPath: '/' in the output it'll work but the app is not able to load images anymore, it'll try to access //assets/images/... instead of /assets/images/....
Here is my webpack config:
const HtmlWebPackPlugin = require('html-webpack-plugin')
const ReactIntlPlugin = require('react-intl-webpack-plugin')
const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath')
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin')
const fs = require('fs')
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const appDirectory = fs.realpathSync(process.cwd())
const resolveApp = relativePath => path.resolve(appDirectory, relativePath)
const publicPath = getPublicUrlOrPath(
process.env.NODE_ENV === 'development',
require(resolveApp('package.json')).homepage,
process.env.PUBLIC_URL
)
const publicUrl = process.env.NODE_ENV === 'development' ? publicPath + "public/assets" : ""
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
},
{
test: /\.(png|jpg|gif|svg|ico)$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[contenthash].[ext]',
outputPath: 'assets/img/'
}
},
],
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
exclude: [/images/],
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'assets/fonts/'
}
},
],
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
},
output:{
filename: 'main.[contenthash].js',
publicPath: '/' //now I can refresh the page but assets folder is not accessible anymore
},
plugins: [
new HtmlWebPackPlugin({
template: "./public/index.html",
filename: "./index.html",
favicon: "./public/assets/favicon.ico"
}),
new ReactIntlPlugin(),
new InterpolateHtmlPlugin(HtmlWebPackPlugin, {
PUBLIC_URL: publicUrl,
}),
new CleanWebpackPlugin()
],
devServer: {
historyApiFallback: true
}
}
Thanks for your help
I fixed it.
So the solution to make the refresh working was to add webpackConfig.output.publicPath = '/' as I tried but the reason why the images were not loading anymore was because in my code I access the images this way:
import Image from '../../images/image.png'
<img src={`/${Image }`} alt="Image"/>
So I just removed the / from src={`/${Image }`} and now it's working and now the images url looks like /assets/images/... instead of //assets/images/...
It was kind of an easy one but I missed it.
I am trying webpack 4 (4.0.1) with code splitting. I am using dynamic loading to load React components.The react components, in turn, are importing components from internal npm modules. For instance,
In my app I have the following routes.
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/topics" component={Topics} />
In each Home, About and Topics components, I am importing a component from my internal npm module( let us say int-home, int-about etc ).
export { App as default } from 'int-about';
Now with this setup, webpack is spitting out extra vendor bundles corresponding to each dynamic import
What could be possibly wrong with my webpack config? How can I make sure that single vendor bundle is churned out in my build?
Below is the webpack config for my main app.
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
entry :'./src/index.js',
output : {
filename: '[name].js',
chunkFilename: '[name].js',
path: path.resolve(__dirname, 'dist'),
publicPath:'dist/',
library : '',
libraryTarget:'umd'
},
resolve:{
extensions: ['.', '.js', '.jsx']
},
mode : process.env.NODE_ENV == 'production' ? 'production' : 'development',
module : {
rules : [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: {
loader:'css-loader',
options:{
minimize : true,
sourceMap: true,
modules:true,
localIdentName: '--[hash:base64:8]'
}
}
})
},
{ test: /\.jsx?$/, use: 'babel-loader' }
]
},
optimization:{
splitChunks:{
cacheGroups:{
vendor: {
chunks: 'initial',
test: path.resolve(__dirname, 'node_modules'),
name: 'vendors',
enforce: true,
},
},
}
},
plugins:[
new ExtractTextPlugin({
filename:"[name].css",
allChunks:true
}),
new webpack.EnvironmentPlugin({
NODE_ENV: process.env.NODE_ENV,
}),
new BundleAnalyzerPlugin({
analyzerMode : 'static'
})
]
}
Taken from this gist:
https://gist.github.com/sokra/1522d586b8e5c0f5072d7565c2bee693#configurate-cache-groups
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all"
}
}
}
Entry file will build literally just fine, but the error occurs on client side, which makes the whole bundle file doesn't work with this issue Uncaught TypeError: Cannot read property 'Blob' of undefined
and i have attached the webpack.config.js which i have tried too
const path = require('path')
const webpack = require('webpack')
const HtmlPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const config = {
entry: './src/main-entry.js',
output: {
path: path.resolve(__dirname, 'views/dist'),
filename: 'bundle.js'
},
module: {
rules: [
{ test: /\.(png|woff|woff2|eot|ttf|svg|gif)$/, loader: 'url-loader?limit=100000' },
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: 'css-loader', fallback: 'style-loader'
})
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
},
plugins: [
new ExtractTextPlugin('bundle.css'),
new webpack.optimize.UglifyJsPlugin({
include: /\.min\.js$/,
minimize: true
})
]
}
module.exports = config
I am using webpack latest version. But i don't know why this is happening? can you help me?
I am trying to use react-icons in my project https://github.com/gorangajic/react-icons
My webpack file looks like this :
import webpack from 'webpack';
import path from 'path';
const GLOBALS = {
'process.env.NODE_ENV': JSON.stringify('development'),
__DEV__: true
};
export default {
debug: true,
devtool: 'cheap-module-eval-source-map', // more info:https://webpack.github.io/docs/build-performance.html#sourcemaps and https://webpack.github.io/docs/configuration.html#devtool
noInfo: true, // set to false to see a list of every file being bundled.
entry: [
'webpack-hot-middleware/client?reload=true',
'./src/index'
],
target: 'web', // necessary per https://webpack.github.io/docs/testing.html#compile-and-test
output: {
path: `${__dirname}/dist`, // Note: Physical files are only output by the production build task `npm run build`.
publicPath: 'http://localhost:3000/', // Use absolute paths to avoid the way that URLs are resolved by Chrome when they're parsed from a dynamically loaded CSS blob. Note: Only necessary in Dev.
filename: 'bundle.js'
},
plugins: [
new webpack.DefinePlugin(GLOBALS), // Tells React to build in prod mode. https://facebook.github.io/react/downloads.htmlnew webpack.HotModuleReplacementPlugin());
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [
{test: /\.js$/, include: path.join(__dirname, 'src'), loaders: ['babel']},
{test: /\.eot(\?v=\d+.\d+.\d+)?$/, loader: 'file'},
{test: /\.(woff|woff2)$/, loader: 'file-loader?prefix=font/&limit=5000'},
{test: /\.ttf(\?v=\d+.\d+.\d+)?$/, loader: 'file-loader?limit=10000&mimetype=application/octet-stream'},
{test: /\.svg(\?v=\d+.\d+.\d+)?$/, loader: 'file-loader?limit=10000&mimetype=image/svg+xml'},
{test: /\.(jpe?g|png|gif)$/i, loaders: ['file']},
{test: /\.ico$/, loader: 'file-loader?name=[name].[ext]'},
{test: /(\.css|\.scss)$/, loaders: ['style', 'css?sourceMap', 'sass?sourceMap']}
]
}
};
It has an svg loader so there shouldn't be an issue, however, I get the following error
ERROR in ./~/react-icons/ti/thumbs-down.js
Module parse failed: /Users/Projects/react-slingshot/node_modules/react-icons/ti/thumbs-down.js Unexpected token (8:12)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (8:12)
Not sure what I'm missing in order to load these in my project
react-icons/ti/thumbs-down.js contains untranspiled ES6+JSX source.
You need to import from react-icons/lib/ti/thumbs-down.js to get the ES5 version, since you're only using Babel on your own src/ directory.
This is mentioned in the README's Usage section.
I'm creating a React Node.js app and I'm trying to generate a Webpack bundle containing the React source code I loaded from NPM.
However, it seems that the React code from NPM cannot be used directly in the client. It triggers this error:
Uncaught ReferenceError: development is not defined
The code that triggers the exception is from the React code:
Is there anything I can do to make that work?
EDIT
This is my webpack.config.js:
import _ from 'lodash';
import webpack from 'webpack';
import yargs from 'yargs';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
export default {
entry: {
bundle: './src/client.js'
},
output: {
filename: '[name].js',
path: './dist/assets',
publicPath: '/assets/'
},
externals: undefined,
resolve: {
extensions: ['', '.js', '.json']
},
module: {
loaders: [
{test: /\.js/, loader: 'babel?optional=es7.objectRestSpread!client', exclude: /node_modules/ },
{test: /\.css/, loader: ExtractTextPlugin.extract("style-loader", "css-loader")},
{test: /\.less$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")},
{test: /\.json$/, loader: 'json'},
{test: /\.jpe?g$|\.gif$|\.png$/, loader: 'file?name=[name].[ext]'},
{test: /\.eot$|\.ttf$|\.svg$|\.woff2?$/, loader: 'file?name=[name].[ext]'}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': 'development'
},
'development': true
}),
new ExtractTextPlugin('[name].css')
]
};
My client.js file only contains this line (for the purpose of debugging this issue):
import React from 'react';
And here is the resulting bundle
Any values passed to webpack.DefinePlugin as strings are treated as code fragments—that is to say, using
new webpack.DefinePlugin({
ENV: "development"
});
with the code
console.log(ENV);
results in
console.log(development);
Instead, you want
new webpack.DefinePlugin({
ENV: "\"development\""
});
which will result in
console.log("development");
To fix your issue, change your plugins to
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': "'development'"
}
}),
new ExtractTextPlugin('[name].css')
]
I usually allow webpack to read from process.env.NODE_ENV so that React minifies properly when you run webpack with NODE_ENV=production:
new webpack.DefinePlugin({
"process.env": { NODE_ENV: JSON.stringify(process.env.NODE_ENV || "development") }
})