trufflesuite / truffle

:warning: The Truffle Suite is being sunset. For information on ongoing support, migration options and FAQs, visit the Consensys blog. Thank you for all the support over the years.
https://consensys.io/blog/consensys-announces-the-sunset-of-truffle-and-ganache-and-new-hardhat?utm_source=github&utm_medium=referral&utm_campaign=2023_Sep_truffle-sunset-2023_announcement_
MIT License
14.02k stars 2.32k forks source link

Support ESM #4328

Open soulofmischief opened 2 years ago

soulofmischief commented 2 years ago

Issue

Truffle doesn't support ESM.

Steps to Reproduce

  1. Set "type": "module" in package.json.
  2. Run truffle.

Expected Behavior

The config loads, and ESM imports are correctly handled.

Actual Results

The configuration doesn't load, because the original-require package which ingests truffle-config.js uses require and not import. The error suggests to change the extension to .cjs, but this just causes a cascade of needing to change extensions until the entire project is .cjs files and no longer a module.

It's impossible to use latest versions of popular tools such as node-fetch which have switched over to ESM, and it's causing dependency rot.

Environment

dongmingh commented 2 years ago

We will look into this issue. Thanks for raising this!

soulofmischief commented 2 years ago

Thank you!

For anyone snooping for an intermediate fix for ESM packages like node-fetch:

esm.js

const
  fetchPromise = import( 'node-fetch' ).then( mod => mod.default ),
  fetch = ( ...args ) => fetchPromise.then( fetch => fetch( ...args ))

module.exports = { fetch }

This is because dynamic import() is still supported by CommonJS.

Fardinak commented 2 years ago

Any temporary workarounds for this? Changing the truffle-config file extension to .cjs and invoking commands returns the following:

Could not find suitable configuration file.
Truffle v5.5.3 (core: 5.5.3)
Node v17.6.0
Fardinak commented 2 years ago

Just found a (seemingly undocumented) --config CLI argument that helped with that.

eggplantzzz commented 2 years ago

@Fardinak so Truffle looks explicitly for truffle-config.js, if you rename it it will not find it. But you found the workaround; namely to pass the --config flag to the file.

Fardinak commented 2 years ago

@eggplantzzz Yes, but unfortunately that did not prove useful in my case after all; since I'm also using Ganach. I gave up when I couldn't add my project.

In the end, I had to move the Truffle directory structure into a subdirectory and add a package.json with type: "commonjs" to work around the issue.

benjamincburns commented 2 years ago

I ran into this while implementing TypeScript support for migrations.

There are likely numerous things that need to be done to support this, and I think the NodeJS docs on the differences between ES modules and CommonJS are a good starting place to identify what needs to be done.

Proper ESM support will likely require several changes to @truffle/require (among other modules).