Solving Uncaught TypeError: n is not a function

This error gave me a headache because it gave little information.

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 productino 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",

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.<anonymous> (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.<anonymous> (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:

Processed:

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;
};

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...
 }

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.

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.

Hope this helps.