Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error in [email protected] + [email protected] + react@16 : Unknown theme type: undefined, name: undefined

Tags:

reactjs

antd

vite

I am trying to migrate an old project into vite and I'm very close to success. There is just one bug which occurs in one of the javascript files of ant design when I deploy the app on server.

bug.

This is happening in the following function exported by [email protected]

export function withSuffix(name, theme) {
  switch (theme) {
    case "fill":
      return name + "-fill";
    case "outline":
      return name + "-o";
    case "twotone":
      return name + "-twotone";
    default:
      throw new TypeError("Unknown theme type: " + theme + ", name: " + name);
  }
}
icons.forEach(function (icon) {
  _this2.definitions.set(withSuffix(icon.name, icon.theme), icon);
});

I think this forEach loop is running on an array of undefined ([undefined, undefined..]) but I can't figure out why. I suspect it is due to some configuration I'm missing in my vite file or some other configuration.

If I change the code to this,

export function withSuffix(name, theme) {
  switch (theme) {
    case "fill":
      return name + "-fill";
    default:
    case "outline":
      return name + "-o";
    case "twotone":
      return name + "-twotone";
  }
}

My project runs perfectly on local as well as on server. Here are my package.json and vite.config.ts

`{
  "name": "ta",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "start": "vite --mode local",
    "start:dev": "vite --mode local-development",
    "start:qa": "vite --mode local-qa",
    "build:dev": "tsc && vite build --base=/ta-admin --mode development",
    "build:qa": "tsc && vite build --base=/ta-admin --mode qa",
    "build:staging": "tsc && vite build --base=/admin --mode staging",
    "build:prod": "tsc && vite build --base=/admin --mode production",
    "preview": "vite preview"
  },
  "dependencies": {
    "@ant-design/plots": "^1.2.4",
    "@material-ui/core": "^4.4.0",
    "@material-ui/icons": "^4.2.1",
    "@reduxjs/toolkit": "^1.9.2",
    "antd": "^3.19.3",
    "antd-virtual-select": "^1.1.2",
    "axios": "^1.3.0",
    "file-saver": "^2.0.5",
    "history": "^4.10.1",
    "html2canvas": "^1.4.1",
    "immutability-helper": "^3.0.1",
    "jquery": "^3.6.3",
    "jspdf": "^2.5.1",
    "keycloak-js": "^20.0.3",
    "less": "^4.1.3",
    "loadable-components": "^2.2.3",
    "lodash-decorators": "^6.0.1",
    "lodash.difference": "^4.5.0",
    "moment": "^2.29.4",
    "popper.js": "^1.16.1",
    "react": "^16.8.6",
    "react-dnd": "^9.4.0",
    "react-dnd-html5-backend": "^9.4.0",
    "react-dom": "^16.8.6",
    "react-html-parser": "^2.0.2",
    "react-intl": "^2.9.0",
    "react-intl-universal": "^2.6.11",
    "react-monaco-editor": "^0.31.0",
    "react-redux": "^8.0.5",
    "react-router-dom": "^5.3.4",
    "styled-components": "^5.3.6"
  },
  "devDependencies": {
    "@types/node": "^18.11.18",
    "@types/react": "^16.8.6",
    "@types/react-dom": "^18.0.10",
    "@types/react-router-dom": "^5.3.3",
    "@vitejs/plugin-react": "^3.0.0",
    "typescript": "^4.9.5",
    "vite": "^4.0.0"
  }
}

import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";

const getApiHost = (npm_lifecycle_event: string) => {
  switch (npm_lifecycle_event) {
    default:
    case "start":
      return "http://localhost:8080";
  }
};
export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), "");
  const scriptArray = env?.npm_lifecycle_script?.split(" ") || [];
  const basePortion = scriptArray.find((scriptPortion) => {
    return scriptPortion.includes("--base");
  });
  let outDir = basePortion ? basePortion.split("/")[1] : "build";
  const target = getApiHost(env.npm_lifecycle_event);
  const runningLocally = mode.includes("local");

  return {
    plugins: [react()],
    ...(runningLocally
      ? {
          define: {
            global: {},
          },
        }
      : {}),
    server: {
      port: 3000,
      open: true,
      proxy: {
        "/api": {
          target,
          changeOrigin: true,
          secure: false,
        },
      },
    },
    css: {
      preprocessorOptions: {
        less: {
          javascriptEnabled: true,
          additionalData: "@root-entry-name: default;",
        },
      },
    },
    build: {
      outDir,
      commonjsOptions: {
        transformMixedEsModules: true,
      },
    },
  };
});
like image 493
Maaz Ahmad Khan Avatar asked Oct 11 '25 11:10

Maaz Ahmad Khan


2 Answers

The problem is because of the "namespace import"

https://github.com/ant-design/ant-design/blob/3.x-stable/components/icon/index.tsx#L4

import * as allIcons from '@ant-design/icons/lib/dist';

When the build is done for some reason vite adds the "allIcons.default" attribute and that breaks everything

const allIcons = /*#__PURE__*/ _mergeNamespaces(
  {
    WindowsFill,
    WindowsOutline,
    WomanOutline,
    YahooFill,
    YahooOutline,
    YoutubeFill,
    YoutubeOutline,
    YuqueFill,
    YuqueOutline,
    ZhihuCircleFill,
    ZhihuOutline,
    ZhihuSquareFill,
    ZoomInOutline,
    ZoomOutOutline,
    default: dist$4,
  },
  [dist$4]
);

Four hours later

I found the reason for the problem

https://github.com/rollup/plugins/blob/54c1a7cd6754e2f7b03615529869fd6711fc17fe/packages/commonjs/src/generate-exports.js#L229

I created a plugin to correct this problem:

vite.config.ts

function antDesignIconsFix() {
  return {
    name: '@ant-design-icons-fix',
    transform(code, id) {
      if (id.includes('@ant-design/icons/lib/dist.js'))
        return code.replace(', dist as default', '')
      return code
    },
  }
}

export default defineConfig({
    ...,
    build: {
      rollupOptions: {
        plugins: [antDesignIconsFix()],
      },
    }
})
like image 177
Andres Castellanos. Avatar answered Oct 14 '25 01:10

Andres Castellanos.


Thanks @andres-castellanos for the plugin function, it did work but I noted some problems with my setup:

  1. I had strictRequires option set to true which seems confused the replace lookup. I had to change the value to ['auto', /someRegexPattern/] to filter by specific packages.
  2. When sourcemap is set to true the plugin breaks the sourcemap generation with this error:

Sourcemap is likely to be incorrect: a plugin (@ant-design-icons-fix) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help

Basically the transform function should return the map as null in order to get sourcemap to work:

transform(code: string, id: string): TransformResult {
    if (id.includes('@ant-design/icons/lib/dist.js')) {
        return {
            code: code.replace(', dist as default', ''),
            map: null
        }
    }
    return {
        code,
        map: null
    };
},
like image 21
wctiger Avatar answered Oct 14 '25 01:10

wctiger