NSGo
开源 · 早期预览

用 Go 写一次在每个平台原生运行

  • iOS
  • 轻 App
  • tvOS
  • watchOS
  • macOS
  • Android
  • Windows
  • Linux
  • Web
  • 微信
  • QQ
  • 支付宝
  • 抖音

NSGo 是一个跨平台 UI 框架。应用的状态、布局和样式在 Go 中运行,再由 iOS 及其轻 App、tvOS、watchOS、Android、macOS、Windows、Linux、Web 和各家小程序用各自的视图绘制。

go get -tool github.com/oneo-me/nsgo/cmd/nsgo
NSGo Gallery 的股票演示,桌面布局,运行在 Web 后端
NSGo Gallery 的组件列表,手机布局,运行在 Web 后端
工作原理

Go 掌管应用,平台负责绘制

应用和屏幕之间没有内嵌浏览器,也没有自绘渲染器:每次更新只跨到主线程一次,一批只带变化的部分。

  1. 你的应用Go 或 TSX
    • 组件
    • signal
    • 样式与 Tailwind
  2. NSGo 引擎运行在 Go 中
    • 响应式图
    • flexbox 与 grid
    • 文本准备
  3. 平台原生视图
    • AppKit · UIKit
    • Android View
    • Direct2D · GTK · DOM
你能得到

应用所需的一切,都在一门语言里

真正的原生

每个平台用自己的视图、文本、滚动和无障碍来绘制。

客户端

  • iOSUIKit · CoreText
  • 轻 AppUIKit · CoreText
  • tvOSUIKit · CoreText
  • watchOSSwiftUI · CoreText
  • macOSAppKit · CoreText
  • AndroidAndroid Views
  • WindowsDirect2D · DirectWrite
  • LinuxGTK 4 · Pango

网页

  • WebWebAssembly · DOM

小程序

  • 微信WebAssembly · WXML
  • QQWebAssembly · QML
  • 支付宝WebAssembly · AXML
  • 抖音WebAssembly · TTML

响应式引擎

signal 只更新读取它的地方,动画运行在平台的帧时钟上。

熟悉的布局与样式

flexbox 与 grid、类 CSS 样式、Tailwind 类名、浅色与深色主题、从右到左的语言。

flex-row gap-3 p-6 md:grid-cols-2

内置组件

base 里是无样式的,ui 里是开箱即用的:从按钮、菜单到完整的工具。

  • DataTable
  • 图表
  • 代码编辑器
  • 富文本
  • 终端
  • Dock
  • 命令面板
  • 日期选择
  • 颜色选择
  • Toast
  • Sheet
  • 菜单

Go 或 TSX

用 Go 值写组件,或用 TSX 配合 Tailwind 类名,提前编译,不需要 Node。

像用户一样测试

按文本找到控件并按下它,无窗口或在真实窗口中运行。

随处嵌入

把 NSGo 视图放进 iOS、Android、桌面或 Web 应用。

API

组件就是 Go

元素是结构体,状态是 signal,测试像用户一样按下按钮。

  1. 1
    没有模板语言

    组件就是返回元素的函数。

  2. 2
    细粒度更新

    按下按钮,只有读取计数的那段文本会变。

  3. 3
    同一个测试,到处运行

    在 CI 中无窗口运行,或在原生窗口中运行并截图。

package main

import (
	"fmt"

	"github.com/oneo-me/nsgo"
	"github.com/oneo-me/nsgo/base"
	"github.com/oneo-me/nsgo/core"
)

func Root(cx *core.Scope) core.Node {
	count := core.NewSignal(cx, 0)
	return core.View{
		Style: core.Style{Padding: core.All(24), Gap: 12},
		Children: []core.Node{
			core.Text{ContentFunc: func() string {
				return fmt.Sprintf("Pressed %d times", count.Get())
			}},
			base.Button{
				Label:   "Press me",
				OnPress: func(core.PressEvent) {
					count.Update(func(n int) int { return n + 1 })
				},
				Style: core.Style{
					Padding:      core.Symmetric(6, 14),
					CornerRadius: 8,
					Background:   core.RGB(0x007aff),
					Color:        core.RGB(0xffffff),
				},
				Children: []core.Node{core.Text{Content: "Press me"}},
			},
		},
	}
}

func main() { nsgo.Run(Root) }
运行效果

Pressed 0 times

工作流

一个工具,从第一行代码到上架

nsgo 负责创建、运行、测试和打包应用。它随 Go 安装,在 Go 能运行的地方都能运行。

  1. 01

    创建

    Go、TSX 或混合应用。

    $ go tool nsgo init
  2. 02

    运行

    每次保存都热重载。

    $ go tool nsgo dev
  3. 03

    测试

    无窗口或原生窗口中运行。

    $ go tool nsgo test
  4. 04

    发布

    为每个目标打出签名的包。

    $ go tool nsgo build

开始用 NSGo 构建

把工具安装到你的模块里,然后创建第一个应用。

go get -tool github.com/oneo-me/nsgo/cmd/nsgo