Goja is an excellent script engine for Go. It can export a Go value to JS engine easily, but you may feel troublesome when deal with a package.
So, I wrote the Goja Tools.
It anaylizes the input go code, then generates a go map, that contains all funcs and values of the src code.
Also, it generates a .ts file for code hints.
go install -v github.com/garfeng/gojatools/cmd/goja_imports@latest
goja_imports -p <dst pkg name> -i <src pkg path> -go <dst go code path> -ja <dst js code path>
# For example:
goja_imports -p js -i compress/gzip -go js/compress.gzip.go -ja js/compress.gzip.ts
goja_imports -p js -i image -go js/image.go -ja js/image.ts
Help:
goja_imports --help
-go string
dst go file (default "js/js.go")
-i string
input package path
-ja string
dst typescript file (default "js/js.ts")
-p string
dst package name
Go:
// Code generated by "goja_imports -p js -i io/ioutil -go io.ioutil.go -ja io.ioutil.ts"; DO NOT EDIT.
// Install by "go get -u -v github.com/garfeng/gojatools/cmd/goja_imports";
//go:generate goja_imports -p js -i io/ioutil -go io.ioutil.go -ja io.ioutil.ts
package js
import (
"github.com/garfeng/gojatools/importgo"
origin "io/ioutil"
)
var ExportJS_IO_IOUTIL = map[string]interface{}{
// Value
"Discard": origin.Discard, // io.Writer |
// Function
// WriteFile writes data to a file named by filename.
// If the file does not exist, WriteFile creates it with permissions perm
// (before umask); otherwise WriteFile truncates it before writing, without changing permissions.
//
// As of Go 1.16, this function simply calls os.WriteFile.
//func WriteFile( filename string, data []byte, perm fs.FileMode,) ( _ error, )
"WriteFile": origin.WriteFile,
// ... other codes
// ReadAll reads from r until an error or EOF and returns the data it read.
// A successful call returns err == nil, not err == EOF. Because ReadAll is
// defined to read from src until EOF, it does not treat an EOF from Read
// as an error to be reported.
//
// As of Go 1.16, this function simply calls io.ReadAll.
//func ReadAll( r io.Reader,) ( _ []byte, _ error, )
"ReadAll": origin.ReadAll,
// NopCloser returns a ReadCloser with a no-op Close method wrapping
// the provided Reader r.
//
// As of Go 1.16, this function simply calls io.NopCloser.
//func NopCloser( r io.Reader,) ( _ io.ReadCloser, )
"NopCloser": origin.NopCloser,
}
func init() {
importgo.Add("io.ioutil", "ioutil", ExportJS_IO_IOUTIL)
}
Typescript:
import io from "./io"
namespace ioutil {
export const Discard: io.Writer = origin.Discard;
// WriteFile writes data to a file named by filename.
// If the file does not exist, WriteFile creates it with permissions perm
// (before umask); otherwise WriteFile truncates it before writing, without changing permissions.
//
// As of Go 1.16, this function simply calls os.WriteFile.
export function WriteFile(filename: string, data: byte[], perm: fs.FileMode) : error {
return origin.WriteFile()
}
// ... other codes
// ReadAll reads from r until an error or EOF and returns the data it read.
// A successful call returns err == nil, not err == EOF. Because ReadAll is
// defined to read from src until EOF, it does not treat an EOF from Read
// as an error to be reported.
//
// As of Go 1.16, this function simply calls io.ReadAll.
export function ReadAll(r: io.Reader) : byte[] {
return origin.ReadAll()
}
// NopCloser returns a ReadCloser with a no-op Close method wrapping
// the provided Reader r.
//
// As of Go 1.16, this function simply calls io.NopCloser.
export function NopCloser(r: io.Reader) : io.ReadCloser {
return origin.NopCloser()
}
}
export default ioutil;
If the method has multiple outputs, the ts code will be:
export class RuneScanner {
UnreadRune() : error {
return origin.UnreadRune();
}
// multiple returns
ReadRune() : [rune, int] {
return origin.ReadRune();
}
}
$ tree js/
js
├── bytes.go
├── bytes.ts
├── image.color.go
├── image.color.ts
├── image.go
├── image.png.go
├── image.png.ts
├── image.ts
├── io.ioutil.go
├── io.ioutil.ts
├── os.go
└── os.ts
0 directories, 12 files
- Windows (Windows 11 x64)
- Linux (Kubuntu 22.04 LTS x64)
- Darwin (no machine to test)
This tool would not exist without them.