I use uglifyjs-webpack-plugin on production.
On production only with react-router and preact, routing action is failed to render routed component in <Switch/>.
Routes.js
import React from 'react'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import Header from './Header'
import Home from './Home'
import NotFound from './NotFound'
export default function App() {
return (
<BrowserRouter>
<div>
<Header />
<Switch>
<Route path="/" exact component={Home} />
<Route path="/*" component={NotFound} />
</Switch>
</div>
</BrowserRouter>
)
}
my webpack.config.js
const path = require('path')
const webpack = require('webpack')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
const CompressionPlugin = require('compression-webpack-plugin')
const pkg = require('./package')
const ENV = process.env.NODE_ENV || 'development'
const DEV_PORT = 4444
const hmrEntries = [
'react-hot-loader/patch',
`webpack-dev-server/client?http://localhost:${DEV_PORT}`,
'webpack/hot/only-dev-server'
]
const deps = Object.keys(pkg.dependencies)
module.exports = {
entry: {
vendor: (ENV !== 'production' ? hmrEntries : []).concat(deps),
app: ['./src/index.js']
},
output: {
filename: '[name].bundle.js',
chunkFilename: '[name].bundle.js',
path: __dirname + '/public',
publicPath: '/'
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/
}
]
},
resolve: {
alias: {
react: 'preact-compat',
'react-dom': 'preact-compat',
'preact-compat': 'preact-compat/dist/preact-compat'
}
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.bundle.js'
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(ENV)
}),
].concat(
ENV === 'production'
? [new UglifyJSPlugin({}), new CompressionPlugin()]
: []
)
}
versions
"preact": "^8.2.7",
"preact-compat": "^3.17.0",
"react-router-dom": "^4.2.2",
"uglifyjs-webpack-plugin": "1.1.4",
When I turn off resolve.alias, it works correctly with react.
Full code is here. https://github.com/mizchi-sandbox/pwa-base
This seems to be caused by the UglifyJS settings compress.reduce_vars causing VNode to be inlined into the definition of h, resulting in a new instance of the VNode-constructor for each call to h. preact-compat uses the constructor of a node to compare to other nodes to determine if the other nodes are valid vdom nodes in preact-compat.isValidElement. With VNode inlined this comparison will always be false. Switch uses preact-compat.isValidElement to filter out nulls, resulting in nothing rendered when minified with compress.reduce_vars=true.
A quick fix would be to set compress.reduce_vars to false.
Same error here, but I don't use react-router. The error appeared when I switched to WebPack 4. compress.reduce_vars fixed it.
The uglify issue is tracked in https://github.com/developit/preact/issues/1065 馃帀
Most helpful comment
This seems to be caused by the UglifyJS settings
compress.reduce_varscausingVNodeto be inlined into the definition ofh, resulting in a new instance of theVNode-constructor for each call toh.preact-compatuses the constructor of a node to compare to other nodes to determine if the other nodes are valid vdom nodes inpreact-compat.isValidElement. WithVNodeinlined this comparison will always be false.Switchusespreact-compat.isValidElementto filter out nulls, resulting in nothing rendered when minified withcompress.reduce_vars=true.A quick fix would be to set
compress.reduce_varstofalse.