причина
Некоторое время назад я написал инструмент для генерации документации по API.mkdoc, потому что он не полагается на go CLI, как swag-go. Позже я задался вопросом, могу ли я скомпилировать его в wasm и разместить на веб-странице, чтобы каждый мог понять его после развертывания 0.
достижение
- ( :
если ты правmkdocЗаинтересованы, добро пожаловать в fork&star
некоторые проблемы
- Файловая система используется в инструменте, и файловая система не реализована в wasm_exec.js, предоставленном go
- Используется системный вызов os.Getwd, который напрямую не поддерживается syscall/js.
- Некоторые проблемы взаимодействия между go и js
решить
Файловая система
Нереализованный можно увидеть в wasm_exec.js.node fs API
, то нам просто нужно следоватьnode fs API
реализоватьmemory filesystem
, можно решить проблему с файловой системой.
Но строить колесо самостоятельно слишком хлопотно, поэтому я его искалmemfsЭта библиотека (100 👍 автору). В случае с memfs я назначаю предоставленную им fs для window.fs в соответствии с тем, как он ее использует, и go будет использовать эту fs.
системный вызов
Посмотрите исходный код 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() (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(".")
if err != 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
}
}
Установлено, что он проверит переменную окружения PWD, если обнаружится, что она в данный момент$PWD
Значение $PWD будет использоваться напрямую,
Таким образом, добавление набора env при запуске может получить каталог getwd неверно.
func initJS() {
//...
os.Setenv("PWD", "/")
}
взаимодействовать
Здесь я в основном пишу метод для привязки go log.Println к 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() {
log.SetOutput(console)
// ...
}