asyncapi / asyncapi-react

React component for rendering documentation from your specification in real-time in the browser. It also provides a WebComponent and bundle for Angular and Vue
https://asyncapi.github.io/asyncapi-react/
Apache License 2.0
188 stars 125 forks source link

Cannot use React component for rendering documentation due to missing modules like fs, util from @asyncapi/parser/esm, @stoplight/json-ref-readers #956

Open MateuszPe opened 8 months ago

MateuszPe commented 8 months ago

Description

I am trying to use React component for rendering documentation. I cannot use it due to the problem with missing modules. I created new application with create react app (I am aware that it is deprecated)

npx create-react-app async-api-check --template typescript

Then I installed asyncapi-react:

npm install --save @asyncapi/react-component   

I am using node v20.11.1.

package.json content:

{
  "name": "async-api-check",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@asyncapi/react-component": "^1.4.2",
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.18.90",
    "@types/react": "^18.2.67",
    "@types/react-dom": "^18.2.22",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.9.5",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Expected result

Application renders provided anyncapi definition.

Actual result

Compiled with problems:
×
ERROR in ./node_modules/@asyncapi/parser/esm/from.js 28:0-30
Module not found: Error: Can't resolve 'fs' in '{project_path}/node_modules/@asyncapi/parser/esm'
ERROR in ./node_modules/@asyncapi/parser/esm/from.js 29:0-33
Module not found: Error: Can't resolve 'util' in '{project_path}/node_modules/@asyncapi/parser/esm'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
    - install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }
ERROR in ./node_modules/@stoplight/json-ref-readers/file.js 6:13-26
Module not found: Error: Can't resolve 'fs' in '{project_path}/node_modules/@stoplight/json-ref-readers'
ERROR in ./node_modules/@stoplight/spectral-runtime/dist/reader.js 10:37-50
Module not found: Error: Can't resolve 'fs' in '{project_path}/node_modules/@stoplight/spectral-runtime/dist'
ERROR in ./node_modules/@stoplight/yaml-ast-parser/dist/src/type/binary.js 3:17-41
Module not found: Error: Can't resolve 'buffer' in '{project_path}/node_modules/@stoplight/yaml-ast-parser/dist/src/type'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
    - install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }
ERROR in ./node_modules/avsc/etc/browser/avsc.js 14:11-28
Module not found: Error: Can't resolve 'stream' in '{project_path}/node_modules/avsc/etc/browser'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
    - install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "stream": false }
ERROR in ./node_modules/avsc/etc/browser/avsc.js 15:9-24
Module not found: Error: Can't resolve 'util' in '{project_path}/node_modules/avsc/etc/browser'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
    - install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }
ERROR in ./node_modules/avsc/etc/browser/lib/crypto.js 14:13-30
Module not found: Error: Can't resolve 'buffer' in '{project_path}/node_modules/avsc/etc/browser/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
    - install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }
ERROR in ./node_modules/avsc/lib/containers.js 17:11-28
Module not found: Error: Can't resolve 'buffer' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
    - install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }
ERROR in ./node_modules/avsc/lib/containers.js 18:11-28
Module not found: Error: Can't resolve 'stream' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
    - install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "stream": false }
ERROR in ./node_modules/avsc/lib/containers.js 19:9-24
Module not found: Error: Can't resolve 'util' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
    - install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }
ERROR in ./node_modules/avsc/lib/containers.js 20:9-24
Module not found: Error: Can't resolve 'zlib' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "zlib": require.resolve("browserify-zlib") }'
    - install 'browserify-zlib'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "zlib": false }
ERROR in ./node_modules/avsc/lib/services.js 18:11-28
Module not found: Error: Can't resolve 'buffer' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
    - install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }
ERROR in ./node_modules/avsc/lib/services.js 20:11-28
Module not found: Error: Can't resolve 'stream' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
    - install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "stream": false }
ERROR in ./node_modules/avsc/lib/services.js 21:9-24
Module not found: Error: Can't resolve 'util' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
    - install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }
ERROR in ./node_modules/avsc/lib/specs.js 12:9-24
Module not found: Error: Can't resolve 'path' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
    - install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "path": false }
ERROR in ./node_modules/avsc/lib/specs.js 13:9-24
Module not found: Error: Can't resolve 'util' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
    - install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }
ERROR in ./node_modules/avsc/lib/types.js 17:11-28
Module not found: Error: Can't resolve 'buffer' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
    - install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }
ERROR in ./node_modules/avsc/lib/types.js 19:9-24
Module not found: Error: Can't resolve 'util' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
    - install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }
ERROR in ./node_modules/avsc/lib/utils.js 9:13-30
Module not found: Error: Can't resolve 'buffer' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
    - install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "buffer": false }
ERROR in ./node_modules/avsc/lib/utils.js 11:11-26
Module not found: Error: Can't resolve 'util' in '{project_path}/node_modules/avsc/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
    - install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }

Steps to reproduce

  1. Create application with npx create-react-app async-api-check --template typescript
  2. Install asyncapi-react with npm install --save @asyncapi/react-component
  3. Create new component AsyncApi.tsx:
    
    import AsyncApiComponent from "@asyncapi/react-component"
    import React from "react";

export const AsyncApi = () => { return <>

</>

}

const schema = asyncapi: '2.0.0' info: title: Example version: '0.1.0' channels: example-channel: subscribe: message: payload: type: object properties: exampleField: type: string exampleNumber: type: number exampleDate: type: string format: date-time ;


4. Add newely created component to your application. e.g. to main `App.tsx` component.
5. Run application with `npm start` and try to render react component with asyncapi.

**Troubleshooting**

- I tried to use version `v1.3.8` 
github-actions[bot] commented 8 months ago

Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Please check out our contributors guide and the instructions about a basic recommended setup useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

derberg commented 8 months ago

Please try with latest 1.4.2 and also older node version. We do not test against node 20 yet and our internal playground builds well against node 18

MateuszPe commented 8 months ago

Regrettably, I've encountered the same outcome even after testing the latest version of the component with both Node 18 and 20.
@derberg why asyncapi/react-component needs fs module? Does it need to interact with files?

MateuszPe commented 7 months ago

@derberg could you help me with this?

yarinvak commented 7 months ago

experiencing it as well (tried to lower version to 1.3.8, still encountering the issue) Can't resolve 'fs' in node_modules/@asyncapi/parser/esm

derberg commented 7 months ago

🤔 fs comes from parser that has a read file functionality, but we had proper webpack in place to make sure package still works in browser 🤔

https://github.com/asyncapi/asyncapi-react/blob/master/library/webpack.config.js#L50

Montysz commented 7 months ago

I'm stuck dealing with a recurring problem and can't seem to find a fix for it.

MrcnP commented 7 months ago

I have the same issue and tried to fix it by downgrading versions (which did not help).

We wanted to adopt AsyncAPI widely for our users, but not having UI for it is a no-go.

magicmatatjahu commented 7 months ago

Webpack since version 5 no longer automatically adds polyfills for all native modules from nodejs, you have to add them yourself. asyncapi-react and parser-js itself has sideEffects: false enabled which means that any unused code is automatically removed from the final bundle (treeshaking), however asyncapi-react uses parser-js underneath and it again uses libraries that parse and validate the AsyncAPI spec that is passed to the component. These libraries (like spectral) have used modules from fs and other native modules which is why webpack throws errors that fs is used somewhere and needs to be discarded or treated as an "empty" module.

If you are using create-react-app then you need to eject config for webpack and add appropriate fallbacks for modules, if you are using nextjs or remix (or another react framrwork) then you should be able to configure webpack without ejecting the framework configuration like here: https://stackoverflow.com/questions/64926174/module-not-found-cant-resolve-fs-in-next-js-application/68098547#68098547

There is also an option to use component without parser-js -> https://github.com/asyncapi/asyncapi-react/blob/master/library/src/without-parser.ts but then you have to parse and validate (and maybe, based on cases, stringify the spec to JSON) on your own and put that inside mentioned component without parser.

magicmatatjahu commented 7 months ago

I forgot about one thing, asyncapi-react has a special version with bundled code, with and without parser - unfortunately with ReactDOM on board - there should be also a version with "pure" component (as another issue), just use

import AsyncAPIStandalone from '@asyncapi/react-component/browser/standalone'

AsyncAPIStandalone.render(...)

docs: https://github.com/asyncapi/asyncapi-react/blob/master/docs/usage/standalone-bundle.md

but I don't remember if it still works.

Yahkob commented 6 months ago

I tried without-parser by slightly modifying the example codesandbox in your readme but something might be broken, nothing happens. I think this might be why there are so many downloads on NPM for 0.24.23

MateuszPe commented 5 months ago

@derberg after two months this issue is still present. It there any plan to fix this issue?

I have tried the newest version with the node in version 18 and 20.

derberg commented 5 months ago

we need more support here in this project and prefer PRs with fixes.

@magicmatatjahu wouldn't be the best from developer experience if we make sure parser-js also publish separately package without functionality of reading from file? Then we just make sure we use here more lightweight version of parser, without delegating workarounds to react components users.