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

Support "extensions" option in config files and presets #12216

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

nicolo-ribaudo
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo commented Oct 19, 2020

Original: #12151

Q                       A
Fixed Issues? Closes #11409, fixes #8652, fixes #11394, fixes #10232, fixes #8962, fixes #11833, closes #8971
Patch: Bug Fix?
Major: Breaking Change?
Minor: New Feature? Yes
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT
  • It can be set in programmatic option, babel.config.json, .babelrc.json and in presets
  • Files not matching any extension are ignored
  • If no filename is given, the file is not ignored
  • "*" is supported as a catch-all extension

For backward compatibility reasons, this option defaults to ["*"].

This PR makes it possible to specify, for example, extensions: [".ts", ".tsx"] in the typescript preset, or in a config file. By doing so, users can keep their config in a single place instead of manually passing the extensions to @babel/register/@babel/cli/@babel/node and other integrations.

Depends on #11689, which makes it possible to know the list of extensions before instantiating the plugins.


This PR fixes following issues, by defining extensions: [".ts", ".tsx"] in @babel/preset-typescript (so Babel can hook into .ts loading without explicitly specifying it in @babel/register's options):

These issues are fixed by not special-casing extensions handling in @babel/cli:


These are done in 4 different commits; I suggest reviewing them one by one!

TODO:

  • Add the option
  • Use it in @babel/register
  • Use it in @babel/cli
  • Use it in the TS preset

@nicolo-ribaudo nicolo-ribaudo added PR: New Feature 🚀 A type of pull request used for our changelog categories pkg: core labels Oct 19, 2020
@nicolo-ribaudo nicolo-ribaudo added this to the v7.13.0 milestone Oct 19, 2020
Comment on lines +41 to +54
// Node.js's algorithm tries to automatically resolve the extension of the
// required file. This means that if you have, for example, require("./foo")
// it can load foo.js (even if ".js" is not specified).
// This doesn't only work with predefined extensions: whenever a new extension
// hook is registered, Node.js can resolve it.
// For this reason, we need to register new extensions as soon as we know about
// them. This means:
// 1) When we compile a file and see a new extension in its `extensions` option.
// 2) When a file with a new explicit extension is loaded
//
// In practice, this means that to load foo.ts you have to use
// node -r @babel/register ./foo.ts
// instead of just
// node -r @babel/register ./foo
Copy link
Member Author

Choose a reason for hiding this comment

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

This will need to be clearly written in the docs.

Another example that cannot work:

// index.js
require("@babel/register");
require("./foo"); // <-- You'll need require("./foo.ts") here, since it's the first time Babel sees a .ts file

// foo.ts
console.log("OK");

Note that the ESM loader won't have this problem, it's CJS-specific (and only for the entry points, require("./foo") correctly resolves foo.ts if it's not the entry point).

@@ -0,0 +1 @@
console.log("DONE: foo.ts");
Copy link
Member Author

Choose a reason for hiding this comment

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

This .ts file is loaded because the TS preset is defined in the config 🎉

@babel-bot
Copy link
Collaborator

babel-bot commented Oct 19, 2020

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/30583/

@codesandbox-ci
Copy link

codesandbox-ci bot commented Oct 19, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 4805c69:

Sandbox Source
babel-repl-custom-plugin Configuration
babel-plugin-multi-config Configuration

@nicolo-ribaudo

This comment has been minimized.

- It can be set in programmatic option, babel.config.json, .babelrc.json and in presets
- Files not matching any extension are ignored
- If no filename is given, the file is not ignored
- "*" is supported as a catch-all extension

For backward compatibility reasons, this option defaults to ["*"].
@loganfsmyth
Copy link
Member

@nicolo-ribaudo If it's useful, here's the WIP patch I had when I was experimenting with this: main...loganfsmyth:__archive-allow-user-extensions

Primary differences I see is that:

  • I was trying to integrate the extensions value with the ignore system itself
  • I was planning to add a new API to Babel to get root-wide config from only babel.config.js, without any specific filename for context.

So on the ignore side, if you call Babel with a file that isn't a known extension, Babel will automatically ignore it, so for instance Webpack would no longer need its test: /\.jsx?$/ tests, and babel-cli would I think be able to just delete it's extension processing logic entirely (in the next major release). My thought had been to have babel-register use a new API like I mentioned on Slack as either like babel.project(rootOpts) or babel.getRootExtensions(rootOpts) or something, that would explictly return the list of extensions that are supported by the project by loading all the settings and presets reachable from the main config. I personally think that is the direction that babel.config.js is already going, so it felt pretty natural to start expanding the API to take more advantage of the root.

@nicolo-ribaudo nicolo-ribaudo removed the PR: Needs Review A pull request awaiting more approvals label Nov 12, 2020
@nicolo-ribaudo nicolo-ribaudo removed this from the v7.13.0 milestone Nov 12, 2020
@nicolo-ribaudo nicolo-ribaudo marked this pull request as draft March 27, 2021 00:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment