-
Notifications
You must be signed in to change notification settings - Fork 19
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
Any signal about supporting ESModules? #47
Comments
Hi, Interestingly enough, I've been working on something that may suit your needs. It's not quite finished yet, but transform-module is an import expression and module body rewriter that uses Babel. It works for all import/export syntax. The module rewrite it uses was designed by @erights and I. My next goal is to get make-importer up-and-running to complete the picture. But yes, transforms were specifically designed for supporting ESModules, so you're on the right track! I don't think the module support will be folded into realms-shim, but feel free to create a wrapper that uses your transforms and importer. That's what I intend to do. Pick your poison: Typescript or Babel. Offering users diversity in this regard is worthwhile. |
I have just make a proposal for it. |
Okay... Not a built-in one... But we can try to do this to enable import transform if developers already have typescript or babel installed
|
I read the URL you pointed to, and wanted to ask: are you targeting only the browser? Or are you aiming for a kind of SystemJS support that would be compatible with Node.js and other runtimes? The goal for the ESM system I'm working on is to have something which would be independent of the particular ECMAScript environment. [BTW, It seems that there is also a Babel transform for ESM-to-SystemJS, so that may be a worthwhile second translation front end for you if you want to offer diversity, regardless of your target.] I must admit to unfamiliarity with SystemJS, so I would be interested in hearing about the tradeoffs of your design. Feel free to take this offline to Thanks, |
Okay, rereading your comments leaves me with the understanding that this could be independent of ES runtime. Interesting! |
Ah. I'm not familiar with SystemJS before I do this. I choose SystemJS because |
What you explained in the description seems to be something that you should do today, and if you can't, then just let us know where the problem lies, and we can try to address it. SystemJS format is a script sourceText, which can be evaluated inside a realm. The SystemJS global references can be installed in the realm, where you can intercept those operations and carry on the proper operation under the hood. |
I have already done this before, but not for realm. I just wonder if I do this for realm, will realm accept it as a pr |
Where can I read about the transformation and the API of the |
@Jack-Works I don't think we want to add SystemJS support to the realms shim as a out of the box feature, but certainly you can create another project on top of the realm to add support for it... seems very straight forward. /cc @guybedford |
No, I'm not supporting SystemJS, but internally transform ESModules into SystemJS so we can run all ESModules files in the sandbox. Here's an example: import x from './dep-a.js'
import { x1 } from './dep-2.js'
export function main(path) {
return import(path)
} Will be transformed to System.register([], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
function main(path) {
return context_1.import(path);
}
exports_1("main", main);
return {
setters: [],
execute: function () {
}
};
}); And we wrap it in a wrapper ;(function (System) {
// translated code here.
}) Then the ESModule file will return a function, and we can let all its dependencies run in the realms. const currentFileModule = translate(sourceText)
const fakeSystem = { register() { ... } }
const currentFileExecutedModule = currentFileModule(fakeSystem)
const dependencies = resolveAllDependenciesAndExecuteInRealms(currentFileExecutedModule) |
I have already done this in another project: Wrap the translated module in a function: The fake SystemJS object, it's register function: Resolve all dependencies and also translate them into the internal module representation: Transform all import declarations from Transform all dynamic |
Transform to another module standard because we can't just Actually use any the internal format is okay, |
@Jack-Works yes, that's precisely what I was saying above, you can do that in an abstraction layer on top of the shim to provide a shim implementation that supports SystemJS, don't need to be here. This shim is first and foremost a polyfill of the Realms proposal, plus a bunch of other things that help us to implement it and bend the rules to the limitations of polyfilling it. IMO, the support for SystemJS should be something that works with this shim and with the eventual native implementation... it is just a new layer that works independently of how the polyfill is implemented. |
I'm afraid you didn't catch my meaning. I'm not "supports SystemJS", I'm supporting ESModule (and system is just an approach ). Since ESModule is the standard module system of ECMAScript, it is meaningful to support it in the Realms shim. |
If there's anything I can advise on here let me know. Although Caridy is probably the right person to suggest / advise re SystemJS here as he was a co-contributor when we were developing the System format! The runtime with TLA support (although not based on the latest spec changes re timings yet) can be easily copied from here if necessary - https://github.com/systemjs/systemjs/blob/master/src/system-core.js, to create a scoped interpretation. But there are many ways to skin modules too. esm's implementation used another approach for live bindings which may be worth looking into. Reexports and cycles are the things to watch out for. |
@michaelfig and I are working on a different module rewrite and linkage scheme for SES. We expect to present this at the SES meeting on Thursday Sep 19. We should examine whether it satisfies your goals. |
From the example at #47 (comment) I was not able to infer what the transformation is in general. Is the full transform explained anywhere? |
The format is described in https://github.com/systemjs/systemjs/blob/master/docs/system-register.md. |
Maybe I need to explain it again. First, we want to run the following code in the realms without breaking the sandbox. import x from './dep-a.js'
import { x1 } from './dep-2.js'
export function main(path) {
return import(path)
} To archive this goal, we need to make modules We can not run code with a static import in eval (Uncaught SyntaxError: Cannot use import statement outside a module). And run code with a dynamic import will cause a sandbox escape. So we need to translate the code into another form(let's call it "internal module format") we can handle it safely. To avoid confusion, I'll not use any existing module format. Let's transform it (use a compiler) into an imaginary module format "RealmsModule". (function (RealmsModule) {
RealmsModule.staticImport("./dep-a.js", "./dep-2.js", (_a, _b) => {
const x = _a
const { x1 } = _b
RealmsModule.exportBindings.main = function main(path) {
return RealmsModule.dynamicImport(path)
}
})
}) Let's call this file "index.(translated).js" After this translation, we can handle all kinds of import statements in the source file. Then we run the code in the index.(translated).js in the save eval function, we will get a function returned. Let's call this function "moduleExecutor". Run the function "moduleExecutor" with RealmsModule object we will get RealmsModule.staticImport called with it dependencies and a callback. We can resolve all its dependencies recursively. After all modules resolved in the realms, we can call the callback to execute the module body. When someone calls the main function in the index.js, it actually calls RealmsModule.dynamicImport so we can hijack it into the realms. This is how I plan to support ESModules. Instead of creating a brand new module format, I reuse the existing module format so I don't need to write a compiler myself. I happened to choose SystemJS because the TypeScript compiler can compile the ESModule syntax |
And yes, I prefer SystemJS as the internal module format because it "support the exact semantics of ES6 modules" |
I have implemented a |
I need to run ESModule code in my project. But realms doesn't support it currently.
I have the willingness to resolve this problem but I don't know if it is acceptable for this project.
Proposal:
System
object to execute and get the binding of the module.import()
by the transform functions. But static import is only supported on the top level of the file.This will make the Realms shim slower and bigger. Is that acceptable for realms-shim? If not, I will do that in my own project instead of contributing it to the upstream
The text was updated successfully, but these errors were encountered: