react-jsonschema-form icon indicating copy to clipboard operation
react-jsonschema-form copied to clipboard

Production Builds with Vite and AntD theme not running correctly

Open karl-d opened this issue 3 years ago • 6 comments

Prerequisites

What theme are you using?

antd

Version

4.2.2

Current Behavior

We are upgrading a project from Webpack to Vite. Currently in development this all works and loads correctly but we have encountered an error with the production build.

After building a production bundle using Vite & AntD theme, there is a console error Uncaught TypeError: generatePickerExports is not a function.

image image

Expected Behavior

Expect the page to load correctly after a production build

Steps To Reproduce

  1. Use a base Vite project npm create vite@latest . --template react-ts
  2. npm install @rjsf/core@^4.2.2 @rjsf/antd@^4.2.2
  3. Create base page with form
  4. Run npm run dev and page loads fine
  5. Run npm build, which runs successfully
  6. Load browser and see error in the console

Environment

- OS: MacOS 12.3
- Node: v16.16.0
- npm: 8.14.0
- vite: 3.0.0
- typescript: 4.6.4
- react: 18.2.0
- antd: 4.22.1

Anything else?

This looks like it may be cause in the import to override moment.js with day.js in this file https://github.com/rjsf-team/react-jsonschema-form/blob/4049011ea59737232a86c193d96131ce61be85fa/packages/antd/src/components/DatePicker/index.js

karl-d avatar Jul 27 '22 06:07 karl-d

@karl-d what version of antd do you have installed?

heath-freenome avatar Jul 27 '22 17:07 heath-freenome

@heath-freenome v4.22.1

karl-d avatar Jul 27 '22 23:07 karl-d

Hmmm, the tests for the theme are using a much earlier version. I'll see whether things work with that version locally

heath-freenome avatar Jul 28 '22 04:07 heath-freenome

So, things work for me with the latest, but we use webpack, not Vite. I wonder if Vite is preventing the import that drills directly into the antd/lib/date-picker/generatePicker and rc-picker/lib/generate/dayjs from actually working. Is there a configuration property for Vite that might allow this?

heath-freenome avatar Jul 28 '22 06:07 heath-freenome

I have the same problem. Do you solve it?

wangxinyu666666 avatar Aug 02 '22 08:08 wangxinyu666666

@heath-freenome I have not been able to find any configuration that helps resolve the issue. I have created a base repo here that I am able to replicate the issue. https://github.com/karl-d/react-json-schema-antd-vite/tree/main

karl-d avatar Aug 03 '22 04:08 karl-d

I faced the same issue. The problem is that antd and rc-picker components are imported from lib directories containing CommonJS modules not compatible with Vite. Vite requires ES modules. Although @rjsf/antd/dist/antd.esm.js is used in Vite build it contains imports of CommonJS modules from antd and rc-picker. So in order to fix the issue for Vite you have to import ES modules everywhere across this project. As example, DatePicker/index.js mentioned above:

import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
import generatePicker from 'antd/lib/date-picker/generatePicker';

const DatePicker = generatePicker(dayjsGenerateConfig);

export default DatePicker;

should be changed to:

import dayjsGenerateConfig from 'rc-picker/es/generate/dayjs';
import generatePicker from 'antd/es/date-picker/generatePicker';

const DatePicker = generatePicker(dayjsGenerateConfig);

export default DatePicker;

As a quick workaround I applied the following patch to antd.esm.js (version 4.23.0) using patch-package:

diff --git a/node_modules/@rjsf/antd/dist/antd.esm.js b/node_modules/@rjsf/antd/dist/antd.esm.js
index 88344cc..50b041d 100644
--- a/node_modules/@rjsf/antd/dist/antd.esm.js
+++ b/node_modules/@rjsf/antd/dist/antd.esm.js
@@ -1,28 +1,28 @@
 import { utils, withTheme } from '@rjsf/core';
 import React, { useState, useEffect } from 'react';
 import classNames from 'classnames';
-import { withConfigConsumer } from 'antd/lib/config-provider/context';
-import Form$1 from 'antd/lib/form';
-import Button from 'antd/lib/button';
-import Col from 'antd/lib/col';
-import Input from 'antd/lib/input';
-import Row from 'antd/lib/row';
+import { withConfigConsumer } from 'antd/es/config-provider/context';
+import Form$1 from 'antd/es/form';
+import Button from 'antd/es/button';
+import Col from 'antd/es/col';
+import Input from 'antd/es/input';
+import Row from 'antd/es/row';
 import DeleteOutlined from '@ant-design/icons/DeleteOutlined';
 import _ from 'lodash-es';
 import PlusCircleOutlined from '@ant-design/icons/PlusCircleOutlined';
 import ArrowDownOutlined from '@ant-design/icons/ArrowDownOutlined';
 import ArrowUpOutlined from '@ant-design/icons/ArrowUpOutlined';
-import Checkbox from 'antd/lib/checkbox';
+import Checkbox from 'antd/es/checkbox';
 import dayjs from 'dayjs';
-import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
-import generatePicker from 'antd/lib/date-picker/generatePicker';
-import Radio from 'antd/lib/radio';
-import Slider from 'antd/lib/slider';
-import Select from 'antd/lib/select';
-import InputNumber from 'antd/lib/input-number';
-import Alert from 'antd/lib/alert';
-import List from 'antd/lib/list';
-import Space from 'antd/lib/space';
+import dayjsGenerateConfig from 'rc-picker/es/generate/dayjs';
+import generatePicker from 'antd/es/date-picker/generatePicker';
+import Radio from 'antd/es/radio';
+import Slider from 'antd/es/slider';
+import Select from 'antd/es/select';
+import InputNumber from 'antd/es/input-number';
+import Alert from 'antd/es/alert';
+import List from 'antd/es/list';
+import Space from 'antd/es/space';
 import ExclamationCircleOutlined from '@ant-design/icons/ExclamationCircleOutlined';
 
 function _extends() {

ezze avatar Aug 18 '22 15:08 ezze

@ezze Are you willing to make a PR against the rjsf-v5 branch with the changes you recommend to DatePicker?

heath-freenome avatar Aug 23 '22 00:08 heath-freenome

Thanks for response. At the moment, we're using rjsf-v4 so that's where we want to see these changes first.

ezze avatar Aug 23 '22 00:08 ezze

There currently isn't a plan to update v4 anymore as v5 beta is going to take over the master branch this weekend.

heath-freenome avatar Aug 23 '22 00:08 heath-freenome

Not good news for us. Probably, we will live with patched v4 for a while. Not sure how many breaking changes will be introduced in v5 and whether they affect us seriously. Anyway, I am pretty sure that v5 must be ESM compatible to fix the issue.

ezze avatar Aug 23 '22 00:08 ezze

this is happening with me too and alas again looks to be related to ESM support in Vite, kinda sad really, Vite is so awesome, i feel like i might have to look into forking this repo to get it fixed. works fine as a dev build but as a prod build its no buneo

nk2580 avatar Aug 23 '22 09:08 nk2580

For me it worked to add this alias to vite.config.js:

resolve: {
    alias: [
      {
        find: "antd/lib",
        replacement: "antd/es",
      }
    ],
  },

aprilis avatar Aug 23 '22 15:08 aprilis

Since there is a vite config work-around, is it ok to close this issue? I just tried making the suggested change in the v5 beta and jest fails badly while trying to run tests and I do not have the bandwidth to figure it out:

 Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /Users/heath/dev/react-jsonschema-form/packages/antd/node_modules/rc-picker/es/generate/dayjs.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import dayjs from 'dayjs';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

    > 1 | import dayjsGenerateConfig from "rc-picker/es/generate/dayjs";
        | ^
      2 | import generatePicker from "antd/es/date-picker/generatePicker";
      3 |
      4 | const DatePicker = generatePicker(dayjsGenerateConfig);

      at Runtime.createScriptFromCode (node_modules/dts-cli/node_modules/jest-runtime/build/index.js:1728:14)
      at Object.<anonymous> (src/components/DatePicker/index.js:1:1)

heath-freenome avatar Aug 24 '22 00:08 heath-freenome

Fixed in v5 beta via https://github.com/rjsf-team/react-jsonschema-form/pull/3044, see the 5.x migration guide

heath-freenome avatar Aug 28 '22 16:08 heath-freenome