-
Notifications
You must be signed in to change notification settings - Fork 518
Description
tldr; Currently only ES Modules (modules containing the import
or export
keyword) are transpiled through Babel. Users of other formats, like CommonJS, would like to also be able to transpile their code for production.
This was discussed on a recent live stream (41:01) and at a contributors meeting (1:01:50)
The Problem
Users in legacy codebases using AMD or CommonJS might want to take advantage of some of the new JavaScript features like arrow functions and destructuring.
Currently in Steal this would require rewriting the module to use ESM syntax. For small modules this is simple, but in more complex cases it is not:
var Todo = require("./todo").Todo;
becomes:
import TodoModule from "./todo";
const { Todo } = TodoModule;
With very large files this can become burdensome.
Additionally, ESM forces strict mode, and some legacy code might be relying on sloppy mode features like arguments.callee
.
The Solution
Allowing non-ESM module formats to also be transpiled can be provided via configuration. We will restrict this to package.json configuration, which almost all Steal users use now, for simplicity of implementation.
API
The API will be a new transpile
configuration option. There will be one signature:
"transpile": true
This will transpile all code within that particular package. Note that if you are using Babel you still might want to configure the babelOptions
to set which plugins and presets you want to use, otherwise it will use the defaults.
A typical use case might be like:
{
"name": "my-app",
"version": "1.0.0",
"main": "index.js",
"steal": {
"transpile": true
}
}
Which, within my-app/todo.js
this:
class Todo {
}
module.exports = Todo;
Should transpile into:
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Todo = function Todo() {
_classCallCheck(this, Todo);
};
module.exports = Todo;
Implementation
To implement this, I would start by making each package's package.json object (represented internally as a pkgInfo
I believe) available on the load.metadata
object.
Then, in the instantiate hook, check for the presence of this transpile
boolean, and call loader.transpile
, just as currently happens with ES modules.
I believe this is a fairly easy change that could be done in a half sprint or so.
Tasks
- - Create tests for CommonJS and AMD.
- - Add the package.json to the
load.metadata
object in the locate hook. - - Checking
load.metadata.package
for the flag in the instantiate hook and callloader.transpile
.
Note for future
Given that CommonJS and AMD are fading out of usage, it might not make sense to put too much effort to these formats. However, if this feature proves to be popular we could expand this option in the future to take a glob pattern so that you can only transpile some files within your project, if desired.