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

require.main === module is different after ncc (again) #748

Closed
KengoTODA opened this issue Aug 12, 2021 · 8 comments
Closed

require.main === module is different after ncc (again) #748

KengoTODA opened this issue Aug 12, 2021 · 8 comments
Assignees
Labels
enhancement New feature or request

Comments

@KengoTODA
Copy link

Thanks for sharing great tool to minify TS code, I'm using ncc so heavily for my GitHub Actions projects :)

Today I found an unexpected behavior same to the #224. I confirmed that v0.27.0 works fine but v0.28.0 doesn't, so there is a regression during 0.27.0...0.28.0 I guess.

I've investigated about why this regression comes again even though #229 added a unit test?
It seems that v0.14 has the test case but v0.15 does not have it, it seems that 8abb4ba (#264) removed the test case.

@KengoTODA
Copy link
Author

KengoTODA commented Aug 12, 2021

Here is the PR fixing problem in my repo. It downgraded ncc from v0.29.0 to v0.27.0.

v0.29.0 uses __nccwpck_require__.c[__nccwpck_require__.s] === module which does not work, and
v0.27.0 uses require.main === require.cache[eval('__filename')] which works fine.

__nccwpck_require__.c[__nccwpck_require__.s] is an object like { id: 930, loaded: false, exports: Object [Module] { run: [Getter] } }, and module is an object like { children: [], exports: [Setter] }

Point is that, ncc v0.29.0 can build the minimal case console.log(require.main === module); without problem. It generates console.log(require.main === require.cache[eval('__filename')]); just like v0.27.0. So maybe there is hidden conditions to use __nccwpck_require__.c[__nccwpck_require__.s] === module but I'm still not so sure.

@guybedford
Copy link
Contributor

Point is that, ncc v0.29.0 can build the minimal case console.log(require.main === module); without problem

I can verify that:

test.js

console.log(require.main === module);

with ncc run test.js works just fine as you say.

So the question then is - under what conditions are you finding this fails?

Looking at your code you are running this check in an ES module file - that may actually be the issue here in that require.main and module aren't supposed to be defined in ES modules.

There is a way to do this same check in ES modules in Node.js although it is a little bit complex:

import { pathToFileURL } from 'url';
import process from 'process';
if (import.meta.url === pathToFileURL(process.argv[1]).href)
  console.log('MAIN');

I just tested the above pattern in ncc, and unfortunately it appears that doesn't seem to be supported.

In that case I'd suggest we treat this issue as a feature request for the above pattern to be supported rather.

@guybedford
Copy link
Contributor

(the test is still present and working just fine at https://github.com/vercel/webpack-asset-relocator-loader/tree/main/test/unit/require-main)

@guybedford guybedford added enhancement New feature or request and removed bug Something isn't working labels Aug 19, 2021
@guybedford
Copy link
Contributor

The reason import.meta doesn't work here is that there doesn't seem to be a way to run a build that exposes import.meta to the output file - webpack always substitutes it even when doing a module build output.

@sokra are there any plans or ways to permit pass-through of import.meta for this kind of use case when outputting modules?

@KengoTODA
Copy link
Author

Thank you! Your comment helped me a lot to clarify what is happening.
But I'm still not so clear about the problem, could you help me to understand:

How you found that the project is built as an ES module?
I think there is no related configuration in both tsconfig.json and package.json... 🤔

Thanks again for your support!

@KengoTODA
Copy link
Author

According to the readme.md:

If building an .mjs or .js module inside a "type": "module" package boundary, an ES module output will be created automatically.

But in my project there is no "type": "module" in package.json.

@styfle
Copy link
Member

styfle commented Sep 9, 2021

How you found that the project is built as an ES module?
I think there is no related configuration in both tsconfig.json and package.json...

@KengoTODA I think the TS bug is fixed in 0.31.0.

Please give it a try, thanks!

@KengoTODA
Copy link
Author

Thanks @styfle, I've confirmed @vercel/ncc v0.31.0 generates require.main === require.cache[eval('__filename')] as expected!

I'll close this issue. @guybedford @styfle Thank you again :) 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants