ethereum / js-ethereum-cryptography

Every cryptographic primitive needed to work on Ethereum, for the browser and Node.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Missing crypto module when building the project using ncc and Webpack

cds95 opened this issue · comments

Hi everyone, this may or may not be an issue with js-ethereum-cryptography itself but rather an issue with @vercel/ncc and webpack builds. I'm posting it here anyways in case anyone has any ideas on what is going on.

Issue
I have a project that is using a dependency that is dependent on the keccak file from ethereum-cryptography@1.0.3. I then bunde my project into a single JS file using the ncc build command from this project, which uses Webpack internally.

Now the issue is that ncc transforms this code to the code below as ncc can't find the crypto package for some reason:

/***/ 84310:
/***/ ((module) => {

function webpackEmptyContext(req) {
	var e = new Error("Cannot find module '" + req + "'");
	e.code = 'MODULE_NOT_FOUND';
	throw e;
}
webpackEmptyContext.keys = () => ([]);
webpackEmptyContext.resolve = webpackEmptyContext;
webpackEmptyContext.id = 84310;
module.exports = webpackEmptyContext;
/***/ }),

This leads to my project crashing with this error when I try run it:

Error: Cannot find module 'crypto'
    at Object.webpackEmptyContext (/Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:183577:10)
    at /Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:83270:43
    at Object.78777 (/Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:83273:3)
    at __nccwpck_require__ (/Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:183842:43)
    at Object.35681 (/Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:83194:17)
    at __nccwpck_require__ (/Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:183842:43)
    at Object.30038 (/Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:169615:16)
    at __nccwpck_require__ (/Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:183842:43)
    at Object.55944 (/Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:168123:14)
    at __nccwpck_require__ (/Users/christophersastropranoto/Documents/external-adapters-js/packages/sources/layer2-sequencer-health/bundle/index.js:183842:43) {
  code: 'MODULE_NOT_FOUND'
}

I've confirmed that this issue is also happening when I try to build the ethereum-cryptography package by itself.

Steps to repro

Run from the root of the ethereum-cryptography repository.

  1. Add @vercel/ncc package yarn add @vercel/ncc
  2. Build the keccak.ts file. ncc build keccak.js -o bundle/index.js
  3. This should have created a new directory named bundle in the root folder with an index.js file. Inspect the generated index.js file and find the code below
exports.crypto = (() => {
    const webCrypto = typeof self === "object" && "crypto" in self ? self.crypto : undefined;
    const nodeRequire =  true &&
        __nccwpck_require__(387).bind(module); ------>. The node ID might be different
    return {
        node: nodeRequire && !webCrypto ? nodeRequire("crypto") : undefined,
        web: webCrypto
    };
})();
  1. The module with ID 387 resolves to the code below
/***/ 387:
/***/ ((module) => {

function webpackEmptyContext(req) {
	var e = new Error("Cannot find module '" + req + "'");
	e.code = 'MODULE_NOT_FOUND';
	throw e;
}
webpackEmptyContext.keys = () => ([]);
webpackEmptyContext.resolve = webpackEmptyContext;
webpackEmptyContext.id = 387;
module.exports = webpackEmptyContext;

Expected Behavior

Running ncc build does not generate a webpackEmptyContext function when looking for the crypto module.

Versions

@vercel/ncc: 0.34.0

Any suggestions on what to check are appreciated! Thanks in advance.

The code is tested with webpack and rollup, so the problem seems to be in your configuration. Report this to NCC.

@paulmillr Hey thanks for responding. I'll open an issue in NCC but I wanted to mention that I didn't configure anything when I built this project directly. I just pulled this repo and ran these steps from the root of the ethereum-cryptography repository to check that NCC bundled the project correctly on it's own.

  1. Add @vercel/ncc package yarn add @vercel/ncc
  2. Build the keccak.ts file. ncc build keccak.js -o bundle/index.js
    This should have created a new directory named bundle in the root folder with an index.js file. Inspect the generated index.js file and find the code below
exports.crypto = (() => {
    const webCrypto = typeof self === "object" && "crypto" in self ? self.crypto : undefined;
    const nodeRequire =  true &&
        __nccwpck_require__(387).bind(module); ------>. The node ID might be different
    return {
        node: nodeRequire && !webCrypto ? nodeRequire("crypto") : undefined,
        web: webCrypto
    };
})();

The module with ID 387 resolves to the code below

/***/ 387:
/***/ ((module) => {

function webpackEmptyContext(req) {
	var e = new Error("Cannot find module '" + req + "'");
	e.code = 'MODULE_NOT_FOUND';
	throw e;
}
webpackEmptyContext.keys = () => ([]);
webpackEmptyContext.resolve = webpackEmptyContext;
webpackEmptyContext.id = 387;
module.exports = webpackEmptyContext;

@cds95 right -- even if you did not configure anything specifically, vercel/ncc executes some configuration on its own.

Gotcha ok. I've gone ahead and opened an issue with NCC.