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

commonjs: hoists conditionally require()'d ESM side effects #1177

Closed
privatenumber opened this issue Apr 29, 2022 · 5 comments
Closed

commonjs: hoists conditionally require()'d ESM side effects #1177

privatenumber opened this issue Apr 29, 2022 · 5 comments

Comments

@privatenumber
Copy link

privatenumber commented Apr 29, 2022

Input

index.js

if (process.env.NODE_ENV === 'production') {
	require('./prod.js');
}

prod.js

console.log('side effect');

export default 'production';

Output

var src = {};

console.log('side effect');

if (process.env.NODE_ENV === 'production') ;

export { src as default };

Expected Behavior

For the console.log('side effect'); to be delayed until the if-condition passes.

Note, this only happens because prod.js is an ESM file. If the export ... is removed for it to be interpreted as a CJS file, it will compile expectedly:

var src = {};

var prod = {};

var hasRequiredProd;

function requireProd () {
	if (hasRequiredProd) return prod;
	hasRequiredProd = 1;
	console.log('side effect');

	// export default 'production';
	return prod;
}

if (process.env.NODE_ENV === 'production') {
	requireProd();
}

export { src as default };

Actual Behavior

The side effects of the ESM file are hoisted up and executed even if the if-condition doesn't pass.

Additional Information

@lukastaegert
Copy link
Member

Yes, conditional requires are only properly supported for CJS targets because it relies on wrapping the target in a function that is later tree-shaken if unused. I currently would not know how to implement that for ESM, we cannot just wrap ES modules in functions.

@privatenumber
Copy link
Author

Thanks for the explanation! Is it possible to emit a warning if its not fully supported?


Just curious--in which cases does it not make sense to wrap the module in a function?

@lukastaegert
Copy link
Member

Thanks for the explanation! Is it possible to emit a warning if its not fully supported?

PR welcome I guess

Just curious--in which cases does it not make sense to wrap the module in a function?

Whenever you want to only execute it conditionally, or whenever you really need to stick to the strict Node execution order as Node itself works this way.

@stale stale bot added the x⁷ ⋅ stale label Jul 10, 2022
@stale
Copy link

stale bot commented Jul 12, 2022

Hey folks. This issue hasn't received any traction for 60 days, so we're going to close this for housekeeping. If this is still an ongoing issue, please do consider contributing a Pull Request to resolve it. Further discussion is always welcome even with the issue closed. If anything actionable is posted in the comments, we'll consider reopening it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants