Comments (22)
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.
from realms-shim.
I have just make a proposal for it.
Check it out and give some support!
https://github.com/Jack-Works/proposal-ecmascript-parser
from realms-shim.
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.
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
let enabledImport = false
try {
enabledImport = ['typescript', require('typescript')]
}
catch {}
from realms-shim.
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 [email protected]
unless you'd like to respond publically.
Thanks,
Michael.
from realms-shim.
Okay, rereading your comments leaves me with the understanding that this could be independent of ES runtime. Interesting!
from realms-shim.
Ah. I'm not familiar with SystemJS before I do this. I choose SystemJS because import.meta
is available when translate target is ESModule or SystemJS in TypeScript compiler. If I choose CJS or AMD, it cannot use import.meta anymore
from realms-shim.
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.
from realms-shim.
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
from realms-shim.
Where can I read about the transformation and the API of the System
object that it assumes?
from realms-shim.
@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
from realms-shim.
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)
from realms-shim.
I have already done this in another project:
Wrap the translated module in a function:
The fake SystemJS object, it's register function:
https://github.com/Jack-Works/loader-with-esmodule-example/blob/master/src/typescript/typescript-shared-compiler.ts#L87
Resolve all dependencies and also translate them into the internal module representation:
Transform all import declarations from import x from './some'
to import x from '/compiler.js?src=./some'
(not useful in the realms's case):
Transform all dynamic import(x)
calls to import((x => x[0] === '.' || x[0] === '/' ? new URL('/compiler.js?src=' + x, import.meta) : x)(x))
(also not useful in realm's case):
https://github.com/Jack-Works/loader-with-esmodule-example/blob/master/src/typescript/typescript-shared-compiler.ts#L226
from realms-shim.
Transform to another module standard because we can't just eval('import(...)')
, it's a sandbox escape. We need to handle how to resolve and execute the module source.
Actually use any the internal format is okay, commonjs
, amd
, SystemJS
. I use SystemJS becuase it is the only format for my compiler that can support import.meta
syntax. (import.meta
will be transformed into something like context_1.meta
, and it comes from System.register
)
from realms-shim.
@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.
from realms-shim.
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.
from 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.
from realms-shim.
@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 realms-shim.
From the example at #47 (comment) I was not able to infer what the transformation is in general. Is the full transform explained anywhere?
from realms-shim.
The format is described in https://github.com/systemjs/systemjs/blob/master/docs/system-register.md.
from realms-shim.
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 dep-a.js
dep-2.js
and the dynamic import run the code in the realms.
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".
It will receive a "RealmsModule" object to handle its dependencies and exports.
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 import.meta
into "context_1.meta", dynamic import into context_1.import()
from realms-shim.
And yes, I prefer SystemJS as the internal module format because it "support the exact semantics of ES6 modules"
from realms-shim.
I have implemented a class SystemJSRealm extends SystemJS implements Realm
in my project and it works well (somehow)
from realms-shim.
Related Issues (20)
- make new release
- Match the new Realms proposal API
- Need to shut down or transfer this shim project HOT 1
- Give an option to close rejectDangerousSourcesTransform HOT 1
- Realm is not a constructor HOT 1
- SyntaxError: possible html comment syntax rejected around line 1
- Breakout via RangeError: Maximum call stack size exceeded HOT 3
- sandbox breach: host objects, evaluator mode switch, Reflect.construct HOT 14
- Function.prototype.constructor is tamed in the host HOT 7
- Protecting prototype accross the sandbox HOT 3
- The minified build is broken HOT 1
- Errors in realm is hard to debug HOT 2
- Rename option `sloppyGlobals` as `sloppyGlobalsMode`
- sandbox breach: rewrite transforms HOT 5
- Add `globalThis` as the global object in the Realms
- sandbox breach: symbol.Unscopables HOT 1
- transforms rely upon Array-ness of user-supplied argument HOT 1
- transforms rely upon user-provided "string", can capture wrong-realm RegExp HOT 1
- Realms Issue #202: Publish Realms Shim on NPM HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from realms-shim.