-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
519 additions
and
394 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package js | ||
|
||
import ( | ||
"fmt" | ||
"net/url" | ||
|
||
"github.com/dop251/goja" | ||
"go.k6.io/k6/js/compiler" | ||
"go.k6.io/k6/js/modules" | ||
) | ||
|
||
// cjsModule represents a commonJS module | ||
type cjsModule struct { | ||
prg *goja.Program | ||
url *url.URL | ||
} | ||
|
||
var _ module = &cjsModule{} | ||
|
||
type cjsModuleInstance struct { | ||
mod *cjsModule | ||
moduleObj *goja.Object | ||
vu modules.VU | ||
} | ||
|
||
func (c *cjsModule) Instantiate(vu modules.VU) moduleInstance { | ||
return &cjsModuleInstance{vu: vu, mod: c} | ||
} | ||
|
||
func (c *cjsModuleInstance) execute() error { | ||
rt := c.vu.Runtime() | ||
exports := rt.NewObject() | ||
c.moduleObj = rt.NewObject() | ||
err := c.moduleObj.Set("exports", exports) | ||
if err != nil { | ||
return fmt.Errorf("error while getting ready to import commonJS, couldn't set exports property of module: %w", | ||
err) | ||
} | ||
|
||
// Run the program. | ||
f, err := rt.RunProgram(c.mod.prg) | ||
if err != nil { | ||
return err | ||
} | ||
if call, ok := goja.AssertFunction(f); ok { | ||
if _, err = call(exports, c.moduleObj, exports); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (c *cjsModuleInstance) exports() *goja.Object { | ||
exportsV := c.moduleObj.Get("exports") | ||
if goja.IsNull(exportsV) || goja.IsUndefined(exportsV) { | ||
return nil | ||
} | ||
return exportsV.ToObject(c.vu.Runtime()) | ||
} | ||
|
||
type cjsModuleLoader func(specifier *url.URL, name string) (*cjsModule, error) | ||
|
||
func cjsmoduleFromString(fileURL *url.URL, data []byte, c *compiler.Compiler) (*cjsModule, error) { | ||
pgm, _, err := c.Compile(string(data), fileURL.String(), false) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &cjsModule{prg: pgm, url: fileURL}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package js | ||
|
||
import ( | ||
"github.com/dop251/goja" | ||
"go.k6.io/k6/js/modules" | ||
) | ||
|
||
// baseGoModule is a go module that does not implement modules.Module interface | ||
// TODO maybe depracate those in the future | ||
type baseGoModule struct { | ||
mod interface{} | ||
} | ||
|
||
var _ module = &baseGoModule{} | ||
|
||
func (b *baseGoModule) Instantiate(vu modules.VU) moduleInstance { | ||
return &baseGoModuleInstance{mod: b.mod, vu: vu} | ||
} | ||
|
||
type baseGoModuleInstance struct { | ||
mod interface{} | ||
vu modules.VU | ||
exportsO *goja.Object // this is so we only initialize the exports once per instance | ||
} | ||
|
||
func (b *baseGoModuleInstance) execute() error { | ||
return nil | ||
} | ||
|
||
func (b *baseGoModuleInstance) exports() *goja.Object { | ||
if b.exportsO == nil { | ||
// TODO check this does not panic a lot | ||
rt := b.vu.Runtime() | ||
b.exportsO = rt.ToValue(b.mod).ToObject(rt) | ||
} | ||
return b.exportsO | ||
} | ||
|
||
// goModule is a go module which implements modules.Module | ||
type goModule struct { | ||
modules.Module | ||
} | ||
|
||
var _ module = &goModule{} | ||
|
||
func (g *goModule) Instantiate(vu modules.VU) moduleInstance { | ||
return &goModuleInstance{vu: vu, module: g} | ||
} | ||
|
||
type goModuleInstance struct { | ||
modules.Instance | ||
module *goModule | ||
vu modules.VU | ||
exportsO *goja.Object // this is so we only initialize the exports once per instance | ||
} | ||
|
||
var _ moduleInstance = &goModuleInstance{} | ||
|
||
func (gi *goModuleInstance) execute() error { | ||
gi.Instance = gi.module.NewModuleInstance(gi.vu) | ||
return nil | ||
} | ||
|
||
func (gi *goModuleInstance) exports() *goja.Object { | ||
if gi.exportsO == nil { | ||
rt := gi.vu.Runtime() | ||
gi.exportsO = rt.ToValue(toESModuleExports(gi.Instance.Exports())).ToObject(rt) | ||
} | ||
return gi.exportsO | ||
} | ||
|
||
func toESModuleExports(exp modules.Exports) interface{} { | ||
if exp.Named == nil { | ||
return exp.Default | ||
} | ||
if exp.Default == nil { | ||
return exp.Named | ||
} | ||
|
||
result := make(map[string]interface{}, len(exp.Named)+2) | ||
|
||
for k, v := range exp.Named { | ||
result[k] = v | ||
} | ||
// Maybe check that those weren't set | ||
result["default"] = exp.Default | ||
// this so babel works with the `default` when it transpiles from ESM to commonjs. | ||
// This should probably be removed once we have support for ESM directly. So that require doesn't get support for | ||
// that while ESM has. | ||
result["__esModule"] = true | ||
|
||
return result | ||
} |
Oops, something went wrong.