使用WebAssembly和围棋编写前端的Web框架

简介:

目录

 ●  介绍
 ●  初始点
 ●  功能注册
 ●  组件
 ●  构建路由器
 ●  一个完整的例子
 ●  挑战前进
 ●  结论

JavaScript前端框架毫无疑问有助于突破以前在浏览器环境中可能实现的界限。更复杂的应用程序已经建立在React,Angular和VueJS之类的基础之上,仅举几例,并且有一个众所周知的笑话,关于新的前端框架似乎每天都会出现。

然而,这种发展速度对全世界的开发者来说都是一个非常好的消息。通过每个新框架,我们可以发现处理状态的更好方法,或者使用shadow DOM等方式有效地渲染。

然而,最新的趋势似乎是在用JavaScript以外的语言编写这些框架并将它们编译成WebAssembly。我们开始看到由于Lin Clark之类的人对JavaScript和WebAssembly进行通信的方式有了重大改进,我们无疑会看到更多重大改进,因为WebAssembly开始在我们的生活中变得更加突出。

介绍

所以,在本教程中,我认为构建一个用Go编写的非常简单的前端框架的基础是一个好主意,它编译成WebAssembly。这至少包括以下功能:

 ●  功能注册
 ●  组件
 ●  超简单路由

我现在警告你,虽然这些将非常简单,并且无法准备好生产。如果这篇文章有点受欢迎,那么我希望能够将它推向前进,并尝试构建满足半正式前端框架要求的东西。

Github: 这个项目的完整源代码可以在这里找到:elliotforbes / oak。如果您喜欢为项目做出贡献,请随意,我很乐意接受任何拉动请求!

初始点

好的,让我们深入选择我们的编辑器并开始编码!我们要做的第一件事就是创建一个非常简单的东西 index.html ,作为我们前端框架的入口点:


1<!doctype html>
2<!--
3Copyright 2018 The Go Authors. All rights reserved.
4Use of this source code is governed by a BSD-style
5license that can be found in the LICENSE file.
6-->
7<html>
8
9<head>
10 <meta charset="utf-8">
11 <title>Go wasm</title>
12 <script src="./static/wasm_exec.js"></script>
13 <script src="./static/entrypoint.js"></script>
14</head>
15<body>
16
17 <div class="container">
18 <h2>Oak WebAssembly Framework</h2>
19 </div>
20</body>
21
22</html>

您会注意到这些js 文件在顶部导入了2个 文件,这使我们可以执行完成的WebAssembly二进制文件。第一个是大约414行,所以,为了保持本教程的可读性,我建议你从这里下载它:https://github.com/elliotforbes/oak/blob/master/examples/blog/static/ wasm_exec.js

第二个是我们的 entrypoint.js 档案。这将获取并运行 lib.wasm 我们即将构建的内容。


1// static/entrypoint.js
2const go = new Go();
3WebAssembly.instantiateStreaming(fetch("lib.wasm"), go.importObject).then((result) => {
4 go.run(result.instance);
5});

最后,既然我们已经解决了这个问题,我们就可以开始深入了解一些Go代码!创建一个新文件 main.go ,其中包含Oak Web Framework的入口点!


1// main.go
2package main
3
4func main() {
5 println("Oak Framework Initialized")
6}

这很简单。我们创建了一个非常简单的Go程序,只需Oak Framework Initialized 打开我们的Web应用程序即可打印出来 要验证一切正常,我们需要使用以下命令编译它:

1$ GOOS=js GOARCH=wasm go build -o lib.wasm main.go

这应该构建我们的Go代码并输出我们在 lib.wasm 文件中引用的 entrypoint.js 文件。

真棒,如果一切正常,那么我们准备在浏览器中试用它!我们可以使用这样一个非常简单的文件服务器:


1// server.go
2package main
3
4import (
5 "flag"
6 "log"
7 "net/http"
8)
9
10var (
11 listen = flag.String("listen", ":8080", "listen address")
12 dir = flag.String("dir", ".", "directory to serve")
13)
14
15func main() {
16 flag.Parse()
17 log.Printf("listening on %q...", *listen)
18 log.Fatal(http.ListenAndServe(*listen, http.FileServer(http.Dir(*dir))))
19}

然后,您可以通过键入满足您的应用程序 go run server.go ,你应该能够从访问你的应用程序 http://localhost:8080

功能注册

好吧,所以我们有一个相当基本的打印声明工作,但在宏观方案中,我不认为它只是作为Web框架的资格。

让我们来看看如何在Go中构建函数并注册这些函数,以便我们可以在我们的函数中调用它们 index.html我们将创建一个新的实用程序函数,它将同时包含 string 我们函数的名称以及它将映射到的Go函数。

将以下内容添加到现有 main.go 文件中:


1// main.go
2import "syscall/js"
3
4// RegisterFunction
5func RegisterFunction(funcName string, myfunc func(i []js.Value)) {
6 js.Global().Set(funcName, js.NewCallback(myfunc))
7}

所以,这就是事情开始变得有用的地方。我们的框架现在允许我们注册函数,以便框架的用户可以开始创建自己的功能。

使用我们框架的其他项目可以开始注册自己的函数,这些函数随后可以在他们自己的前端应用程序中使用。

组件

所以,我想接下来我们需要考虑添加到我们的框架中的是组件的概念。基本上,我希望能够components/ 在项目中定义一个 使用它的目录,并且在该目录中我希望能够构建一个home.go具有我的主页所需的所有代码的 组件。

那么,我们该怎么做呢?

好吧,React倾向于提供具有render() 函数的类,这些 函数返回HTML / JSX /您希望为所述组件呈现的任何代码。让我们窃取它并在我们自己的组件中使用它。

我本质上希望能够在使用此框架的项目中执行此类操作:


1package components
2
3type HomeComponent struct{}
4
5var Home HomeComponent
6
7func (h HomeComponent) Render() string {
8 return "<h2>Home Component</h2>"
9}

因此,在我的 components 包中,我定义了 HomeComponent 一个Render() 返回HTML 的 方法。

为了向我们的框架添加组件,我们将保持简单,并且只需定义 interface 我们随后定义的任何组件必须遵守的组件。components/comopnent.go 在我们的Oak框架中创建一个新文件 


1// components/component.go
2package component
3
4type Component interface {
5 Render() string
6}

如果我们想要为各种组件添加新功能会发生什么?好吧,这让我们可以做到这一点。我们可以oak.RegisterFunction 在init组件功能中使用 调用 来注册我们想要在组件中使用的任何函数!


1package components
2
3import (
4 "syscall/js"
5
6 "github.com/elliotforbes/oak"
7)
8
9type AboutComponent struct{}
10
11var About AboutComponent
12
13func init() {
14 oak.RegisterFunction("coolFunc", CoolFunc)
15}
16
17func CoolFunc(i []js.Value) {
18 println("does stuff")
19}
20
21func (a AboutComponent) Render() string {
22 return `<div>
23 <h2>About Component Actually Works</h2>
24 <button onClick="coolFunc();">Cool Func</button>
25 </div>`
26}

当我们将它与路由器结合起来时,我们应该能够看到我们 HTML 被渲染到我们的页面,我们应该能够点击那个调用的按钮, coolFunc() 它将does stuff 在我们的浏览器控制台中打印出来 

太棒了,让我们看看我们现在如何构建一个简单的路由器。

构建路由器

好的,我们已经components 在我们的Web框架中得到了概念 我们差不多完成了吗?

不完全是,我们可能需要的下一件事是在不同组件之间导航的方法。大多数框架似乎都 <div> 具有特定的特性 id ,它们会绑定并呈现其中的所有组件,因此我们将在Oak中窃取相同的策略。

让我们router/router.go 在我们的橡木框架中创建一个 文件,以便我们可以开始破解。

在这个中,我们想要将string 路径映射 到组件,我们不会进行任何URL检查,我们现在只需将所有内容保存在内存中以保持简单:


1// router/router.go
2package router
3
4import (
5 "syscall/js"
6
7 "github.com/elliotforbes/oak/component"
8)
9
10type Router struct {
11 Routes map[string]component.Component
12}
13
14var router Router
15
16func init() {
17 router.Routes = make(map[string]component.Component)
18}

因此,在此范围内,我们创建了一个新 Router 结构,其中包含 Routes 了我们在上一节中定义的组件的字符串映射。

路由不是我们框架中的强制性概念,我们希望用户在他们希望初始化新路由器时进行选择。因此,让我们创建一个新函数,它将注册一个 Link 函数,并将我们映射中的第一个路径绑定到我们的 <div id="view"/> html标记:


1// router/router.go
2// ...
3func NewRouter() {
4 js.Global().Set("Link", js.NewCallback(Link))
5 js.Global().Get("document").Call("getElementById", "view").Set("innerHTML", "")
6}
7
8func RegisterRoute(path string, component component.Component) {
9 router.Routes[path] = component
10}
11
12func Link(i []js.Value) {
13 println("Link Hit")
14
15 comp := router.Routes[i[0].String()]
16 html := comp.Render()
17
18 js.Global().Get("document").Call("getElementById", "view").Set("innerHTML", html)
19}

您应该注意到,我们已经创建了一个 RegisterRoute 函数,允许我们将a注册 path 到给定的组件。

我们的 Link 功能也非常酷,因为它允许我们在项目中的各个组件之间导航。我们可以指定非常简单的 <button>元素,以允许我们导航到已注册的路径,如下所示:

1<button onClick="Link('link')">Clicking this will render our mapped Link component</button>

很棒,所以我们现在有一个非常简单的路由器,如果我们想在一个简单的应用程序中使用它,我们可以这样做:


1// my-project/main.go
2package main
3
4import (
5 "github.com/elliotforbes/oak"
6 "github.com/elliotforbes/oak/examples/blog/components"
7 "github.com/elliotforbes/oak/router"
8)
9
10func main() {
11 // Starts the Oak framework
12 oak.Start()
13
14 // Starts our Router
15 router.NewRouter()
16 router.RegisterRoute("home", components.Home)
17 router.RegisterRoute("about", components.About)
18
19 // keeps our app running
20 done := make(chan struct{}, 0)
21 <-done
22}

一个完整的例子

将所有这些放在一起,我们可以开始构建具有组件和路由功能的非常简单的Web应用程序。如果你想看一些关于它是如何工作的例子,那么看一下官方回购中的例子:elliotforbes / oak / examples

挑战前进

这个框架中的代码绝不是生产准备好的,但是我希望这篇文章能够开始讨论如何在Go中开始构建更多生产就绪的框架。

如果不出意外,它开始了识别仍需要做什么的旅程,以使其成为React / Angular / VueJS之类的可行替代方案,所有这些都是大规模加速开发人员生产力的现象框架。

我希望这篇文章能激励你们中的一些人开始研究如何在这个非常简单的起点上进行改进。


原文发布时间为:2018-11-9

本文来自云栖社区合作伙伴“Golang语言社区”,了解相关信息可以关注“Golang语言社区”。

相关文章
|
2月前
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
227 1
|
3月前
|
JavaScript 前端开发 API
|
3月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
296 70
|
8月前
|
前端开发 JavaScript
探索现代Web应用的微前端架构
【10月更文挑战第40天】在数字时代的浪潮中,Web应用的发展日益复杂多变。微前端架构作为一种新兴的设计理念,正逐步改变着传统的单一前端开发模式。本文将深入探讨微前端的核心概念、实现原理及其在实际项目中的应用,同时通过一个简单的代码示例,揭示如何将一个庞大的前端工程拆分成小而美的模块,进而提升项目的可维护性、可扩展性和开发效率。
|
5月前
|
安全 前端开发 开发工具
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
202 5
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
|
5月前
|
前端开发
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
136 1
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
|
8月前
|
前端开发 JavaScript 搜索推荐
HTML与CSS在Web组件化中的核心作用及前端技术趋势
本文探讨了HTML与CSS在Web组件化中的核心作用及前端技术趋势。从结构定义、语义化到样式封装与布局控制,两者不仅提升了代码复用率和可维护性,还通过响应式设计、动态样式等技术增强了用户体验。面对兼容性、代码复杂度等挑战,文章提出了相应的解决策略,强调了持续创新的重要性,旨在构建高效、灵活的Web应用。
137 6
|
8月前
|
前端开发 JavaScript API
前端界的秘密武器:掌握这些框架,让你轻松秒杀99%的同行!
前端开发日新月异,掌握几个明星框架如React、Vue.js和Angular,不仅能让工作更得心应手,还能轻松超越同行。React以高效的虚拟DOM和组件化著称;Vue.js简洁易懂,灵活性高;Angular提供全面的解决方案,适合大型应用。此外,轻量级的Svelte也值得关注,其编译时处理设计提升了应用性能。掌握这些框架,结合深刻理解和灵活运用,助你在前端领域脱颖而出。
85 9
|
8月前
|
消息中间件 前端开发 JavaScript
探索微前端架构:构建现代Web应用的新策略
本文探讨了微前端架构的概念、优势及实施策略,旨在解决传统单体应用难以快速迭代和团队协作的问题。微前端允许不同团队独立开发、部署应用的各部分,提升灵活性与可维护性。文中还讨论了技术栈灵活性、独立部署、团队自治等优势,并提出了定义清晰接口、使用Web组件、状态管理和样式隔离等实施策略。
|
8月前
|
机器学习/深度学习 编解码 JavaScript
探索WebAssembly:加速Web应用性能的神奇引擎
探索WebAssembly:加速Web应用性能的神奇引擎