-
Notifications
You must be signed in to change notification settings - Fork 778
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
Uncaught TypeError: Common is not a constructor #978
Comments
Hi there, I can indeed reproduce this, I am not yet sure if this is a bug or not since we use these imports a lot in the package without any problem. That might be because these run on typescript? Any thoughts here @holgerd77 @ryanio ? Anyways, you can temporarily fix the problem using this; import {default as common} from '@ethereumjs/common';
const Common = common.default
const c = new Common({ chain: 'ropsten' }) |
that's weird.
what happens if you try i'm also not too familiar with node v15 yet and what changes may be affecting this, can you try on node v12? |
|
@jochem-brouwer Yes with @ryanio Sam with v12 |
Can also reproduce, adding to the analysis here. Put the following code into a script import Common from '@ethereumjs/common'
const c = new Common({ chain: 'ropsten' }) The {
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@ethereumjs/common": "^2.0.0"
},
"type": "module"
} Following behavior:
Running with |
I just reported the same problem here.
This is because ESM support landed in node v13.2.0. It seems TSC is flakely supporting ESM A way to use them is explained here. However, when vm's {
"extends": "@ethereumjs/config-typescript/tsconfig.prod.json",
"compilerOptions": {
"outDir": "./dist",
"lib": ["dom"],
"resolveJsonModule": true,
"target": "ES2015",
"module": "ES2015"
},
"include": ["lib/**/*.ts"]
} A new problem with arise. When now trying to import, node will complain that no file type extensions are used. Node.js file extensions in the node index.mjs
internal/process/esm_loader.js:74
internalBinding('errors').triggerUncaughtException(
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/user/Projects/ethereumjs-monorepo/packages/vm/dist/state/index' imported from /Users/user/
Projects/ethereumjs-monorepo/packages/vm/dist/index.js
at finalizeResolution (internal/modules/esm/resolve.js:276:11)
at moduleResolve (internal/modules/esm/resolve.js:699:10)
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:810:11)
at Loader.resolve (internal/modules/esm/loader.js:86:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:230:28)
at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:56:40)
at link (internal/modules/esm/module_job.js:55:36) {
code: 'ERR_MODULE_NOT_FOUND'
} So can we somehow magically add file extensions to the files of dist? TSC has decided that they don't want to add file extensions for imports. There's good reasons they won't automatically add it. It's because a compiler wouldn't be able to know when to add what extension. For details see this comment "Fact 2: It's not as simple as "add extension"". |
esm support has landed in TypeStrong/ts-node#1007 |
Update: this issue is important and should get some more attention. |
Thanks @TimDaub for sharing. hmmm, just reviewing the whole issue, so the crux of the problem seems to be that typescript doesn't output A suggested solution on the consumer side seems to be that you can reference the If we provide When I get some time I will try to answer these questions for myself and report back with results. |
You can find the (hopefully) reproducible introductions to the problems here: #1131
In the past Anyways, I'm not aware that JavaScript had a standardized approach for opening an organization scope e.g. @ethereumjs in the ModuleSpecifier. I think that's something informal some projects use, but I'm not sure (nodejs subpath exports). Anyways, if I can do smth like:
I don't know, we can of course try it.
I'm not sure if it is possible to write trivial code that transforms In Feb I posted that TSC is not supporting |
This is also not "the solution" [tm], but I guess it would ease things (mid-term) if we - as we are already planning for the VM - remove the import { Common } from '@ethereumjs/common' Have added this to the v6 (so: all breaking releases) planning notes. Let me know if this assumption is false though. Update: respectively I assume we can directly do this in parallel respectively export both like we have done (or: have not done yet, still not merged) on the wallet library here: ethereumjs/ethereumjs-wallet#145 Can someone please confirm that this would improve things? 😄 |
(changes to the comment, please read on-site and not in your mail client) |
Additional note: I've done a search for "export default class" throughout the monorepo and this actually reveals a lot of occurrences (26 results). So this is somewhat of a bigger decision and effort (manageable though) and should be handled and decided with some minimal care. Also: is "export default function" also a problem? |
Did a test on this and this impressively did not solve the issue. So I adopted the Then I created a file import { Common } from '@ethereumjs/common'
const c = new Common({ chain: 'mainnet' }) This resulted in: import { Common } from '@ethereumjs/common'
^^^^^^
SyntaxError: Named export 'Common' not found. The requested module '@ethereumjs/common' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from '@ethereumjs/common';
const { Common } = pkg; I then tested this solution proposed with the original unedited Common version but this comes back to: const common = new Common({ chain: 'baikal', hardfork: 'london' })
^
TypeError: Common is not a constructor Phew. 🙁 |
Haven't digged deeper, but here is a proposed solution to create hybrid modules supporting ESM and CommonJS with TypeScript as a source: https://www.sensedeep.com/blog/posts/2021/how-to-create-single-source-npm-module.html Would need some analysis what this means for our codebase and distribution process and what might be potential pitfalls or drawbacks though. |
Update: I am just through the article, still sounds interesting too me, nevertheless some substantial change to our build process if we decide to do. One can test such a module in practice by doing |
Hey, I think you'll have to pick between either Anyways here's the import results they should yield export default class Common {}
// should allow you to use the following import statement in another file
import Common from "@ethereumjs/common"; export class Common {}
// should allow you to use the following import statement in another file
import { Common } from "@ethereumjs/common"; class Common {}
export { Common };
// should allow you to use the following import statement in another file
import { Common } from "@ethereumjs/common"; |
I believe this is the problem I have with Typescript. That its output is an ES5 build with CommonJS modules (probably using
Looks interesting. I'll also give it a read once I have time. |
From my side, no. I'm fine with using a library that exports a function. It's equivalent to the following commonJS syntax: module.exports = function add(a, b) { return a+b };
// is equivalent to ESM
function add(a, b) { return a+b };
export default add; |
Running into this issue as well |
Everyone is |
I also faced a similar issue. After some hardcore searches and debugging, I got a fix for this. Let me know if this works. |
FYI, maybe the issue can be resolved by following this guide: https://2ality.com/2019/10/hybrid-npm-packages.html |
Just to add that we have also an issue open on this (opened couple of days ago): #1468 @TimDaub thanks, I am also taking this one since it's a bit newer and might be a bit more up-to-date (?) on the issue. Would it work if we do an additional ESM build to "files": [
"dist",
"dist.browser",
"dist.esm",
"src"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"browser": "dist.browser/index.js",
"module": "dist.esm/index.js",
"exports": {
".": {
"import": "./dist.esm/index.js",
"require": "./dist/index.js"
}
} Ah, I am just seeing: how do we get our |
I have the same problem. I would like a solution out of the box, without reading the manuals for solving compatibility. |
@coderbara Sorry we need to add this to our Common README (I will do this today), the solution is to use
This is because we have not shipped esm support yet (in progress #1654), so you need to load the code using CommonJS |
I will be opening an ESM PR for develop today that will solve this issue when released |
This should be mitigated by the removal of all default exports in the monorepo along with the breaking releases (VM v6 and others), see #2018, will close. |
My Nodejs version is
v15.1.0
and mypackage.json
looks like -In my code I do -
Which gives me
Uncaught TypeError: Common is not a constructor
. I also tried withimport { Common } from '@ethereumjs/common';
andimport * as Common from '@ethereumjs/common';
but still the same.Is this a bug? Or I am doing something wrong?
The text was updated successfully, but these errors were encountered: