Coder Social home page Coder Social logo

Comments (22)

michaelfig avatar michaelfig commented on July 24, 2024

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.

Jack-Works avatar Jack-Works commented on July 24, 2024

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.

Jack-Works avatar Jack-Works commented on July 24, 2024

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.

michaelfig avatar michaelfig commented on July 24, 2024

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.

michaelfig avatar michaelfig commented on July 24, 2024

Okay, rereading your comments leaves me with the understanding that this could be independent of ES runtime. Interesting!

from realms-shim.

Jack-Works avatar Jack-Works commented on July 24, 2024

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.

caridy avatar caridy commented on July 24, 2024

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.

Jack-Works avatar Jack-Works commented on July 24, 2024

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.

erights avatar erights commented on July 24, 2024

Where can I read about the transformation and the API of the System object that it assumes?

from realms-shim.

caridy avatar caridy commented on July 24, 2024

@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.

Jack-Works avatar Jack-Works commented on July 24, 2024

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.

Jack-Works avatar Jack-Works commented on July 24, 2024

I have already done this in another project:

Wrap the translated module in a function:

https://github.com/Jack-Works/loader-with-esmodule-example/blob/master/src/typescript/typescript-shared-compiler.ts#L45

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:

https://github.com/Jack-Works/loader-with-esmodule-example/blob/master/src/typescript/typescript-shared-compiler.ts#L108

Transform all import declarations from import x from './some' to import x from '/compiler.js?src=./some' (not useful in the realms's case):

https://github.com/Jack-Works/loader-with-esmodule-example/blob/master/src/typescript/typescript-shared-compiler.ts#L195

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.

Jack-Works avatar Jack-Works commented on July 24, 2024

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.

caridy avatar caridy commented on July 24, 2024

@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.

Jack-Works avatar Jack-Works commented on July 24, 2024

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.

guybedford avatar guybedford commented on July 24, 2024

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.

erights avatar erights commented on July 24, 2024

@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.

erights avatar erights commented on July 24, 2024

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.

guybedford avatar guybedford commented on July 24, 2024

The format is described in https://github.com/systemjs/systemjs/blob/master/docs/system-register.md.

from realms-shim.

Jack-Works avatar Jack-Works commented on July 24, 2024

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.

Jack-Works avatar Jack-Works commented on July 24, 2024

And yes, I prefer SystemJS as the internal module format because it "support the exact semantics of ES6 modules"

from realms-shim.

Jack-Works avatar Jack-Works commented on July 24, 2024

I have implemented a class SystemJSRealm extends SystemJS implements Realm in my project and it works well (somehow) 🤔

from realms-shim.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.