-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Description
Feature Request
A request we've gotten in several different contexts is for Babel to have better file extension handling. This is particularly clear in the context of Typescript, because we don't want to process.ts files unless users have enabled @babel/preset-typescript. Unfortunately, Babel currently pretty much just processes whatever it is given and assumes that it will be able to parse it, so if it is given Typescript without the plugin enabled, it will just throw errors about unknown syntax.
Some examples:
- Make input file extensions configurable via .babelrc/API (T6673) #3741
- Add '.ts' and '.tsx' to default extensions #6027
Essentially, these all come down to a primary question, which is, how does Babel decide what files to process? Before the release of 7.x, I experimented quite a bit around file extension handling. The behavior I lean toward is, Babel should be passed all files, and if it doesn't care about a file, it can behave like the file was ignoreed.
The primary concern from my point of view is, which stopped me from landing my PR in 7.x, was what about files have have non-standard extensions? For instance, .vue templates still get passed to Babel. Do we require all users of vue to enable a Babel plugin to opt into compilation of .vue files? The downside there is that .vue files in Webpack are only sometimes JavaScript. Sometimes, it might be the actual Vue template file. Ideally Webpack would have some way to split up files, so we'd at least get a .vue.js file or something, but it's not really obvious what the right behavior is, and we were very close to releasing 7.x by the time I started thinking about this issue.
A few other questions:
- What should Babel do if no filename is given? (This may have answered itself, since we now require a filename to be given, in order to use
preset-typescript, unless you pass an option). - What about cases like
@babel/registerwhere we need to know the extensions up front in order to register the require hooks? We'd need a concept of a project root config, which we kind of have now withconfigFileandbabel.config.js, but we have no infrastructure to query that project-wide config for things like registered file extensions. It also means that if you loadedpreset-typescriptin a.babelrc, we'd still always ignore.tsfiles, which isn't the best. - Do we want extensions to have metadata associated with them? In 7.x for instance we hard-coded
.mjsto besourceType: "module"always, is that what we want in the long run, or should it be a configurable flag attached to each extension? - Do we want this to try to handle output extensions, for things like
gulp-babeland@babel/clithat frequently write files back to disk after transformation?
It's definitely something we should think through for 8.x though.