2

I have a Razzle app and build is broken. It doesn't make sense as the error shown in build result points to something that doesn't exist in my code. This is the error message from Terser:

'Unexpected token: punc (.) [webpack://./node_modules/ts-loader/index.js??ruleSet[1].rules[4]!./src/Components/ImageUploader/ImageUploader.tsx:35,33][static/js/client.8ef62a8a.js:23168,34]\n'

and the code this error refers to this piece:

Terser error

This is my razzle.config.js file:

const path = require('path');
const LoadableWebpackPlugin = require("@loadable/webpack-plugin");
const { loadableTransformer } = require('loadable-ts-transformer');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  plugins: [
    'typescript',
    new MiniCssExtractPlugin(),
  ],
  buildType: 'iso-serverless',
  target: 'web',
  modify: (config, { target, dev }, webpack) => {
    config.resolve.extensions = config.resolve.extensions.concat(['.ts', '.tsx']);
    config.module.rules.push({ test: /\.tsx?$/, loader: 'ts-loader' });
    config.module.rules.push({ test: /\.(png|jpe?g|gif|ico)$/i, loader: 'file-loader' });

    if (dev) {
      if (target === 'node') {
        config.plugins = config.plugins.filter(p => p.constructor.name !== 'HotModuleReplacementPlugin');
        config.entry = config.entry.filter(e => e !== 'webpack/hot/poll?300');
      }
      if (target === 'web') {
        config.devServer.https = true;
        config.devServer.pfx = process.env.RAZZLE_PFX;
        config.devServer.pfxPassphrase = process.env.RAZZLE_PFX_PASSPHRASE;
      }
      config.output.publicPath = config.output.publicPath.replace('http://', 'https://');
    } else {
      if (target === 'node') {
        config.externals = [];
      }
    }

    return config;
  },
  modifyWebpackConfig(opts) {
    const config = opts.webpackConfig;
    const filename = path.resolve(__dirname, "build");

    if (!opts.env.dev) {
      config.output.publicPath = '/public/';
    }

    if (opts.env.target === "web") {
      config.plugins.push(
        new LoadableWebpackPlugin({
          outputAsset: false,
          writeToDisk: { filename },
        })
      );
    }

    if (opts.env.target === "web" && opts.env.dev) {
      config.devServer.https = true;
      config.devServer.pfx = process.env.RAZZLE_PFX;
      config.devServer.pfxPassphrase = process.env.RAZZLE_PFX_PASSPHRASE;

      config.output.publicPath = config.output.publicPath.replace('http://', 'https://');

      // config.plugins.push(new ForkTsCheckerWebpackPlugin({
      //   eslint: {
      //     files: './React/**/*.{ts,tsx}',
      //   },
      // }));
    }

    config.module.rules.push({
      test: /\.(t|j)sx?$/,
      exclude: /node_modules/,
      loader: 'ts-loader',
      options: {
        getCustomTransformers: () => ({ before: [loadableTransformer] }),
      },
    });

    return config;
  },
};

And this is my package.json file:

{
  "name": "website",
  "version": "0.1.0",
  "license": "MIT",
  "scripts": {
    "start": "razzle start",
    "build": "razzle build --noninteractive",
    "start:prod": "NODE_ENV=production node build/server.js"
  },
  "dependencies": {
    "@loadable/component": "^5.15.0",
    "@loadable/server": "5.15.0",
    "@types/loadable__component": "^5.13.4",
    "@types/styled-components": "^5.1.12",
    "@uiw/react-md-editor": "^3.8.4",
    "axios": "^0.24.0",
    "express": "4.17.1",
    "grommet": "^2.17.4",
    "grommet-icons": "^4.6.0",
    "grommet-styles": "^0.2.0",
    "i18next": "^20.4.0",
    "razzle": "4.0.5",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-i18next": "^11.11.4",
    "react-image-crop": "^9.0.5",
    "react-router-dom": "5.1.2",
    "react-toastify": "7.0.3",
    "styled-components": "^5.3.0"
  },
  "devDependencies": {
    "@babel/preset-typescript": "^7.14.5",
    "@loadable/babel-plugin": "^5.13.2",
    "@loadable/webpack-plugin": "^5.15.0",
    "@types/react": "^17.0.15",
    "@types/react-dom": "^17.0.9",
    "@types/react-loadable": "^5.5.6",
    "@types/react-router-dom": "^5.1.8",
    "@typescript-eslint/eslint-plugin": "4.28.5",
    "@typescript-eslint/parser": "^4.28.5",
    "babel-preset-razzle": "^4.0.5",
    "css-loader": "^6.5.1",
    "eslint": "^7.32.0",
    "eslint-config-airbnb-typescript": "^12.3.1",
    "eslint-plugin-import": "^2.22.0",
    "eslint-plugin-jsx-a11y": "^6.3.1",
    "eslint-plugin-react": "^7.20.3",
    "eslint-plugin-react-hooks": "^4.0.8",
    "file-loader": "^6.2.0",
    "fork-ts-checker-webpack-plugin": "^6.3.2",
    "html-webpack-plugin": "^5.3.2",
    "loadable-ts-transformer": "^1.0.0-alpha.3",
    "mini-css-extract-plugin": "^0.9.0",
    "razzle-dev-utils": "^4.0.5",
    "razzle-plugin-typescript": "^4.0.5",
    "ts-loader": "9.2.5",
    "typescript": "4.3.5",
    "typescript-loadable-components-plugin": "^1.0.2",
    "webpack": "5.50.0",
    "webpack-dev-server": "^3.11.2"
  }
}

Can you please help me? Thanks in advance.

Ricardo Gaefke
  • 823
  • 1
  • 7
  • 21

1 Answers1

1

I've found the problem and a workaround. Terser cannot compile ?. (possible nulls). So I replaced

UploadBase64: result?.toString(),

with

// @ts-ignore: Object is possibly 'null'.
UploadBase64: result.toString(),

This is not the very best solution but it works fine.

Ricardo Gaefke
  • 823
  • 1
  • 7
  • 21