Skip to content

Support for ES Modules #99

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

Open
robfig opened this issue Apr 1, 2021 · 6 comments
Open

Support for ES Modules #99

robfig opened this issue Apr 1, 2021 · 6 comments

Comments

@robfig
Copy link
Contributor

robfig commented Apr 1, 2021

It looks like v8go does not support ES Modules. For example, I translated the Context example to use modules:

package main

import (
	"fmt"

	"rogchap.com/v8go"
)

func main() {
	ctx, _ := v8go.NewContext()
	val, err := ctx.RunScript("export function add(a, b) { return a + b };", "math.mjs")
	fmt.Println(val, err)
	val, err = ctx.RunScript("import { add } from 'math.mjs';\nconst result = add(3, 4)", "main.js")
	fmt.Println(val, err)
	val, err = ctx.RunScript("result", "value.js")
	fmt.Println(val, err)
	fmt.Println(val)
}

and it resulted in these errors:

<nil> SyntaxError: Unexpected token 'export'
<nil> SyntaxError: Cannot use import statement outside a module
...

I do not typically develop JS or use Node.js, so I might be doing something dumb too.

Do you have any particular ideas around how this might work? I'd be happy to submit a pull request if so.

Thanks!
Rob

@tmc
Copy link
Collaborator

tmc commented Apr 1, 2021

Hi Rob!

Until V8 has direct support for interpreting that syntax I think you'll need a step in between the V8 context and that source.

Thankfully we have the https://pkg.go.dev/github.com/evanw/esbuild/pkg/api project that is rapidly growing in popularity that gives us access to exactly this type of bundling task.

Perhaps we should consider some sort of v8goext package that could provide some helpers for this sort of thing.

@tmc
Copy link
Collaborator

tmc commented Apr 1, 2021

This comment here points to various implementations of modules using the V8 api: https://stackoverflow.com/a/52031275/105456

I'm personally a bit skeptical we should add this type and amount of code to this project - perhaps another candidate for a ext or contrib package.

@robfig
Copy link
Contributor Author

robfig commented Apr 1, 2021

Thanks for the pointers. So you're saying that V8 itself does not deal with ES Modules and expects to be handed JS to execute after all the module stuff has been taken care of.

I should mention my higher level goal is to accept Deno / TypeScript programs and run a function defined by them. To do that, I used the Deno CLI to execute "deno bundle" to convert the provided program to plain JS. However, Deno uses ES Modules and the bundle output is a ES Module. My goal is to execute an exported function from that module.

Using esbuild to transform into FormatIIFE allows this to work! Many thanks

package main

import (
	"fmt"
	"os"

	"github.com/evanw/esbuild/pkg/api"
	"rogchap.com/v8go"
)

func main() {
	script := "export function add(a, b) { return a + b };"
	result := api.Transform(script, api.TransformOptions{
		Loader:     api.LoaderJS,
		Format:     api.FormatIIFE,
		GlobalName: "global",
	})
	os.Stdout.Write(result.Code)
	fmt.Printf("%d errors and %d warnings\n",
		len(result.Errors), len(result.Warnings))

	ctx, _ := v8go.NewContext()
	ctx.RunScript(string(result.Code), "math.mjs")
	global, _ := ctx.Global().Get("global")
	globalObj, _ := global.AsObject()
	fmt.Println(globalObj.Get("add"))
}

@robfig robfig closed this as completed Apr 1, 2021
robfig pushed a commit to robfig/v8go that referenced this issue Apr 3, 2021
The result is a Value of type ModuleNamespace, from which the module's
exports can be accessed. Imports are not supported.

Fixes rogchap#99
@robfig
Copy link
Contributor Author

robfig commented Apr 3, 2021

Reopening to link with a pull request

@robfig robfig reopened this Apr 3, 2021
robfig pushed a commit to robfig/v8go that referenced this issue Apr 3, 2021
The result is a Value of type ModuleNamespace, from which the module's
exports can be accessed. Imports are not supported.

Fixes rogchap#99
robfig pushed a commit to robfig/v8go that referenced this issue Apr 4, 2021
The result is a Value of type ModuleNamespace, from which the module's
exports can be accessed. Imports are not supported.

Top-level await IS supported, which can require us to poll for
completion of module resolution, done using a busy loop.

Fixes rogchap#99
robfig pushed a commit to robfig/v8go that referenced this issue Apr 4, 2021
The result is a Value of type ModuleNamespace, from which the module's
exports can be accessed. Imports are not supported.

Top-level await IS supported, which can require us to poll for
completion of module resolution, done using a busy loop.

Fixes rogchap#99
robfig pushed a commit to robfig/v8go that referenced this issue Apr 4, 2021
The result is a Value of type ModuleNamespace, from which the module's
exports can be accessed. Imports are not supported.

Top-level await IS supported, which can require us to poll for
completion of module resolution, done using a busy loop.

Fixes rogchap#99
robfig pushed a commit to robfig/v8go that referenced this issue Apr 13, 2021
The result is a Value of type ModuleNamespace, from which the module's
exports can be accessed. Imports are not supported.

Top-level await IS supported, which can require us to poll for
completion of module resolution, done using a busy loop.

Fixes rogchap#99
@etiennemartin
Copy link

Tested this again today, looks like we are still getting the same type of response. That being said I'm not sure if anything has changed with the default v8 binary bundled with v8go.

@dylanahsmith
Copy link
Collaborator

@etiennemartin Modules are not just a backwards compatible extensions to scripts, so it isn't just going to change using the current APIs. Support needs to be added for the separate V8 APIs for modules such as v8::ScriptCompiler::CompileModule and the v8::Module methods. E.g. see #101 for a previous abandoned attempt to add support for ES modules

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

Successfully merging a pull request may close this issue.

4 participants