Isomorphic React, for many reasons, is gaining traction with many developers. Not least for the SEO benefits – or should we say that massive SEO pitfalls of *NOT* using isomorphic React. Blank pages for Googlebot anyone?
Anyway, a great course available for this very topic, that covers Isomorphic React in a concise fashion is Dan Sterns course over at Pluralsight.
I myself have also started looking at this course – and for anyone else who has started recently, they may have hit a snag with the demo.
Dan provides a starting template for the course – only issue is, that the template falls over with an error after you’ve followed the initial instructions to npm install, npm post install and npm start in the second module ‘Course Introduction’.
A few people have been discussing this on the Isomorphic React course discussion page and a few people have tried to help, but it appears Dan hasn’t had a chance to provide an update yet – probably because he’s uber busy with a load of other things at the moment as many of us are!
Unfortunately, there’s a couple of pieces of the answer missing to get up and running and some helpful steps along the way that are spread out so I’m writing this article to put the solution in one place. Don’t worry, I will of course also be submitting a pull request to Daniel to help get this fixed in the git repo also.
The Issue with the Isomorphic React Template
So, you followed all the instructions, you’re raring to go and boom!
So what does this mean? Short answer, the app isn’t running.
Slightly longer answer (just about!): Uglify can’t understand the pretty new ES6 syntax that we’re all using (or should be using!) by now.
Full error stack included below:
PS C:\Pluralsight\Isomorphic-React\> npm start
> isomorphic-react@1.0.0 start C:\Pluralsight\Isomorphic-React\isomorphic-react
> npm run start-prod
> isomorphic-react@1.0.0 start-prod C:\Pluralsight\Isomorphic-React\
> npm run build && cross-env NODE_ENV=production babel-node server --useServerRender=true --useLiveData=false
> isomorphic-react@1.0.0 build C:\Pluralsight\Isomorphic-React\
> cross-env webpack --config ./webpack.config.prod.babel.js
C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\config-descriptors.js:178
throw new Error(`Plugin/Preset files are not allowed to export objects, only functions. In ${filepath}`);
^
Error: Plugin/Preset files are not allowed to export objects, only functions. In C:\Pluralsight\Isomorphic-React\node_modules\babel-preset-es2015\lib\index.js
at createDescriptor (C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\config-descriptors.js:178:11)
at C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\config-descriptors.js:109:50
at Array.map (<anonymous>)
at createDescriptors (C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\config-descriptors.js:109:29)
at createPresetDescriptors (C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\config-descriptors.js:101:10)
at presets (C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\config-descriptors.js:47:19)
at mergeChainOpts (C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\config-chain.js:320:26)
at C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\config-chain.js:283:7
at buildRootChain (C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\config-chain.js:120:22)
at loadPrivatePartialConfig (C:\Pluralsight\Isomorphic-React\node_modules\@babel\core\lib\config\partial.js:85:55)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! isomorphic-react@1.0.0 build: `cross-env webpack --config ./webpack.config.prod.babel.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the isomorphic-react@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\DPS Computing\AppData\Roaming\npm-cache\_logs\2020-03-31T15_35_22_069Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! isomorphic-react@1.0.0 start-prod: `npm run build && cross-env NODE_ENV=production babel-node server --useServerRender=true --useLiveData=false`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the isomorphic-react@1.0.0 start-prod script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\DPS Computing\AppData\Roaming\npm-cache\_logs\2020-03-31T15_35_22_139Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! isomorphic-react@1.0.0 start: `npm run start-prod`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the isomorphic-react@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\DPS Computing\AppData\Roaming\npm-cache\_logs\2020-03-31T15_35_22_237Z-debug.log
Fixing Isomorphic React Template
The two main areas that need updating are the depdencies and the webpack configuration. I’ll detail the specific steps below.
There’s obviously more than one way to skin a cat – or, in this case, fix a programming template, but we’ve tried and tested this way and all seems fine up to now (we’ll provide updates here if we discover any issues or come up with a more optimum fix).
The main steps are to teach Uglify ES6 (via the very handy uglifyjs-webpack-plugin), upgrade webpack – including adding the recommended webpack command line interface and then substituting the webpack config and including some nice new config features that are part of Webpack 4.
Step 1 – Upgrade Webpack
We’re going to take advantage of some new features of Webpack (such as the optimisation configuration) and this requires an upgrade to Webpack 4.x
You can:
Run:
npm update webpack
Or Change the package.json file directly and run:
npm install
Or you can run:
npm uninstall webpack npm install webpack
To install the latest version (currently 4.42.1).
Step 2 – Add The Webpack CLI
This isn’t included in the original template – but is a recommended part of Webpack 4.x so we ought to add it.
You can do this by running the following command in Powershell:
npm install webpack-cli
If you get giddy and forget this step, you will get a reminder when we start later that the command line interface is missing and you ought to add it:
One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:
- webpack-cli (https://github.com/webpack/webpack-cli)
The original webpack full-featured CLI.
We will use "npm" to install the CLI via "npm install -D".
Do you want to install 'webpack-cli' (yes/no):
Enter ‘yes’ here at the prompt and the default webpack-cli will be installed:
Installing 'webpack-cli' (running 'npm install -D webpack-cli')...
npm WARN webpack-dev-middleware@1.12.2 requires a peer of webpack@^1.0.0 || ^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN isomorphic-react@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
+ webpack-cli@3.3.11
added 38 packages from 24 contributors and audited 870908 packages in 22.005s
1 package is looking for funding
run `npm fund` for details
Step 3 – Install UglifyJS Webpack Plugin
Remember when we said we have to teach Uglify JS ES6? Don’t worry, it’s not like homeschooling! The UglifyJS Webpack Plugin will do the heavy lifting for us!
This isn’t part of the template project so we just need to npm install the latest version:
npm install uglifyjs-webpack-plugin
That’ll whirl away as usual and install in the background.
Step 4 – Updating the Webpack Config
Now onto the final step – updating the webpack config.
One of the key differences is what we’ll need to include our new UglifyJS Webpack plugin that we installed in the previous step:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
This should be included at the top along with the path and webpack dependencies.
Then we add a mode:
- ‘development‘: for webpack.config.dev.babel.js
- ‘production‘: for webpack.config.prod.babel.js
The next major change is the addition of a brand new optimisation (or optimization in American English) object which includes a minimiser (minimizer) array that calls our newly included UglifyJS plugin to, among other things, parse ES6 and sort out the source maps.
There are some other minor changes and renames for Webpack 4 compatibility but we won’t cover them explicitly in detail at the moment.
New Dev Webpack Configuration
Below is the complete development Webpack configuration with all the updates required included. Feel free to drop this straight into your webpack.config.dev.babel.js file:
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const webpack = require('webpack');
module.exports = {
mode: 'development',
entry: [
'babel-regenerator-runtime',
path.resolve(__dirname, 'src')
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/'
},
optimization: {
minimizer: [
// we specify a custom UglifyJsPlugin here to get source maps in production
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
compress: false,
ecma: 6,
mangle: true
},
sourceMap: true
})
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
WEBPACK: true
}
}),
/*
* Uglifies JS which improves performance
* React will throw console warnings if this is not implemented
*/ ],
resolve: {
extensions: ['.js', '.json', '.jsx'],
},
module: {
rules: [
{
test: /.jsx?$/,
use: {
loader: 'babel-loader'
},
include: path.resolve(__dirname, 'src')
}
]
}
};
New Production Webpack Config
For the webpack.config.prod.babel.js, the main change is to update the mode to ‘production’ to take advantage of additional optimisations available for a build environment:
mode: 'production'
The New Webpack Config Doesn’t Work!
It does, trust me! The error you’re probably encountering is that you’ve skipped updating the webpack depedency – this is by far the most common. As the new configuration takes advantage of some new features of Webpack 4 – such as optimisation – Webpack 3.x will throw a hissy fit if you don’t upgrade:
The full error stack is included below for convienience:
PS C:\Pluralsight\Isomorphic-React> npm start
> isomorphic-react@1.0.0 start C:\Pluralsight\Isomorphic-React
> npm run start-prod
> isomorphic-react@1.0.0 start-prod C:\Pluralsight\Isomorphic-React
> npm run build && cross-env NODE_ENV=production babel-node server --useServerRender=true --useLiveData=false
> isomorphic-react@1.0.0 build C:\Pluralsight\Isomorphic-React
> cross-env webpack --config ./webpack.config.prod.babel.js
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration has an unknown property 'optimization'. These properties are valid:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry, externals?, loader?, module?, name?, node?, output?, parallelism?, performance?, plugins?, profile?,
recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
For typos: please correct them.
For loader options: webpack 2 no longer allows custom properties in configuration.
Loaders should be updated to allow passing options via loader options in module.rules.
Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:
plugins: [
new webpack.LoaderOptionsPlugin({
// test: /\.xxx$/, // may apply this only for some modules
options: {
optimization: ...
}
})
]
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! isomorphic-react@1.0.0 build: `cross-env webpack --config ./webpack.config.prod.babel.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the isomorphic-react@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\DPS Computing\AppData\Roaming\npm-cache\_logs\2020-03-31T15_49_53_357Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! isomorphic-react@1.0.0 start-prod: `npm run build && cross-env NODE_ENV=production babel-node server --useServerRender=true --useLiveData=false`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the isomorphic-react@1.0.0 start-prod script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\DPS Computing\AppData\Roaming\npm-cache\_logs\2020-03-31T15_49_53_424Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! isomorphic-react@1.0.0 start: `npm run start-prod`
npm ERR! Exit status 1
npm ERR!
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\DPS Computing\AppData\Roaming\npm-cache\_logs\2020-03-31T15_49_53_507Z-debug.log
PS C:\Pluralsight\Isomorphic-React> rm -rf node_modules
At line:1 char:4
+ rm -rf node_modules
+ ~~~
+ CategoryInfo : InvalidArgument: (:) [Remove-Item], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
Go back to Step 1 above, upgrade webpack and you should be sorted!
Error: Cannot find module!
Sounds like you’ve skipped step 3 – installing the uglify-js-webpack-plugin. Go back and do this and you should be good to go. The good news is, step 4 – replacing webpack config went well if you’re getting this error message!
Full error stack for this one is listed below:
Error: Cannot find module 'uglifyjs-webpack-plugin'
Require stack:
- C:\Pluralsight\Isomorphic-React\webpack.config.prod.babel.js
- C:\Pluralsight\Isomorphic-React\node_modules\webpack-cli\bin\utils\convert-argv.js
- C:\Pluralsight\Isomorphic-React\node_modules\webpack-cli\bin\cli.js
- C:\Pluralsight\Isomorphic-React\node_modules\webpack\bin\webpack.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:797:15)
at Function.Module._load (internal/modules/cjs/loader.js:690:27)
at Module.require (internal/modules/cjs/loader.js:852:19)
at require (C:\Pluralsight\Isomorphic-React\node_modules\v8-compile-cache\v8-compile-cache.js:161:20)
at Object.require (C:\Pluralsight\Isomorphic-React/webpack.config.prod.babel.js:2:24)
at Module._compile (C:\Pluralsight\Isomorphic-React\node_modules\v8-compile-cache\v8-compile-cache.js:192:30)
at Module._compile (C:\Pluralsight\Isomorphic-React\node_modules\pirates\lib\index.js:99:24)
at Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Object.newLoader [as .js] (C:\Pluralsight\Isomorphic-React\node_modules\pirates\lib\index.js:104:7)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.Module._load (internal/modules/cjs/loader.js:727:14)
at Module.require (internal/modules/cjs/loader.js:852:19)
at require (C:\Pluralsight\Isomorphic-React\node_modules\v8-compile-cache\v8-compile-cache.js:161:20)
at WEBPACK_OPTIONS (C:\Pluralsight\Isomorphic-React\node_modules\webpack-cli\bin\utils\convert-argv.js:114:13)
at requireConfig (C:\Pluralsight\Isomorphic-React\node_modules\webpack-cli\bin\utils\convert-argv.js:116:6)
at C:\Pluralsight\Isomorphic-React\node_modules\webpack-cli\bin\utils\convert-argv.js:123:17
at Array.forEach (<anonymous>)
at module.exports (C:\Pluralsight\Isomorphic-React\node_modules\webpack-cli\bin\utils\convert-argv.js:121:15)
at C:\Pluralsight\Isomorphic-React\node_modules\webpack-cli\bin\cli.js:71:45
at Object.parse (C:\Pluralsight\Isomorphic-React\node_modules\yargs\yargs.js:567:18)
at C:\Pluralsight\Isomorphic-React\node_modules\webpack-cli\bin\cli.js:49:8
at Object.<anonymous> (C:\Pluralsight\Isomorphic-React\node_modules\webpack-cli\bin\cli.js:366:3)
at Module._compile (internal/modules/cjs/loader.js:959:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.Module._load (internal/modules/cjs/loader.js:727:14)
at Module.require (internal/modules/cjs/loader.js:852:19)
at require (internal/modules/cjs/helpers.js:74:18)
at C:\Pluralsight\Isomorphic-React\node_modules\webpack\bin\webpack.js:143:5
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'C:\\Pluralsight\\Isomorphic-React\\webpack.config.prod.babel.js',
'C:\\Pluralsight\\Isomorphic-React\\node_modules\\webpack-cli\\bin\\utils\\convert-argv.js',
'C:\\Pluralsight\\Isomorphic-React\\node_modules\\webpack-cli\\bin\\cli.js',
'C:\\Pluralsight\\Isomorphic-React\\node_modules\\webpack\\bin\\webpack.js'
]
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! isomorphic-react@1.0.0 build: `cross-env webpack --config ./webpack.config.prod.babel.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the isomorphic-react@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\DPS Computing\AppData\Roaming\npm-cache\_logs\2020-03-31T16_02_09_115Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! isomorphic-react@1.0.0 start-prod: `npm run build && cross-env NODE_ENV=production babel-node server --useServerRender=true --useLiveData=false`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the isomorphic-react@1.0.0 start-prod script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\DPS Computing\AppData\Roaming\npm-cache\_logs\2020-03-31T16_02_09_312Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! isomorphic-react@1.0.0 start: `npm run start-prod`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the isomorphic-react@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\DPS Computing\AppData\Roaming\npm-cache\_logs\2020-03-31T16_02_09_395Z-debug.log
Still Got An Issue?
Let us know in the comments below and we’ll try to help solve!
What About That Pull Request?
I know, I promised didn’t I? Don’t worry, I’ll get it over to Dan ASAP.
View Comments (8)
Thanks for your informative discussion.
Hey William, thanks for stopping by and thanks for getting involved! Great to see you around here and thanks for the feedback! Look forward to seeing you on other posts too! :)
Stunning post with valuable information.
Hey Angel, thanks for stopping by and thank you for the positive feedback! Look forward to seeing you around on other posts too!
I have done this and still getting error
ERROR in bundle.js from UglifyJs
Unexpected token: punc «}» [./src/components/TagsList.js:2,16][bundle.js:14088,0]
another thing I noticed was that
the package.json start script is using prod.
Hey,
Sorry, I got a bit copy-paste happy there I think! I've changed it in my repo and will open another pull request but in the mean time if you change the dev webpack to 'development' that will fix that issue (although I don't believe that's impacting your babel node issue below but it is worth sorting).
Good spot!
'babel-node' is not recognized as an internal or external command,
operable program or batch file.
events.js:287
throw er; // Unhandled 'error' event
^
Error: spawn babel-node ENOENT
I got this to start has dev
Hi there,
Have you ran NPM install recently? Sounds like there's an issue with your babel dependencies. These things can be finiky - particularly between different versions of plugins etc!
You can follow through this guide to install babel node: https://babeljs.io/docs/en/next/babel-node.html
Hope that helps - let me know if there's anything else you need! :)