I found the root cause by backtracking the commits I made in Git. The error only happened in Production environment which led me to believe there was something in the Babel/Webpack configuration for production optimisation of assets.
I am using a HTML template with some jquery script.
import '../../vendor/adminlte/js/adminlte.js'
The development server and DEV builds work fine, without any JS errors. However, when building the application for production using the webpack.prod.babel.js configuration, it causes a fatal JS error stopping the application from starting up.
React Boilerplate provides this npm
script for production builds:
"build:prod": "cross-env NODE_ENV=productino webpack --config internals/webpack/webpack.prod.babel.js --color -p --progress --hide-modules --display-optimization-bailout",
Analysis
Advertisement Begins
Advertisement End
The following is the stock webpack.prod.babel.js build (minified):
main.65905c438dc34c6ad88e.chunk.js:1 Uncaught TypeError: n is not a function
at i (main.65905c438dc34c6ad88e.chunk.js:1)
at Object. (main.65905c438dc34c6ad88e.chunk.js:1)
at Object.c3748e5404d292c1e468 (main.65905c438dc34c6ad88e.chunk.js:1)
at i (runtime.1d221209e67203e8a273.js:1)
at Module.8b703812aa8ae3c41814 (main.65905c438dc34c6ad88e.chunk.js:1)
at i (runtime.1d221209e67203e8a273.js:1)
at Object.1 (main.65905c438dc34c6ad88e.chunk.js:1)
at i (runtime.1d221209e67203e8a273.js:1)
at t (runtime.1d221209e67203e8a273.js:1)
at Array.r [as push] (runtime.1d221209e67203e8a273.js:1)
I disabled minification for debugging to show this error:
main.210f877fbe34535fda25.chunk.js:42317 Uncaught TypeError: _typeof is not a function
at main.210f877fbe34535fda25.chunk.js:42317
at main.210f877fbe34535fda25.chunk.js:42310
at Object. (main.210f877fbe34535fda25.chunk.js:42314)
at Object.c3748e5404d292c1e468 (main.210f877fbe34535fda25.chunk.js:43065)
at __webpack_require__ (runtime.e582a08007dcb8b8e6b3.js:84)
at Object.ac98c3de4b2b055bd46f (main.210f877fbe34535fda25.chunk.js:38654)
at __webpack_require__ (runtime.e582a08007dcb8b8e6b3.js:84)
at Object.6c925591d78ad1124781 (main.210f877fbe34535fda25.chunk.js:17694)
at __webpack_require__ (runtime.e582a08007dcb8b8e6b3.js:84)
at Module.8b703812aa8ae3c41814 (main.210f877fbe34535fda25.chunk.js:33026)
This shows a problem with typeof
in a newly added vendor JS file.
The offending line in the babel processed source code is shown below:
Kitchen Multi-Timer Pro
Now you’re cooking
Multi Timer Pro is your ultimate meal prep companion, keeping track of multiple cooking times and making adjustments on the fly. Give it a try today and become a better home cook!
Processed source code:
var _typeof = typeof Symbol === "function" && _typeof(Symbol.iterator) === "symbol" ? function (obj) {
return _typeof(obj);
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof(obj);
};
Original sourcecode:
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
The root cause
It appears the production optimisations inserts parentheses in _typeof(Symbol.iterator) === "symbol"
when original source code is _typeof Symbol.iterator === "symbol"
This is the root cause and fixing it involved removing vendor JS and CSS from webpacks optimisation routines.
As I am using the react-boilerplate
template, this was done by adding an excluded directory to the babel-loader.
{
test: /\.jsx?$/, // Transform all .js and .jsx files required somewhere with Babel
exclude: [/node_modules/,/vendor/],
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
{
// Preprocess our own .css files
// This is the place to add your own loaders (e.g. sass/less etc.)
// for a list of loaders, see https://webpack.js.org/loaders/#styling
test: /\.css$/,
exclude: [/node_modules/,/vendor/],
use: ['style-loader', 'css-loader'],
},
{
// Preprocess 3rd party .css files located in node_modules and vendor
test: /\.css$/,
include: [/node_modules/,/vendor/],
use: ['style-loader', 'css-loader'],
},
// etc...
}
The solution
I replaced the exclude: /node_modules/
with an array, adding the /vendor/
directory. The configuration now excludes any third-party CSS and JS from the optimisation and minification process.
The first step in debugging this sort of thing should be to disable minification and check which line is causing the problem. {: .notice }
What didnt help me is that I added react-bootstrap
and jquery
in the same step which added more fluff and room for error in my investigations.
MY MISSION
This blog started nearly 10 years ago to help me document my technical adventures in home automation and various side projects. Since then, my audience has grown significantly thanks to readers like you.
While blog content can be incredibly valuable to visitors, it’s difficult for bloggers to capture any of that value – and we still have to work for a living too. There are many ways to support my efforts should you choose to do so:
Consider joining my newsletter or shouting a coffee to help with research, drafting, crafting and publishing of new content or the costs of web hosting.
It would mean the world if gave my Android App a go or left a 5-star review on Google Play. You may also participate in feature voting to shape the apps future.
Alternatively, leave the gift of feedback, visit my Etsy Store or share a post you liked with someone who may be interested. All helps spread the word.
BTC network: 32jWFfkMQQ6o4dJMpiWVdZzSwjRsSUMCk6
Conclusion
Hope this helps you resolve the notorious “n is not a function” typescript error. If you have any other suggestion for resolving this type of problem, please leave a comment.