Skip to content
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

Steps needed for es6 modules embedding ChakraCore #4324

Closed
ross-weir opened this issue Nov 26, 2017 · 4 comments
Closed

Steps needed for es6 modules embedding ChakraCore #4324

ross-weir opened this issue Nov 26, 2017 · 4 comments

Comments

@ross-weir
Copy link
Contributor

If someone had some spare time would it be possible to get a little rundown on the steps involved or even a simple hello world example on implementing ES6 modules when embedding ChakraCore in my own application please?

I'm completely new to the codebase so I've been spending a lot of time studying ch but a quick rundown on this would be extremely helpful.

Thanks a lot.

@rhuanjl
Copy link
Collaborator

rhuanjl commented Nov 27, 2017

One of the team may be able to provide something more detailed, but I've got some experience of the Module code (having submitted 2 PRs related to it) so thought I could write something on this.

Starting point, all the APIs you need are in this header:
https://github.com/Microsoft/ChakraCore/blob/master/lib/Jsrt/ChakraCore.h

Other note - Dynamic imports - import()
Dynamic import is supported alongside static import but is disabled by default, to enable it you can pass the flag: JsRuntimeAttributeEnableExperimentalFeatures to your JsCreateRuntime call. (It's disabled by default not because of any problem with it in CC but because it's not supported in Edge yet).

Callbacks you must create

  1. FetchImportedModuleCallBack
    This function will be called when a module is being imported from within another module - the specifier will be supplied; you need to implement an algorithm for checkcing if a record has already been created for the requested module - return it if it has; if there is no record for the requested module you need to crate a module record for it and return that - note this requires you to run your own array or table of some kind to store the module records you've created so you can do this check.
  2. FetchImportedModuleFromScriptCallBack
    This function will be similar to the above except it will be called for import() from a script rather than from a module - the key difference is that it has a source context parameter instead of a module record parameter. Warning - the header I reference above has an incorrect comment in describing this function - it describes the next one by mistake...
  3. NotifyModuleReadyCallback
    This function will be called when the module record has been instantiated, it needs to arrange for a call to JsParseModuleSource to be made to Parse the Module; and JsModuleEvaluation to evaluate the module (only after it and all dependencies have been parsed note you only need to Evaluate the root parent module, don't evaluate the dependencies, just parse them before the evaluate call for their parent) - these calls should be done from your event loop, so ideally this callback will add the module record to some sort of queue.

Key JSRT functions you will need

  1. JsInitializeModuleRecord
    This creates a module record - you will need it inside your first two callbacks above; note only use it when no record has already been created for the module you're loading otherwise you end up loading the same module twice.
  2. JsParseModuleSource
    This actually loads the module - as mentioned above call it from your event loop with the details set up via your NotifyModuleReadyCallback
  3. JsModuleEvaluation
    This executes the module and runs the code - as mentioned above this should happen from your event loop and only when the module and all its dependencies have been parsed.
  4. JsSetModuleHostInfo
    This is used for a few largely unrelated purposes:
  • Setting up the module callbacks - you must use this function to setup the 3 module callbacks shown above; this must be done before your JS execution encounters an import or import() call. As this function requires a module record in order for it to be called you may have to create a fake module record to call this with to set those 3 callbacks - you have to do this otherwise CC doesn't know what to call for the first module it encounters. Note you do not need to reset these callbacks for each module - though ch currently does this it's irrelevant as this function sets the callbacks on to the JsContext, not the module.
  • Setting a URL for a module - this step is optional, however if you don't do it the Module URL will not show in error stack traces (if running JS on your desktop the URL should be the full path to the module or a relative path from your CWD) - the URL should be a javascriptstring
  • Storing an exception object on a module record - this may be needed for some error handling systems.

For example implementations:

  1. ch: https://github.com/Microsoft/ChakraCore/blob/master/bin/ch/WScriptJsrt.cpp
  2. miniSphere (JavaScript game engine made by a friend of mine) https://github.com/fatcerberus/minisphere/blob/master/src/shared/jsal.c

@akroshg
Copy link
Contributor

akroshg commented Nov 27, 2017

@rhuanjl those are nice steps you have mentioned and to the point. Thanks,
@notvita you can also looked at https://github.com/Microsoft/ChakraCore/blob/master/bin/NativeTests/JsRTApiTest.cpp#L1929
how natively it is consumed step-by-step
@liminzhu I couldn't find anything on the wiki to share here. Do you have anything else to add?

@ross-weir
Copy link
Contributor Author

@rhuanjl Thank you very much for taking the time to write that up. Extremely helpful and very much appreciated.
@akroshg Thanks for that, very useful.

@digitalinfinity
Copy link
Contributor

Sounds like this question was answered- closing this issue. @notvita please reopen the issue if you think the issue wasn't resolved- or if you have another question, please feel free to open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants