登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> SoftHub关联区 >> 主题: goja 支持es6的一种方法[zt]     [回主站]     [分站链接]
goja 支持es6的一种方法[zt]
clq
浏览(567) - 2022-09-05 08:58:12 发表 编辑

关键字:



https://www.cnblogs.com/rongfengliang/p/14232784.html

基本原理

k6 是利用了goja 的js 能力,但是为了支持es6,使用了babel (standalone),同时为了方便扩展ls 的能力,使用了core.js
同时利用了js可以直接转换为golang 方法的模式,直接使用了golang 方法进行es6 编译处理

核心代码
使用babel 的transform 方法,转换es6 为es6,同时暴露为一个golang 方法



func newBabel() (*babel, error) {

var err error



once.Do(func() {

conf := rice.Config{

LocateOrder: []rice.LocateMethod{rice.LocateEmbedded},

}

babelSrc := conf.MustFindBox("lib").MustString("babel.min.js")

vm := goja.New()

if _, err = vm.RunString(babelSrc); err != nil {

return

}



this := vm.Get("Babel")

bObj := this.ToObject(vm)

globalBabel = &babel{vm: vm, this: this}

if err = vm.ExportTo(bObj.Get("transform"), &globalBabel.transform); err != nil {

return

}

})



return globalBabel, err

}

globalBabel.transform 的定义
使用了goja 的Callable


transform goja.Callable

进行es6代码编译处理

func (b *babel) Transform(logger logrus.FieldLogger, src, filename string) (string, *SourceMap, error) {

b.mutex.Lock()

defer b.mutex.Unlock()

opts := make(map[string]interface{})

for k, v := range DefaultOpts {

opts[k] = v

}

opts["filename"] = filename



startTime := time.Now()

v, err := b.transform(b.this, b.vm.ToValue(src), b.vm.ToValue(opts))

if err != nil {

return "", nil, err

}

logger.WithField("t", time.Since(startTime)).Debug("Babel: Transformed")



vO := v.ToObject(b.vm)

var code string

if err = b.vm.ExportTo(vO.Get("code"), &code); err != nil {

return code, nil, err

}

var rawMap map[string]interface{}

if err = b.vm.ExportTo(vO.Get("map"), &rawMap); err != nil {

return code, nil, err

}

var srcMap SourceMap

if err = mapstructure.Decode(rawMap, &srcMap); err != nil {

return code, &srcMap, err

}

return code, &srcMap, err

}

一个参考集成babel 的demo

参考代码

package main



import (

"demoapp-goja/pkg"

"log"



"github.com/dop251/goja"

)



const (

bablename = "node_modules/babel.min.js"

corejsname = "node_modules/index.js"

demomodule = "node_modules/app.js"

)



var convert func(string) string



var jsCompilerVM *goja.Runtime = goja.New()



func main() {

jsCompilerVM = goja.New()

// 使用go-bindata

bableContent, _ := pkg.Asset(bablename)

corejsContent, _ := pkg.Asset(corejsname)

mydemomodule, _ := pkg.Asset(demomodule)

corejs, _ := goja.Compile(corejsname, string(corejsContent), false)

bable, _ := goja.Compile(bablename, string(bableContent), false)

// 预加载babel 以及core-js

jsCompilerVM.RunProgram(bable)

jsCompilerVM.RunProgram(corejs)

// es6 编译es5 转换为golang 代码

jsCompilerVM.RunString(`var convert = function(es6code) {

return Babel.transform(es6code, { presets: ['env'] }).code;

}

`)

err := jsCompilerVM.ExportTo(jsCompilerVM.Get("convert"), &convert)

if err != nil {

panic(err)

}

// 调用转换

log.Println(convert(string(mydemomodule)))



}



node_modules/app.js 内容

import rong from "./rong.js"

var demo = new rong("dalong",222)

console.log(demo.printInfo())

效果




说明

实践方法参考自k6一个很不错的基于golang 开发的压力测试工具,k6集成goja js 引擎还是比较巧妙的,后边说明下方法
参考资料

https://github.com/loadimpact/k6/blob/master/js/lib/lib.go
https://github.com/loadimpact/k6/blob/master/js/compiler/compiler.go#L85
https://github.com/dop251/goja
https://github.com/dop251/goja/blob/master/runtime.go#L2017
https://github.com/loadimpact/k6/blob/master/js/compiler/compiler.go#L116
https://k6.io/docs/using-k6/modules


总数:0 页次:1/0 首页 尾页  
总数:0 页次:1/0 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1