Skip to content

Detect require vs. import based on the entry point, not package.json #39353

Closed
@Pomax

Description

@Pomax

Is your feature request related to a problem? Please describe.

Node does not require a package.json file to run, unless you're writing modern import/export code, in which case you suddenly need to define a package.json even if you have no intention of creating a project out of the code you just wrote. You can't even use node --input-type=module because it will --for no reason that makes sense for users-- complain that you Cannot use import statement outside a module, the thing we're literally saying that's what we're doing by using that flag.

Describe the solution you'd like

Node should not need folks to tell it which parsing mode to use: it should scan the entry point it's being asked to run, and simply check whether or not the reserved JS keyword import is found in that file. If it is, done: run in ES module mode without needing folks to create a file that Node should not rely on to do its job.

  • node is invoked with a file as run target
  • node scans that files for the import keyword
  • if it's found, node runs the target in ES module mode
    • any use of require(...) during the run is now a perfectly normal "this function is not defined in this scope" error.
  • if it's not found, node runs the target in CJS mode
    • any instance of import during the run is now a perfectly normal "import is a reserved keyword" error.
    • any instance of the dynamic import(...) during the run is now a perfectly normal "this function is not defined in this scope" error.

And now Node does the correct thing, given perfectly normal code as run target. Will that very first step add to the startup time before code actually runs? Sure, but scanning for the import keyword takes on the order of nanoseconds, not milliseconds. We're not scanning the entire dependency tree to see if somewhere down the line we suddenly switch from import to require or vice versa: by default, without a package.json, Node doesn't need to mix and match: as default behaviour Node should run both legacy CJS and modern JS (either/or, not a mix, obviously) without runtime flags or needing files that have nothing to do with Node itself created.

Describe alternatives you've considered

There are no alternatives: Node should not rely on package.json just to run normal modern code, it should do the right thing automatically, with runtime flags and package.json only for folks who need it to do something else (and it should probably never need package.json, that file is so that NPM can do proper package management. Node should never need to consult it just to run normal, valid, modern or legacy, JS)

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestIssues that request new features to be added to Node.js.help wantedIssues that need assistance from volunteers or PRs that need help to proceed.moduleIssues and PRs related to the module subsystem.stale

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions