Skip to content
This repository was archived by the owner on Jul 31, 2018. It is now read-only.
Closed
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
1 change: 1 addition & 0 deletions 000-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
* [Port core to uv_link_t](004-uv_link_t.md)
* [ABI Stable Module API](005-ABI-Stable-Module-API.md)
* [AsyncHooks API](006-asynchooks-api.md)
* [Extension CLI Flag](007-extension-flag.md)
57 changes: 57 additions & 0 deletions 007-extension-flag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
| Title | Implement --extension flag |
|--------|-----------------------------|
| Author | @bmeck |
| Status | DRAFT |
| Date | 2017-08-09T10:00:00-05:00 |

## Description

The Node CLI currently accepts input in both filename (`node app.js`) and opaque text stream form (`node -e '123'` and `node <app.js`). This behavior always results in running the stream as a CommonJS goal. With the upcoming usage of ESM and WASM there will be cases where developers wish to pipe other forms of text to the CLI.

Choose a reason for hiding this comment

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

Script goal and maybe also other program forms to the CLI

Choose a reason for hiding this comment

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

On second thought, I suppose that last one could also be clarified as source text if that is more consistent.


This proposal is to implement an `--entry-extension` CLI flag for the cases which may want to use a stream that does not have a file extension.

Choose a reason for hiding this comment

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

If we are defining the name here, might be worthwhile to also specify --ext as a shorter-hand. People will want to see using it as reasonable UX.

Copy link
Member Author

Choose a reason for hiding this comment

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

do we have any abbreviates -- flags?

Choose a reason for hiding this comment

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

Unsure but I don't really see an issue with it.

Copy link
Member

Choose a reason for hiding this comment

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

What about -x ?

Choose a reason for hiding this comment

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

Could use that, I suppose. Does it have any common UNIX meaning it might be confused with?

Copy link
Member Author

Choose a reason for hiding this comment

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


## Example

```sh
node --entry-extension=js <app.js
node --entry-extension=js -e $(cat <app.js)
node --entry-extension=wasm <app.wasm
node --entry-extension=wasm -e $(cat <app.wasm)
node --entry-extension=mjs <app.mjs
node --entry-extension=mjs -e $(cat <app.mjs)
```

## Considerations

If mixing `--entry-extension` with a non-stream argument such as a file path or entry URL, Node should exit with an error prior to any evaluation. This also means that `--entry-extension` cannot be used to override the extension of file paths.

```sh
# exits with an error
node --entry-extension=json app.js
Copy link
Member

Choose a reason for hiding this comment

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

node --entry-extension=js app.js should then also error?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes

Copy link
Member

Choose a reason for hiding this comment

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

Might be a good example to add so that people don't think it's the mismatch that errors

Copy link

Choose a reason for hiding this comment

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

Definitely a good example since most of the feedback so far has been above this :)

Copy link
Member Author

Choose a reason for hiding this comment

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

added

# exits with an error
node --entry-extension=js app.js
```

### Userland Extensions

Some libraries extend `require.extensions` with new extensions. These libraries should be considered when determining the list of extensions allowed in `--entry-extension`.

Choose a reason for hiding this comment

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

How would this work? Only for preload modules I suppose?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep. Only preload would affect this.


Any future extensions to the ESM based loading mechanisms will have to account for collisions and define behavior when they collide.

### Early Errors

Any unknown file extension should prevent the main entry point to the program from executing anything. Preloaded files such as using `--require` should continue to load normally.
Copy link
Member

Choose a reason for hiding this comment

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

Is there any concept of preloading files, but with a different entry extension? In other words, --import to match --require?

Copy link
Member Author

Choose a reason for hiding this comment

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

@ljharb not currently, use a wrapper for now. --require uses file paths always, so file extensions are always included. There are some odd problems with naming here, and some timing differences due to ESM being async that I think are fine to put off for a future time.

Copy link
Member

Choose a reason for hiding this comment

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

ah, so --require file.mjs would work as expected?

Copy link
Member Author

Choose a reason for hiding this comment

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

maybe? require('./foo.mjs') throws so the naming is a bit odd but since CLI arg for main file to run accepts .mjs it should work fine I would expect.

Choose a reason for hiding this comment

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

Correct, but require() has synchronous code boundaries to deal with. We have more freedom in how we define preload's interactions.

Perhaps we should have --import alias to --require though, for posterity and to avoid confusion. That being said, -i is already used.

Copy link
Member Author

Choose a reason for hiding this comment

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

IDK, --import seems fine and can use the module resolution of ESM rather than CJS then ESM


Any error produced by this should describe how to get the list of known extensions; and the error should attempt to point towards how to add an extension if needed. The error may change from preferring `require.extensions` to a new mechanism that supports ESM over time.

## Alternate Possibilities

Some alternate possibilities exist that might be relevant. `--entry-url` for example could be used to provide an `import.meta.url` properly while also providing the pathname that contains an extension. However, since URLs are not mandated to have file extensions this might be for nothing. Applications can also access `process.cwd()` to recreate similar data to `import.meta.url`.

Choose a reason for hiding this comment

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

Seems far less intuitive?

Copy link
Member Author

Choose a reason for hiding this comment

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

yup, not suggested.


## APIs

No new runtime APIs are to be added.

## Future considerations

Some upcoming file formats are also proposed such as [WebPackage](https://github.com/WICG/webpackage) that would also benefit from this.