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

Fixes: #56518 - Warning Message for .cjs Files Using import Statements #56618

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

wongprom
Copy link

Summary

This PR introduces the following changes to address issue #56518:

Add a specific warning for .cjs files using import statements:

  • Displays a clear error message to inform users that .cjs files do not support import and advises them to use require() instead.

Update tests:

  • Added a test case in test/es-module/test-cjs-esm-warn.js to validate the warning message.
  • Test compares the exact string value of the warning for now but could be optimized in the future to validate only the critical parts of the message.

Refactored src/node_contextify.cc:

  • Added GetFileExtension and GetWarningMessage helper functions for better code readability and modularity.

Details

Testing:

  • Verified the changes with the test suite using make -j6 test. All tests passed successfully.
  • Validated linting with make lint.

Changes:

  • Removed the temporary jimmy.cjs test file after confirming its purpose was fulfilled during development.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

  1. The contribution was created in whole or in part by me, and I have the right to submit it under the open source license indicated in the file.
  2. The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part, by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file.
  3. The contribution was provided directly to me by some other person who certified (1), (2), or (3) and I have not modified it.
  4. I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.

Additional Notes

  • The test compares the exact warning string. Future improvements could involve matching only essential parts of the message for better flexibility.

…y.cc

- Added a utility function GetFileExtension to extract file extensions from filenames.
- Enhanced the require_esm_warning logic to dynamically generate appropriate error messages based on file extensions.
- Included a TODO comment to enhance error messages further with specific package.json file locations if applicable.
- Cleaned up and removed redundant code for better maintainability and clarity.
- Extracted warning message logic into a dedicated `GetWarningMessage` function.
- Encapsulated file extension handling and warning generation for improved reusability.
- Updated relevant code sections to use the new factory-style function.
- Aligns with existing design patterns and improves maintainability.
- Added new tests for invalid imports in .cjs files.
- Added tests for loading .mjs files in CommonJS packages.
- Refactored assertions to align with project lint rules.
- Verified all tests pass with Node.js tools and addressed related errors.
- Formatted src/node_contextify.cc using clang-format for consistent code style.

Refs: nodejs#56518
- Updated `GetWarningMessage` in `node_contextify.cc` to handle `.cjs` files and emit appropriate warnings.
- Normalized the warning message in tests to simplify comparison and improve readability.
- Added specific tests to verify warnings for invalid imports in `.cjs` files and handling of `.mjs` in CommonJS packages.

Note: The test currently compares the exact string value for warnings. This could be optimized by validating only the critical parts of the warning message.

Refs: nodejs#56518
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. vm Issues and PRs related to the vm subsystem. labels Jan 15, 2025

std::string GetWarningMessage(const std::string& file_extension) {
if (file_extension == ".cjs") {
return "Cannot use 'import' statement in a .cjs file. "
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be also caused by e.g. top-level await. It would be confusing to directly suggest import as the cause of the parse error without checking the error messages (which are available in as cjs_message in CompileFunctionForCJSLoader).

// Convert an int to a V8 Name (String or Symbol).
Local<Name> Uint32ToName(Local<Context> context, uint32_t index) {
return Uint32::New(context->GetIsolate(), index)->ToString(context)
return Uint32::New(context->GetIsolate(), index)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revert the unrelated formatting changes? These would make backporting harder.

std::string file_extension = GetFileExtension(filename_utf8.ToStringView());
// TODO(wongprom): Enhance require_esm_warning to include
// the specific package.json file location, if applicable.
std::string require_esm_warning = GetWarningMessage(file_extension);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to only construct right before emitting the warning, otherwise it's going to be an overhead even on paths that would just retry with a successful detection and not emit the warning.

`Error [ERR_REQUIRE_ESM]: require() of ES Module ${required} from ${requiringCjsAsEsm} not supported.\n`
)
);
assert.ok(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you either use assert.match or spawnSyncAndAssert (see https://github.com/nodejs/node/blob/99e0d0d2186065aa8ca9ab7cd94e1637bb166220/test/common/README.md#spawnsyncandexitcommand-args-spawnoptions-expectations )? Otherwise when mismatches happen it would be very difficult to see why without modifying the source and re-running it in e.g. the CI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. vm Issues and PRs related to the vm subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants