'Invalid left-hand side in assignment' after webpack and babel build

Viewed 139

Brief overview

I am struggling with porting a react app to be es5 compatible. We have special requirements to run the app on Chrome v37. Therefore i added es5 compatible polyfills, shimming and transpiling to the toolchain

Tools and basic configuration

  • Webpack (v5+), babel (v7+), npm, and typescript (v4.7+)
  • core-js (v3.23+) for polyfills
  • bundle file for our sources
  • bundle file for vendor sources
  • node_modules which are not es5 compatible are NOT excluded from babel-loader
  • node_modules which are es5 compatible are excluded from babel-loader

I also tried:

  • use different module types in the typescript.config (CommonJS, AMD and ES6)
  • use different properties for strict mode in tthe typescript.config
  • downgrade rtf.js package (but don't go under 3.0 because the author removed jquery with 3.0)

Problem

Modern browsers do not throw any error. Old browser does.

The error states: 'Invalid left-hand side in assignment' in the vendor.bundle.js file on 'push.../node_modules/rtf.js/dist/RTFJS.bundle.js'

Chrome v37 throws following error:

Uncaught ReferenceError: Invalid left-hand side in assignment 
vendors.c543a78e.js:10131push.../node_modules/rtf.js/dist/RTFJS.bundle.js 
vendors.c543a78e.js:10131__webpack_require__ app.c543a78e.js:1802fn 
app.c543a78e.js:2048(anonymous function) index.js:7push.../node_modules/rtf.js/index.js 
vendors.c543a78e.js:10152__webpack_require__ app.c543a78e.js:1802fn 
app.c543a78e.js:2048(anonymous function) 
RtfTextConverter.ts?111d:4__webpack_modules__../controllers/sceneInterpreters
/compositeSceneInterpreter/RtfTextConverter.ts app.c543a78e.js:1533__webpack_require__ 
app.c543a78e.js:1802fn app.c543a78e.js:2048(anonymous function) 
CompositeSceneInterpreter.ts?8981:16__webpack_modules__../controllers/sceneInterpreters
/compositeSceneInterpreter/CompositeSceneInterpreter.ts 
app.c543a78e.js:1523__webpack_require__ app.c543a78e.js:1802fn 
app.c543a78e.js:2048(anonymous function) 
PlaylistInterpreter.ts?e5ab:6__webpack_modules__../PlaylistInterpreter.ts 
app.c543a78e.js:543__webpack_require__ app.c543a78e.js:1802fn 
app.c543a78e.js:2048(anonymous function) 
PlaylistManager.tsx?4d1a:5__webpack_modules__../PlaylistManager.tsx 
app.c543a78e.js:553__webpack_require__ app.c543a78e.js:1802fn 
app.c543a78e.js:2048(anonymous function) 
KeyConfigurer.ts?e3b4:8__webpack_modules__../KeyConfigurer.ts 
app.c543a78e.js:493__webpack_require__ app.c543a78e.js:1802fn 
app.c543a78e.js:2048(anonymous function) Main.tsx?e426:5__webpack_modules__../Main.tsx 
app.c543a78e.js:503__webpack_require__ app.c543a78e.js:1802(anonymous function) 
app.c543a78e.js:2958__webpack_require__.O app.c543a78e.js:1851(anonymous function) 
app.c543a78e.js:2959(anonymous function)

Build Configuration

webpack.config.json

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const SignageOSPlugin = require('@signageos/webpack-plugin');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const Dotenv = require('dotenv-webpack');
const fs = require('fs');

var GitRevisionPlugin = require('git-revision-webpack-plugin');

var gitRevisionPlugin = new GitRevisionPlugin({
  commithashCommand: 'rev-list --max-count=1 --no-merges HEAD',
  versionCommand: 'rev-list HEAD --count',
  branchCommand: 'status --porcelain',
});

module.exports = {
  optimization: {
    minimize: false,
    // put all third-party libs into separate bundle file.
    // (https://webpack.js.org/plugins/split-chunks-plugin/)
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
        },
      },
    },
  },

  plugins: [
    new webpack.DefinePlugin({
      __COMMITHASH__: JSON.stringify(gitRevisionPlugin.commithash()),
      __COMMITS_TOWARDS_HEAD__: JSON.stringify(gitRevisionPlugin.version()),
      __GIT_STATUS__: JSON.stringify(gitRevisionPlugin.branch()),
    }),
    new HtmlWebpackPlugin({
      template: '../index_web.html',
    }),
    new Dotenv(),
    new webpack.HotModuleReplacementPlugin(),
    new SignageOSPlugin(),
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
    }),
  ],
  entry: {
    app: ['core-js', 'whatwg-fetch', 'raf/polyfill', './Main.tsx'],
  },
  mode: 'development',
  devServer: {
    host: '0.0.0.0',
  },
  devtool: 'eval-cheap-module-source-map',

  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: new RegExp(fs.readFileSync(path.resolve('./non_ES5_node_modules'), 'utf-8').slice(1, -2)), // /[\\/]node_modules[\\/](?!(free-style|rtf.js|rtfjs)[\\/])/,
      },
      {
        /*
         * https://github.com/webpack-contrib/html-loader/pull/116/commits/843c76eef19122142505ef3c4611ec5b2c70ba24#diff-04c6e90faac2675aa89e2176d2eec7d8
         * https://github.com/dbailo1988/html-loader#examples
         */
        test: /\.html$/,
        use: [
          {
            loader: 'html-loader',
            options: {
              minimize: false,
            },
          },
        ],
      },
      {
        test: /^(.(?!.module.css))*.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: ['/.jsx?$/', '/.js$/', '/.m?js$/'],
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
            plugins: [
              [
                // disabling strict mode for babel transform because free-style lib would fail
                '@babel/plugin-transform-modules-commonjs',
                {
                  loose: true,
                  strictMode: false,
                },
              ],
            ],
          },
        },
        exclude: new RegExp(fs.readFileSync(path.resolve('./non_ES5_node_modules'), 'utf-8').slice(1, -2)), // /[\\/]node_modules[\\/](?!(free-style|rtf.js|rtfjs)[\\/])/,
      },
    ],
  },
  context: path.resolve(__dirname, 'src'),
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
    modules: ['src', 'node_modules'],
    fallback: { stream: require.resolve('stream-browserify') },
    alias: {
      process: 'process/browser', // shimming process/browser for chrome v37
      'free-style': 'free-style/dist.es5/index.js', // avoid es2015 build and use es5 dist files for free-style
    },
  },

  output: {
    path: path.resolve(__dirname, './dist/'),
    filename: '[name].[hash:8].js',
    sourceMapFilename: '[name].[hash:8].map',
    chunkFilename: '[id].[hash:8].js',
  },
};

tsconfig.json

{
  "extends": "./node_modules/gts/tsconfig-google.json",
  "compilerOptions": {
    "outDir": "./dist/",
    "module": "ES6", //es6
    "target": "ES5",
    "allowJs": true,
    "sourceMap": true,
    "strict": false,
    "jsx": "react",
    "noEmit": false,
    "moduleResolution": "node",
    "esModuleInterop": true,
    // es2015.promise -> required for promises
    // es2017 -> required for maps/sets
    "lib": ["es2017", "dom"],
    // related to jest
    //"allowSyntheticDefaultImports": true
    "typeRoots": ["../node_modules/@types"],
    "skipLibCheck": true,
    // "alwaysStrict": true,
    // disabling strict because free-style lib would fail
    "noImplicitUseStrict": true
  },
  "exclude": ["node_modules", "src/**/*.spec.ts", "src/**/*.test.ts"],
  "include": ["src/**/*.ts", "test/**/*.ts", "typings/**/*.d.ts", "src/**/*"]
}

package.json

{
  "name": "newsrodeoviewer",
  "version": "2.0.3",
  "description": "NewsRodeo Viewer built with SignageOS middleware",
  "private": true,
  "main": "dist/index.html",
  "browserslist": [
    "since 2014",
    "dead",
    "chrome 37",
    "chrome 38"
  ],
  "scripts": {
    "start": "webpack-dev-server --mode development",
    "prepare": "npm run clean && npm run build",
    "upload": "sos applet upload",
    "clean": "gts clean",
    "escheck": "npx es-check --module=false es5 dist/*.js",
    "build": "webpack --mode production",
    "postbuild": "npm run escheck",
    "connect": "webpack --watch",
    "lint": "gts lint",
    "test": "jest --watch",
    "test-failures": "jest --onlyFailures",
    "test-unit": "jest unit.test",
    "test-int": "jest int.tes",
    "dev-build": "npx webpack --mode development",
    "prod-build": "npx webpack --mode production",
    "compile": "tsc",
    "fix": "gts fix",
    "postinstall": "sh -c \"npx --silent are-you-es5 check -r . | tail -n 1 > ./non_ES5_node_modules \""
  },
  "keywords": [],
  "author": "",
  "files": [
    "dist"
  ],
  "devDependencies": {
    "@babel/core": "^7.17.10",
    "@babel/preset-env": "^7.17.10",
    "@signageos/cli": "^1.0.2",
    "@signageos/webpack-plugin": "^0.3.0",
    "@types/jest": "^28.1.3",
    "@types/node": "^14.18.21",
    "@types/node-fetch": "^2.1.2",
    "@types/react": "^18.0.12",
    "@types/uuid": "^8.3.4",
    "amd-define-factory-patcher-loader": "^1.0.0",
    "are-you-es5": "^2.1.2",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "dotenv-webpack": "^7.1.1",
    "git-revision-webpack-plugin": "^3.0.3",
    "gts": "^3.1.0",
    "html-loader": "^3.1.2",
    "html-webpack-plugin": "^5.5.0",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^28.1.1",
    "jest-css-modules": "^1.1.0",
    "jest-environment-jsdom": "^28.1.1",
    "node-fetch": "^2.2.0",
    "source-map-loader": "^4.0.0",
    "style-loader": "^3.3.1",
    "ts-jest": "^28.0.5",
    "ts-loader": "^9.3.1",
    "tslint": "^5.11.0",
    "tslint-react": "^3.6.0",
    "typescript": "^4.7.4",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3",
    "webpack-node-externals": "^3.0.0"
  },
  "dependencies": {
    "@signageos/front-applet": "^5.3.0",
    "@signageos/front-display": "^9.16.2",
    "@types/crypto-js": "^3.1.43",
    "@types/jquery": "^3.5.14",
    "@types/react-dom": "^18.0.4",
    "@types/react-redux": "^7.1.24",
    "async-mutex": "^0.1.3",
    "circularbuffer": "^0.1.1",
    "core-js": "^3.23.3",
    "crypto-js": "^3.1.9-1",
    "free-style": "^3.2.4",
    "http-status-codes": "^1.3.0",
    "moment": "^2.29.3",
    "raf": "^3.4.0",
    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "react-icons-kit": "^2.0.0",
    "react-live-clock": "^5.10.0",
    "react-redux": "^8.0.2",
    "react-spinkit": "^3.0.0",
    "redux": "^4.2.0",
    "regenerator-runtime": "^0.13.9",
    "rtf.js": "^3.0.1",
    "stream-browserify": "^3.0.0",
    "typesafe-actions": "^2.0.4",
    "typestyle": "^2.3.0",
    "uuid": "^8.3.2",
    "whatwg-fetch": "^3.6.2",
    "xml-js": "^1.6.7"
  }
}

non_ES5_node_modules

/[\\/]node_modules[\\/](?!(free-style|rtf.js)[\\/])/

I really need to solve this and have no clue what to do. Please feel free to ask for additional information if necessary. Thank you very much!

0 Answers
Related