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

Experimental esm support #14

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
HARDHAT_TYPECHECK=false

# network specific node uri : `"ETH_NODE_URI_" + networkName.toUpperCase()`
ETH_NODE_URI_MAINNET=https://eth-mainnet.alchemyapi.io/v2/<apiKey>
# generic node uri (if no specific found) :
Expand Down
35 changes: 35 additions & 0 deletions .mocharc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';
process.env.TS_NODE_FILES = true;
function stringToBoolean(val, defaultVal) {
const strValue = String(val).toLowerCase();
switch (strValue) {
case 'true':
case '1':
return true;
case 'false':
case '0':
return false;
default:
return defaultVal; // Default to 'defaultVal' if the value is not recognized
}
}
module.exports = {
'allow-uncaught': true,
diff: true,
extension: ['ts'],
recursive: true,
reporter: 'spec',
require: ['ts-node/register', 'hardhat/register'], // ['ts-node/register/transpile-only'], (for yarn link <plugin>)
'node-option': [
'experimental-specifier-resolution=node',
`loader=ts-node/esm${stringToBoolean(process.env.HARDHAT_TYPECHECK, false) ? '' : '/transpile-only'}`,
'no-warnings=ExperimentalWarning',
'enable-source-maps',
],
slow: 300,
spec: 'test/**/*.test.ts',
timeout: 20000,
ui: 'bdd',
watch: false,
'watch-files': ['src/**/*.sol', 'test/**/*.ts'],
};
16 changes: 0 additions & 16 deletions .mocharc.js

This file was deleted.

8 changes: 4 additions & 4 deletions .prettierrc.js → .prettierrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ module.exports = {
options: {
printWidth: 120,
singleQuote: false,
parser: 'solidity-parse'
}
}
parser: 'solidity-parse',
},
},
],
plugins: [require('prettier-plugin-solidity')]
plugins: [require('prettier-plugin-solidity')],
};
File renamed without changes.
23 changes: 23 additions & 0 deletions _scripts.js → _scripts.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ const {spawn} = require('child_process');
const path = require('path');
require('dotenv').config();

function stringToBoolean(val, defaultVal) {
const strValue = String(val).toLowerCase();
switch (strValue) {
case 'true':
case '1':
return true;
case 'false':
case '0':
return false;
default:
return defaultVal; // Default to 'defaultVal' if the value is not recognized
}
}

// Conditionally set NODE_OPTIONS based on HARDHAT_TYPECHECK
const nodeOptions = `--loader ts-node/esm${
stringToBoolean(process.env.HARDHAT_TYPECHECK, false) ? '' : '/transpile-only'
} --no-warnings=ExperimentalWarning`;

const commandlineArgs = process.argv.slice(2);

function parseArgs(rawArgs, numFixedArgs, expectedOptions) {
Expand Down Expand Up @@ -57,6 +76,10 @@ function execute(command) {
};
spawn(command.split(' ')[0], command.split(' ').slice(1), {
stdio: 'inherit',
env: {
...process.env,
NODE_OPTIONS: nodeOptions,
},
shell: true,
}).on('exit', onExit);
});
Expand Down
2 changes: 1 addition & 1 deletion deploy/001_deploy_simple_erc20.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DeployFunction} from 'hardhat-deploy/types';
import {DeployFunction} from 'hardhat-deploy/types.js';
import {parseEther} from 'ethers';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
Expand Down
2 changes: 1 addition & 1 deletion deploy/002_deploy_greetings_registry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {HardhatRuntimeEnvironment} from 'hardhat/types';
import {DeployFunction} from 'hardhat-deploy/types';
import {DeployFunction} from 'hardhat-deploy/types.js';

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {deployer} = await hre.getNamedAccounts();
Expand Down
30 changes: 29 additions & 1 deletion hardhat.config.ts → hardhat.config.cts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import 'dotenv/config';
import {HardhatUserConfig} from 'hardhat/types';

import {join} from 'path';
import {writeFile} from 'fs/promises';
import {subtask} from 'hardhat/config';
import {TASK_COMPILE_SOLIDITY} from 'hardhat/builtin-tasks/task-names';

import '@nomicfoundation/hardhat-chai-matchers';
import '@nomicfoundation/hardhat-ethers';
import '@typechain/hardhat';
Expand All @@ -11,7 +16,30 @@ import 'hardhat-deploy';
import 'hardhat-deploy-ethers';
import 'hardhat-deploy-tenderly';

import {node_url, accounts, addForkConfiguration} from './utils/network';
import {node_url, accounts, addForkConfiguration} from './utils/network.cjs';

// overriding 'hardhat' compile solidity task to generate "commonjs" 'package.json' for typechain after compilation
// see: https://github.com/NomicFoundation/hardhat/issues/3385#issuecomment-1841380253

subtask(TASK_COMPILE_SOLIDITY).setAction(async (_, {config}, runSuper) => {
const superRes = await runSuper();
const basePath = config.paths.root;
const packageJsonContent = '{ "type": "commonjs" }';
const paths = ['typechain-types'];

const writePackageJson = async (path: string) => {
const fullPath = join(basePath, path, 'package.json');
try {
await writeFile(fullPath, packageJsonContent);
} catch (error) {
console.error(`Error writing package.json at ${path}: `, error);
}
};

await Promise.all(paths.map(writePackageJson));

return superRes;
});

const config: HardhatUserConfig = {
solidity: {
Expand Down
46 changes: 26 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "mycontracts",
"version": "0.0.1",
"description": "",
"type": "module",
"devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "^2.0.1",
"@nomicfoundation/hardhat-ethers": "^3.0.2",
Expand All @@ -15,7 +16,7 @@
"dotenv": "^16.3.1",
"ethers": "^6.6.1",
"fs-extra": "^11.1.1",
"hardhat": "^2.16.0",
"hardhat": "^2.19.4",
"hardhat-deploy": "^0.11.34",
"hardhat-deploy-ethers": "^0.4.0",
"hardhat-deploy-tenderly": "^0.2.0",
Expand All @@ -28,27 +29,32 @@
"typescript": "^5.1.3"
},
"scripts": {
"prepare": "node ./.setup.js && hardhat typechain",
"format": "prettier --check \"**/*.{ts,js,sol}\"",
"format:fix": "prettier --write \"**/*.{ts,js,sol}\"",
"prepare": "node ./.setup.cjs && hardhat typechain",
"format": "prettier --check \"**/*.{ts,mts,cts,js,mjs,cjs,sol}\"",
"format:fix": "prettier --write \"**/*.{ts,mts,cts,js,mjs,cjs,sol}\"",
"compile": "hardhat compile",
"void:deploy": "hardhat deploy --report-gas",
"void:deploy": "cross-env NODE_OPTIONS='--loader ts-node/esm/transpile-only --no-warnings=ExperimentalWarning' hardhat deploy --report-gas",
"test": "cross-env HARDHAT_DEPLOY_FIXTURE=true HARDHAT_COMPILE=true mocha --bail --recursive test",
"gas": "cross-env REPORT_GAS=true hardhat test",
"coverage": "cross-env HARDHAT_DEPLOY_FIXTURE=true hardhat coverage",
"dev:node": "cross-env MINING_INTERVAL=\"3000,5000\" hardhat node --hostname 0.0.0.0",
"dev": "cross-env MINING_INTERVAL=\"3000,5000\" hardhat node --hostname 0.0.0.0 --watch",
"local:dev": "hardhat --network localhost deploy --watch",
"execute": "node ./_scripts.js run",
"deploy": "node ./_scripts.js deploy",
"verify": "node ./_scripts.js verify",
"export": "node ./_scripts.js export",
"gas": "cross-env NODE_OPTIONS='--loader ts-node/esm/transpile-only --no-warnings=ExperimentalWarning' REPORT_GAS=true hardhat test",
"coverage": "cross-env NODE_OPTIONS='--loader ts-node/esm/transpile-only --no-warnings=ExperimentalWarning' HARDHAT_DEPLOY_FIXTURE=true hardhat coverage",
"dev:node": "cross-env NODE_OPTIONS='--loader ts-node/esm/transpile-only --no-warnings=ExperimentalWarning' MINING_INTERVAL=\"3000,5000\" hardhat node --hostname 0.0.0.0",
"dev": "cross-env NODE_OPTIONS='--loader ts-node/esm/transpile-only --no-warnings=ExperimentalWarning' MINING_INTERVAL=\"3000,5000\" hardhat node --hostname 0.0.0.0 --watch",
"local:dev": "cross-env NODE_OPTIONS='--loader ts-node/esm/transpile-only --no-warnings=ExperimentalWarning' hardhat --network localhost deploy --watch",
"execute": "node ./_scripts.cjs run",
"deploy": "node ./_scripts.cjs deploy",
"verify": "node ./_scripts.cjs verify",
"export": "node ./_scripts.cjs export",
"hardhat": "hardhat",
"fork:execute": "node ./_scripts.js fork:run",
"fork:deploy": "node ./_scripts.js fork:deploy",
"fork:dev": "node ./_scripts.js fork:dev",
"fork:node": "node ./_scripts.js fork:node",
"fork:test": "node ./_scripts.js fork:test",
"tenderly:push": "node ./_scripts.js tenderly:push"
"fork:execute": "node ./_scripts.cjs fork:run",
"fork:deploy": "node ./_scripts.cjs fork:deploy",
"fork:dev": "node ./_scripts.cjs fork:dev",
"fork:node": "node ./_scripts.cjs fork:node",
"fork:test": "node ./_scripts.cjs fork:test",
"tenderly:push": "node ./_scripts.cjs tenderly:push"
},
"pnpm": {
"patchedDependencies": {
"[email protected]": "patches/[email protected]"
}
}
}
48 changes: 48 additions & 0 deletions patches/[email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
diff --git a/dist/src/DeploymentsManager.js b/dist/src/DeploymentsManager.js
index 9a0de00de387641947da608bef1184c6b185a072..d3e76ff1269e3c01e3c2901147f8086f577cbdc6 100644
--- a/dist/src/DeploymentsManager.js
+++ b/dist/src/DeploymentsManager.js
@@ -733,10 +733,7 @@ class DeploymentsManager {
// console.log("fetching " + scriptFilePath);
try {
delete require.cache[scriptFilePath]; // ensure we reload it every time, so changes are taken in consideration
- deployFunc = require(scriptFilePath);
- if (deployFunc.default) {
- deployFunc = deployFunc.default;
- }
+ deployFunc = await dynamicImportModule(scriptFilePath);
funcByFilePath[scriptFilePath] = deployFunc;
}
catch (e) {
@@ -1104,5 +1101,31 @@ class DeploymentsManager {
};
}
}
+async function dynamicImportModule(path) {
+ // Adjust the function to handle both ESM and CJS modules uniformly
+ let module;
+ try {
+ module = await import(path);
+ } catch (error) {
+ if (error.code === 'ERR_REQUIRE_ESM') {
+ // The error indicates that the module is an ESM
+ throw error;
+ } else {
+ // Fallback to CommonJS require
+ module = require(path);
+ }
+ }
+ // Check if the module has a 'default' property and if it looks like a wrapped CJS module
+ if (module.default && typeof module.default === 'object' && 'default' in module.default) {
+ // This is a workaround for the double 'default' wrapping issue
+ return module.default.default;
+ } else if (module.default) {
+ // Handle normal ESM default export
+ return module.default;
+ } else {
+ // Return the module directly if it's not using ESM default export
+ return module;
+ }
+}
exports.DeploymentsManager = DeploymentsManager;
//# sourceMappingURL=DeploymentsManager.js.map
Loading