bpmn-io / form-js

View and visually edit JSON-based forms.
https://bpmn.io/toolkit/form-js/
Other
414 stars 107 forks source link

Formjs Viewer: Error in production build - onSubmit and onChange #240

Closed manoj-mukherjee-maersk closed 2 years ago

manoj-mukherjee-maersk commented 2 years ago

Describe the Bug

Getting below error on running the project in production build. It's working fine in dev build.

Uncaught Error: No provider for "e"! (Resolving: validator -> e)

at l (334.94231739ff87ca26.js:1:27430)
at Object.get (334.94231739ff87ca26.js:1:27228)
at s (334.94231739ff87ca26.js:1:27763)
at 334.94231739ff87ca26.js:1:28016
at Array.map (<anonymous>)
at a (334.94231739ff87ca26.js:1:27979)
at Array.u (334.94231739ff87ca26.js:1:28046)
at kn.s [as get] (334.94231739ff87ca26.js:1:27731)
at kn._update (334.94231739ff87ca26.js:1:47645)
at Object.onChange (334.94231739ff87ca26.js:1:43819)

Steps to Reproduce

  1. Create Nextjs project (typescript) -> yarn create next-app --typescript
  2. add "@bpmn-io/form-js": "^0.7.0" -> yarn add @bpmn-io/form-js
  3. Create a FormViewer components
    
    //components/formViewer.tsx
    import { Form } from "@bpmn-io/form-js";
    import { useEffect } from "react";

import "@bpmn-io/form-js/dist/assets/form-js.css";

const FormViewer = () => { useEffect(() => { const data = { creditor: "John Doe Company", amount: 456, invoiceNumber: "C-123", approved: true, approvedBy: "John Doe", };

const form = new Form({
  container: document.querySelector("#task-form-js-viewer"),
});

//@ts-ignore
form.on("submit", () => {
  console.log("called");
});

const schema = {
  components: [
    {
      key: "creditor",
      label: "Creditor",
      type: "textfield",
      validate: {
        required: true,
      },
    },
    {
      key: "amount",
      label: "Amount",
      type: "number",
      validate: {
        required: true,
      },
    },
    {
      description: "An invoice number in the format: C-123.",
      key: "invoiceNumber",
      label: "Invoice Number",
      type: "textfield",
      validate: {
        pattern: "^C-[0-9]+$",
      },
    },
    {
      key: "approved",
      label: "Approved",
      type: "checkbox",
    },
    {
      key: "approvedBy",
      label: "Approved By",
      type: "textfield",
    },
    {
      key: "submit",
      label: "Submit",
      type: "button",
    },
    {
      action: "reset",
      key: "reset",
      label: "Reset",
      type: "button",
    },
  ],
  type: "default",
};

form
  .importSchema(schema, data)
  .catch((error) => console.error("cannot import form schema", error));

}, []); return

; };

export default FormViewer;


4. Pages/index.tsx
```ts
import type { NextPage } from "next";
import dynamic from "next/dynamic";

// dynamic static components
const FormViewerC = dynamic(() => import("../components/formViewer"), {
  ssr: false,
});

const Home: NextPage = () => {
  return (
    <div>
      <FormViewerC />
    </div>
  );
};

export default Home;
  1. yarn build
    yarn start
  2. fill the form and open console and submit the form you will get the error.

Expected Behavior

In production build no error and onSubmit should work.

Environment

  • Host (Browser/Node version) MS Edge Version 99.0.1150.46 (Official build) (arm64), Chrome
  • OS: [e.g. Windows 7] Mac OS 12.2.1
  • Library version: Tried 0.6.1, 0.7.0
Screenshot 2022-03-22 at 4 42 19 PM
manoj-mukherjee-maersk commented 2 years ago

Example repo -> https://github.com/2manoj1/bpnmformjs clone it. For Reproduce

  • yarn install
  • yarn build
  • yarn start
barmac commented 2 years ago

Hi,

Thanks for reporting this issue. It seems that the build tool (Terser) used by Next.js transforms the Validator to a function below:

> f.toString()
'function f(e){var t=l.call(e);return"[object Function]"===t||"[object AsyncFunction]"===t||"[object GeneratorFunction]"===t||"[object AsyncGeneratorFunction]"===t||"[object Proxy]"===t}'

Then, the didi dependency injection kicks in and tries to provide the cryptic "e" module which does not exist. I don't quite get it why the class is transformed this way, but can see a potential solution to the issue. We could try out if adding a line below fixes the problem:

Validator.$inject = []

We are happy to accept external contributions so if you want to provide a PR, you are welcome to do so.

manoj-mukherjee-maersk commented 2 years ago

Hi @barmac, I dont much idea and knowledge on form-js lib. Can you give some workaround or quick fix for production issue.

barmac commented 2 years ago

I think you could try to play with the configuration, but can't give you a ready-to-use solution as I lack knowledge on Next.js. Check out this: https://stackoverflow.com/questions/42300147/how-to-disable-in-webpack-to-rename-of-function-names-typescript-javascript

manoj-mukherjee-maersk commented 2 years ago

Latest nextjs does nott use Terser. swcMinify by default. https://nextjs.org/docs/upgrading#swc-replacing-terser-for-minification. Tried swcMinify: false but no luck of work.

manoj-mukherjee-maersk commented 2 years ago

I debug and found strict: undefined coming.

Screenshot 2022-03-23 at 3 43 46 PM
manoj-mukherjee-maersk commented 2 years ago
kdy1 commented 2 years ago

Not sure if this is an issue of swc, considering that it fails even with swcMinify: true (Actually it's very unlikely buf of swc)

barmac commented 2 years ago

The solution to the issue is in https://github.com/bpmn-io/form-js/issues/240#issuecomment-1075526031 It's not an swc issue but a problem with how dependency injection form-js works.

manoj-mukherjee-maersk commented 2 years ago

@barmac When this fix available so I will test?

manoj-mukherjee-maersk commented 2 years ago

@barmac not able test this. Its showing close issue but not get any releases.

barmac commented 2 years ago

Indeed, this will be possible when we release the library. This should happen rather soon.

barmac commented 2 years ago
barmac commented 2 years ago

@manoj-mukherjee-maersk Please verify it's fixed with v0.7.1

manoj-mukherjee-maersk commented 2 years ago

Its fixed. Thank you 😊.

Ken-Scofield commented 4 months ago

marker

Ken-Scofield commented 4 months ago

I got the same problem in webpack, optimization.minimize = true , it's caused by terser plugin? @barmac ,Please help me !

Ken-Scofield commented 4 months ago

I got the same problem in webpack, optimization.minimize = true , it's caused by terser plugin? @barmac ,Please help me !

form-js 1.8.6

Ken-Scofield commented 4 months ago

I got the same problem in webpack, optimization.minimize = true , it's caused by terser plugin? @barmac ,Please help me !

And error echo: Error: No provider for "e"! (Resolving: fileUploadField -> e) fileUploadField is my custom field

barmac commented 4 months ago

Please read this part carefully: https://github.com/bpmn-io/form-js/issues/240#issuecomment-1075526031

You need to add proper $inject field for minimized code to work.

Ken-Scofield commented 4 months ago

You need to add proper $inject field for minimized code to work.

FileUploadPropertiesProvider.$inject = ['propertiesPanel'] already in custom properties panel.

Ken-Scofield commented 4 months ago

I followed the example https://github.com/bpmn-io/form-js-examples/blob/master/custom-components/app/extension/render/index.js , At last, I've figured it out that missing $inject in custom fields render class, like this FileUploadFields.$inject = ['formFields'] in render index.js