-
Notifications
You must be signed in to change notification settings - Fork 185
Transpiler handling #463
Comments
@guybedford If there is only a custom build which does the module conversion, how would we then transpile other features? Have a separate transpile step from raw es6/7 to es5 which leaves the |
@johanneslumpe SystemJS has actually already solved this problem by treating all dependencies as dynamic modules in the pipeline, and reimplementing the zebra striping linking algorithm for CJS / ESM circular references internally. That is, SystemJS only uses the "dynamic" custom module part of this pipeline, while replicating the rest itself. It's as if the module loader can't load ES modules at all, and can only load through the legacy layer, which is the nice polyfill path. Hence the removal of focus on transpilation in this project. |
@guybedford Oh that's great! My use-case is basically that I want to load transpiled es6 modules transparently without having to worry about fetching the default export when using |
Hmm I'm hesitating a bit about this suggestion for a couple of reasons. If I understand correctly, this would mean we don't fully implement the spec here in es6-module-loader, but instead lean on SystemJS to perform much of the actual work. Specifically, if es6-module-loader is unable to transpile I think some of the reason why I'm hesitating on this is because es6-module-loader would really not be useful without a hard dependency on SystemJS. Nor would it really be a polyfill of the whatwg/loader spec. Additionally, SystemJS may never be able to move off of the es6-module-loader polyfill if we go with something that is not in the spec. I'm not an expert in zebra striping nor in the technical differences between implementing dynamic modules and static modules, so maybe what I'm about to say doesn't make a ton of sense. But what I'm thinking is that SystemJS would take care of (1) transpiling all the non-module-loading stuff via the Does that make sense? I know that it's a pretty dramatic shift from where es6-module-loader and SystemJS are today. Especially (2). |
@joeldenning to clarify the specific point I'm making is to deprecate the |
Ah I see. In that case, yes I completely agree that we should do that. |
This is exactly what I've tried to build using transpiler configs like below .. which didn't work, apparently broke es6-module-loader. I'd LOVE a modules-only transpilation! System.traceurOptions = { arrowFunctions: false, blockBinding: false, classes: false, computedPropertyNames: false, defaultParameters: false, destructuring: false, forOf: false, generators: false, numericLiterals: false, propertyMethods: false, propertyNameShorthand: false, restParameters: false, spread: false, symbols: false, templateLiterals: false, unicodeEscapeSequences: false, unicodeExpressions: false } |
How big would such a parser be? Current/upcoming versions of main browsers now support more ES6 than traceur/Babel, so transpiling no longer makes much sense IMO. The problem however has always been that to handle import/export you need a huge parser. |
It would be the size of Babel without any plugins. |
Note though that this is still not a production-suitable workflow, so transpiler size is not a big concern. |
Since my first couple of comments on this thread, I've been working on a babel-less compiler that compiles the I'm interested in your feedback on it: the implementation method I've chosen is fast and has a small footprint, but that comes with some doubt in my mind about whether I'd really be able to pull off complete correctness for all es6 modules. Do you think it's worth pursuing? |
The other way round surely: not prod because of size :-) Iirc what Joel is attempting is how the polyfill used to work, before using a separate transpiler |
Yeah looks like es6-module-loader used to use esprima. |
There's another issue with not transpiling ATM, that uglify doesn't yet support es6. Last time I looked, this was being worked on in a separate branch. |
@joeldenning this is a really great idea and certainly something that would help this project for the transition to ES modules. Having a transpiler just for modules that is both small and performant is definitely something we want. But correctness becomes critically important. And I think that is only possible with a full JS tokenizer, which I can't see implemented there? The rules of JS language tokenizing are not straightforward unfortunately. For example there are cases like the inability to distinguish if a |
I think this is becoming increasingly necessary. Babel no longer supports running in the browser and no longer produces (https://babeljs.io/docs/usage/browser/) the |
this comment doesn't really belong here, as the loader doesn't use Uglify, but I'd suggest changing to the harmony branch of Uglify throughout all the jspm and systemjs workflows. AIUI, this doesn't yet support all of ES6, for example, generators, but should enable removing transpile except for import/export for those who want to use native minimised ES6. |
I've been thinking over this problem a lot recently, and realized that @guybedford is right that it would probably be really difficult for the kremling compiler I wrote to completely accurately compile es6 down to System.register. However, I came up with another solution that I believe would completely work all the time. There's one major problem that I know of with it, but thought I'd put it here and maybe you guys would either find a way to solve that problem or maybe find other problems with it. My solution is slightly different than the normal System.register format, but could work either with a vanilla System.register implementation or a slightly adjusted System.register implementation. The idea is that the compiler complexity is really caused by having to call The way that you can get away with not calling $__export when exported variables change is by defining getters and setters on the global/window object. So a module that vends exports would actually have all of its exports be variables on the window, instead of local to the function declared inside of the Code example (just shows the basics of what I mean, is not by any means complete): System.register('foo.js', [], function __System__register__foo() {
return {
setters: [],
execute: function() {
setupExportGettersSetters('value1', 2);
setupExportGettersSetters('value2', function() { return value1 });
value1 = 3;
}
})
System.register('bar.js', ['foo.js'], function __System__register__bar() {
setupGetter('value1', 'foo.js');
setupGetter('value2', 'foo.js');
return {
setters: [],
execute: function() {
console.log(value1);
console.log(value2);
}
})
function setupExportGettersSetters(name, value) {
Object.defineProperty(window, name, {
get: function() {
var whoIsGettingTheValue = searchCallerName(caller);
if (whoIsGettingTheValue) {
getValue(whoIsGettingTheValue);
} else {
return actualGlobalValue;
}
},
set: function() { ... }
}
function searchCallerName(theCaller) { ... }
function setupGetter(propName, depName) { ... }
function getValue(who) { ... } Anyway, if that explanation and code sample are intelligible enough to get the idea of what I'm describing, I think that it would completely work (even though that code sample is far from complete). The one big problem with it, though, is that |
I'm not understanding. The docs say:
I have Babel installed, but I'm getting "critical errors" from this module by way of Traceur. CLI: WARNING in ./~/es6-module-loader/index.js
Module not found: Error: Can't resolve 'babel/browser.js' in '/Users/kevinSuttle/Code/platform-ui-primitives/node_modules/es6-module-loader'
@ ./~/es6-module-loader/index.js 17:58-93
WARNING in ./~/es6-module-loader/index.js
Module not found: Error: Can't resolve 'typescript/bin/typescript.js' in '/Users/kevinSuttle/Code/platform-ui-primitives/node_modules/es6-module-loader'
@ ./~/es6-module-loader/index.js 21:41-88
WARNING in ./~/es6-module-loader/index.js
Module not found: Error: Can't resolve 'babel-core/browser.js' in '/Users/kevinSuttle/Code/platform-ui-primitives/node_modules/es6-module-loader'
@ ./~/es6-module-loader/index.js 13:36-76
WARNING in ./~/traceur/bin/traceur.js
Module not found: Error: Can't resolve 'vertx' in '/Users/kevinSuttle/Code/platform-ui-primitives/node_modules/traceur/bin'
@ ./~/traceur/bin/traceur.js 2578:18-28
WARNING in ./~/traceur/bin/traceur.js
1023:38 Critical dependency: the request of a dependency is an expression
WARNING in ./~/traceur/bin/traceur.js
1023:102 Critical dependency: the request of a dependency is an expression
WARNING in ./~/traceur/bin/traceur.js
25877:45 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ./~/traceur/bin/traceur.js
26080:45 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ./~/traceur/bin/traceur.js
26128:45 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ./~/traceur/bin/traceur.js
26152:45 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ./~/traceur/bin/traceur.js
26205:45 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ./~/traceur/bin/traceur.js
26234:45 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ./~/traceur/bin/traceur.js
26277:45 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ./~/traceur/bin/traceur.js
26525:45 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ./~/traceur/bin/traceur.js
26810:45 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
ERROR in ./~/es6-module-loader/dist/es6-module-loader-dev.src.js
Module not found: Error: Can't resolve 'fs' in '/Users/kevinSuttle/Code/platform-ui-primitives/node_modules/es6-module-loader/dist'
@ ./~/es6-module-loader/dist/es6-module-loader-dev.src.js 1529:17-30
ERROR in ./~/traceur/bin/traceur.js
Module not found: Error: Can't resolve 'fs' in '/Users/kevinSuttle/Code/platform-ui-primitives/node_modules/traceur/bin'
@ ./~/traceur/bin/traceur.js 33500:21-34
ERROR in ./~/traceur/bin/traceur.js
Module not found: Error: Can't resolve '../node/nodeLoader.js' in '/Users/kevinSuttle/Code/platform-ui-primitives/node_modules/traceur/bin'
@ ./~/traceur/bin/traceur.js 33491:23-55
ERROR in ./~/source-map-support/source-map-support.js
Module not found: Error: Can't resolve 'fs' in '/Users/kevinSuttle/Code/platform-ui-primitives/node_modules/source-map-support'
@ ./~/source-map-support/source-map-support.js 3:9-22 Browser:
|
I'm wondering where to go with the transpiler handling for this project.
The internal transpilation layer is great for seeing a demo how things work, and is completely necessary to replicate the full pipeline, but I'm wondering if we really need it with pluggable transpilers, or if we shouldn't just create for example a custom build of Traceur or Babel that only does module conversion into System.register and embedding that within the build as the only option.
The text was updated successfully, but these errors were encountered: