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

Fix web3 entry points #352

Merged
merged 1 commit into from
May 18, 2024
Merged

Fix web3 entry points #352

merged 1 commit into from
May 18, 2024

Conversation

nop33
Copy link
Member

@nop33 nop33 commented May 17, 2024

Web3 uses some Node.js core modules, which are not available in a browser env (ex: Buffer).
Web3 should work for both a Node.js env, as well as a browser env. That's why it provides 2 entry points, the second of which is polyfilled using webpack:

https://github.com/alephium/alephium-web3/blob/master/packages/web3/package.json#L6-L7

  "main": "dist/src/index.js",
  "browser": "dist/alephium-web3.min.js",

In theory, this means that when the package is imported in a Node.js env, the first path will be used, and when it's imported in a browser env, the second path will be used.

In practice, however, only the first path is being used, no matter the environment. We can confirm this with the desktop wallet and explorer, which are browser environments. Both are importing the dist/src/index.js path. This is problematic because we are forced to polyfill Node.js core modules on our side as well, which is redundant, since web3 already does it.

The reason why this happens is that the web3 package.json configuration is problematic. The problem is in the "exports" key:

https://github.com/alephium/alephium-web3/blob/master/packages/web3/package.json#L9-L12

  "exports": {
    ".": "./dist/src/index.js",
    "./test": "./dist/src/test/index.js"
  },

Reading the docs of exports:

The "exports" provides a modern alternative to "main" allowing multiple entry points to be defined, conditional entry resolution support between environments, and preventing any other entry points besides those defined in "exports". This encapsulation allows module authors to clearly define the public interface for their package.

For new packages targeting the currently supported versions of Node.js, the "exports" field is recommended. For packages supporting Node.js 10 and below, the "main" field is required. If both "exports" and "main" are defined, the "exports" field takes precedence over "main" in supported versions of Node.js.

https://nodejs.org/api/packages.html#package-entry-points

Further diving into the docs, I believe that the correct configuration should be this:

  "exports": {
    "node": "./dist/src/index.js",
    "default": "./dist/alephium-web3.min.js"
  },
  • "node" - matches for any Node.js environment. Can be a CommonJS or ES module file. In most cases explicitly calling out the Node.js platform is not necessary.
  • "default" - the generic fallback that always matches. Can be a CommonJS or ES module file. This condition should always come last.

https://nodejs.org/api/packages.html#dual-commonjses-module-packages

I've tested the above with desktop wallet, mobile wallet, and explorer and it works. We no longer need to polyfill Node.js core modules. I've also created a very simple Node app to test that it works well in Node.js environments as well:

// index.js
const web3 = require('@alephium/web3')
console.log(web3)

//package.json
{
  "name": "test-project",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "@alephium/web3": "0.38.0"
  }
}
> node index.js
{
  web3: {
    setCurrentNodeProvider: [Function: setCurrentNodeProvider],
...

Remarks

As the JS environment evolves, many of the Node.JS core modules start becoming available for the web. For example, Buffer can be replaced by Uint8Array, which is an extension of Buffer that is compatible for both node and web envs (in fact, it's already been used in @alephium/web3). Another example is the Node.js core module crypto which could potentially be replaced by the web crypto API https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API

@polarker
Copy link
Member

@nop33 Thanks a lot for the post and the fix!

We will use Uint8Array to replace Buffer when we have more bandwidth. Web crypto is still limited for our use case as I checked before.

@polarker polarker merged commit 8c18457 into master May 18, 2024
8 checks passed
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.

2 participants