The cause of

Some time ago, I wrote an API document generation tool mkdoc, because I didn’t rely on go CLI like swag-Go, and then I wondered if I could compile it into WASM and put it on the web, so that it would be easy for everyone to deploy 0 and have a good understanding of it.

results

👉 Online experience 👈

  • (:

If you are interested in MKDoc, welcome Fork&Star

Some of the problems

  1. The utility uses a file system that is not implemented in the WASm_exec.js provided by GO
  2. Getwd system call is used, syscall/js is not directly supported
  3. Some interaction issues between GO and JS

To solve

The file system

In wasm_exec.js you can see an unimplemented Node FS API, so simply implement a memory Filesystem in the browser according to the Node FS API to solve the filesystem problem.

But it was too much trouble to build your own wheels, so I found the memfs library (click 100 👍 for the author). With memfs, I assign the fs provided to window.fs as it is used, and go will use the FS.

The system calls

Look at the source code of os.getwd

// Getwd returns a rooted path name corresponding to the
// current directory. If the current directory can be
// reached via multiple paths (due to symbolic links),
// Getwd may return any one of them.
func Getwd(a) (dir string, err error) {
	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
		return syscall.Getwd()
	}

	// Clumsy but widespread kludge:
	// if $PWD is set and matches ".", use it.
	dot, err := statNolog(".")
	iferr ! =nil {
		return "", err
	}
	dir = Getenv("PWD")
	if len(dir) > 0 && dir[0] = ='/' {
		d, err := statNolog(dir)
		if err == nil && SameFile(dot, d) {
			return dir, nil}}Copy the code

$PWD = $PWD; $PWD = $PWD;

func initJS(a) {
	/ /...
	os.Setenv("PWD"."/")}Copy the code

interaction

Log = js console.log = js console.log = js console.log

func (c *ConsoleWriter) Write(p []byte) (n int, err error) {
	js.Global().Get("console").Call("log".string(p))
	return len(p), nil
}

func (c *ConsoleWriter) Log(s string) {
	c.Write([]byte(s))
}

var console = new(ConsoleWriter)

func initJS(a) {
	log.SetOutput(console)
	// ...
}

Copy the code