asyncapi-react icon indicating copy to clipboard operation
asyncapi-react copied to clipboard

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

Open MateuszPe opened this issue 11 months ago • 13 comments

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 <>
        <AsyncApiComponent schema={schema} />
    </>
}

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
`;

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

Troubleshooting

  • I tried to use version v1.3.8

MateuszPe avatar Mar 19 '24 10:03 MateuszPe

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.

github-actions[bot] avatar Mar 19 '24 10:03 github-actions[bot]

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

derberg avatar Mar 20 '24 14:03 derberg

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 avatar Mar 20 '24 14:03 MateuszPe

@derberg could you help me with this?

MateuszPe avatar Mar 26 '24 08:03 MateuszPe

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

yarinvak avatar Mar 27 '24 22:03 yarinvak

🤔 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

derberg avatar Apr 17 '24 16:04 derberg

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

Montysz avatar Apr 18 '24 06:04 Montysz

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.

MrcnP avatar Apr 18 '24 06:04 MrcnP

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 avatar Apr 18 '24 08:04 magicmatatjahu

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.

magicmatatjahu avatar Apr 18 '24 09:04 magicmatatjahu

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

Yahkob avatar May 08 '24 23:05 Yahkob

@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.

MateuszPe avatar Jun 03 '24 13:06 MateuszPe

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.

derberg avatar Jun 20 '24 12:06 derberg