Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: replace isomorphic-ws with unws #390

Closed
wants to merge 2 commits into from
Closed

refactor: replace isomorphic-ws with unws #390

wants to merge 2 commits into from

Conversation

sxzz
Copy link
Contributor

@sxzz sxzz commented Apr 19, 2023

unws (https://github.com/sxzz/unws) is designed for modern browsers and bundlers.

isomorphic-ws is a lack of active maintenance, see heineiuo/isomorphic-ws#33


PR-Codex overview

This PR updates the ws package to version 8.12.0 and replaces isomorphic-ws with unws. It also updates the abitype package to version 0.7.1.

Detailed summary

  • Updated ws package to version 8.12.0
  • Replaced isomorphic-ws with unws
  • Updated abitype package to version 0.7.1.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

@changeset-bot
Copy link

changeset-bot bot commented Apr 19, 2023

⚠️ No Changeset found

Latest commit: 2daedc3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Apr 19, 2023

@sxzz is attempting to deploy a commit to the wagmi Team on Vercel.

A member of the Team first needs to authorize it.

@fubhy
Copy link
Collaborator

fubhy commented Apr 19, 2023

Hm. We are already doing the import dynamically. So why not just do the differentiation ourselve within viem and not rely on a package for that at all?

@sxzz
Copy link
Contributor Author

sxzz commented Apr 19, 2023

@fubhy Good idea

@sxzz
Copy link
Contributor Author

sxzz commented Apr 19, 2023

@fubhy I tried that. But unfortunately, Webpack cannot be aware that ws will never be imported on the browser. So it will always bundle ws and cause an error.

Module not found: Error: Can't resolve 'zlib' in '/path/viem/node_modules/.pnpm/[email protected]/node_modules/ws/lib'

@fubhy
Copy link
Collaborator

fubhy commented Apr 19, 2023

@fubhy I tried that. But unfortunately, Webpack cannot be aware that ws will never be imported on the browser. So it will always bundle ws and cause an error.

Module not found: Error: Can't resolve 'zlib' in '/path/viem/node_modules/.pnpm/[email protected]/node_modules/ws/lib'

Too bad :-(. Thanks for trying though.

@nissoh
Copy link

nissoh commented Apr 19, 2023

@sxzz @fubhy possibly related, using vite const { WebSocket } = await import('isomorphic-ws') seems to be failing to load on-demand

TypeError: WebSocket is not a constructor will eventually throw.

haven't checked webpack or other bundlers, but i wonder if anyone has some insights on Vite

@nissoh
Copy link

nissoh commented Apr 19, 2023

i've tried to riff around this issue, here's a log coming out of this code in Vite typescript environment with allowSyntheticDefaultImports = true and esModuleInterop = true (just for the kicks)

  const WebSocket2 = await import('isomorphic-ws')
  const { WebSocket } = await import('isomorphic-ws')

  console.log(window.WebSocket) // ƒ WebSocket() { [native code] }
  console.log(WebSocket2) // Module {Symbol(Symbol.toStringTag): 'Module'}
  console.log(WebSocket) // undefined

i was wondering however if const WebSocket = await import('isomorphic-ws') would work on Webpack as-well so both would be compatible? @fubhy

@fubhy
Copy link
Collaborator

fubhy commented Apr 19, 2023

i've tried to riff around this issue, here's a log coming out of this code in Vite typescript environment with allowSyntheticDefaultImports = true and esModuleInterop = true (just for the kicks)

  const WebSocket2 = await import('isomorphic-ws')
  const { WebSocket } = await import('isomorphic-ws')

  console.log(window.WebSocket) // ƒ WebSocket() { [native code] }
  console.log(WebSocket2) // Module {Symbol(Symbol.toStringTag): 'Module'}
  console.log(WebSocket) // undefined

i was wondering however if const WebSocket = await import('isomorphic-ws') would work on Webpack as-well so both would be compatible? @fubhy

Yeah that could be related.

Our vitest test suite runs only in node environment atm. which isn't ideal. I've also discussed with @tmm and @jxom to add consumer acceptance tests by adding a few different example packages with different setups, environments, bundlers, typescript version, etc. and seeing if they compile & run properly.

@fubhy
Copy link
Collaborator

fubhy commented Apr 19, 2023

@nissoh Can you maybe test whether it works for you with the replacement package that @sxzz has proposed?

@nissoh
Copy link

nissoh commented Apr 19, 2023

@nissoh Can you maybe test whether it works for you with the replacement package that @sxzz has proposed?

checked, unws. seems to working properly. package.json includes cjs, esModules and typescript d.ts
https://github.com/sxzz/unws/blob/main/package.json

with that said, i think the core issue is that https://github.com/wagmi-dev/viem/blob/136c4022c3ab4020f37333876bed788a111bff47/src/utils/rpc.ts#L147 doesn't use default export

check https://github.com/heineiuo/isomorphic-ws/blob/master/browser.js
looking at this file, only default is exported. not sure why { Websocket } destrucutre works on webpack

@fubhy
Copy link
Collaborator

fubhy commented Apr 19, 2023

Right. We should probably completely remove the esModuleInterop setting from our tsconfig to guard against this (but not sure if that would have helped here)

@sxzz
Copy link
Contributor Author

sxzz commented Apr 19, 2023

but i wonder if anyone has some insights on Vite

Vite or Rollup is an ES module bundler and it will strictly treat the modules. It won't convert or interop the code by default. But webpack will.

All in all, Webpack has more compatibility and Vite respects the specs more (even though some specs are very weird)

@fubhy
Copy link
Collaborator

fubhy commented Apr 19, 2023

but i wonder if anyone has some insights on Vite

Vite or Rollup is an ES module bundler and it will strictly treat the modules. It won't convert or interop the code by default. But webpack will.

All in all, Webpack has more compatibility and Vite respects the specs more (even though some specs are very weird)

Yeah exactly. We should follow the strictest possible setup. 100% agree.

@nissoh
Copy link

nissoh commented Apr 19, 2023

but i wonder if anyone has some insights on Vite

Vite or Rollup is an ES module bundler and it will strictly treat the modules. It won't convert or interop the code by default. But webpack will.
All in all, Webpack has more compatibility and Vite respects the specs more (even though some specs are very weird)

Yeah exactly. We should follow the strictest possible setup. 100% agree.

are we good with @sxzz solution?

can we merge this?

@sxzz
Copy link
Contributor Author

sxzz commented Apr 19, 2023

@fubhy seems that esModuleInterop is unnecessary to be disabled. esModuleInterop is enabled by default in the default template of Vite projects.

@sxzz
Copy link
Contributor Author

sxzz commented Apr 19, 2023

FYI interopDefault is extremely complicated. See the table https://sokra.github.io/interop-test/

@fubhy
Copy link
Collaborator

fubhy commented Apr 19, 2023

@fubhy seems that esModuleInterop is unnecessary to be disabled. esModuleInterop is enabled by default in the default template of Vite projects.

It might not be necessary for vite projects. I just noticed that it was enabled and it imho shouldn't be. Libraries shouldn't assume any interop whatsoever imho.

FYI interopDefault is extremely complicated. See the table https://sokra.github.io/interop-test/

Yeah. I deep dived into that very topic not long ago as I was bumping a few of my own projects to TS5, NodeNext, etc. and revamped the build setup along the way. Complicated indeed.

@sxzz
Copy link
Contributor Author

sxzz commented Apr 19, 2023

@fubhy I just checked. There's no import default or export default in viem codebase. So I guess it won't change anything, so we can safely disable this option. Done.

@fubhy
Copy link
Collaborator

fubhy commented Apr 19, 2023

@fubhy I just checked. There's no import default or export default in viem codebase. So I guess it won't change anything, so we can safely disable this option. Done.

Yeah. It'd basically act as a safe guard to prevent us from introducing sth. like that down the line by accident. I already opened #391 :)

@sxzz
Copy link
Contributor Author

sxzz commented Apr 19, 2023

@fubhy Oh I revert my commit.

@sxzz
Copy link
Contributor Author

sxzz commented Apr 26, 2023

@jxom Is this PR still needed? I noticed #399 is fixed it.

@vercel
Copy link

vercel bot commented May 3, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
viem ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 3, 2023 3:50pm

@codecov
Copy link

codecov bot commented May 3, 2023

Codecov Report

Merging #390 (2daedc3) into main (9f71067) will decrease coverage by 4.71%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main     #390      +/-   ##
==========================================
- Coverage   99.93%   95.22%   -4.71%     
==========================================
  Files         270      267       -3     
  Lines       22974    22335     -639     
  Branches     1963     1748     -215     
==========================================
- Hits        22958    21269    -1689     
- Misses         16     1060    +1044     
- Partials        0        6       +6     
Impacted Files Coverage Δ
src/clients/transports/webSocket.ts 100.00% <100.00%> (ø)
src/utils/rpc.ts 100.00% <100.00%> (ø)

... and 48 files with indirect coverage changes

@jxom
Copy link
Member

jxom commented May 7, 2023

Let's put this PR on hold for now as isomorphic-ws is working now (at least I think lol). If anymore issues arise, we can consider switching to this!

@jxom jxom closed this May 7, 2023
@sxzz sxzz deleted the feat/unws branch May 8, 2023 07:29
@nissoh
Copy link

nissoh commented May 21, 2023

@sxzz @jxom i'm still having issues transpiling with tsc a standalone project without a bunlder with both esModuleInterop and allowSyntheticDefaultImports turned on

this is reproducible by cloning https://github.com/GMX-Blueberry-Club/Puppet

building by running pnpm run build in @gambitdao-gmx-middleware package would throw

../node_modules/.pnpm/[email protected][email protected]/node_modules/viem/dist/types/utils/rpc.d.ts:2:15 - error TS2595: 'WebSocket' can only be imported by using a default import.

@nissoh
Copy link

nissoh commented May 30, 2023

@jxom @fubhy ping fine sers (;

@kolirt
Copy link

kolirt commented Jun 23, 2023

@sxzz @jxom i'm still having issues transpiling with tsc a standalone project without a bunlder with both esModuleInterop and allowSyntheticDefaultImports turned on

this is reproducible by cloning https://github.com/GMX-Blueberry-Club/Puppet

building by running pnpm run build in @gambitdao-gmx-middleware package would throw

../node_modules/.pnpm/[email protected][email protected]/node_modules/viem/dist/types/utils/rpc.d.ts:2:15 - error TS2595: 'WebSocket' can only be imported by using a default import.

same problem. any solutions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants