使用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 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
101 9
|
2月前
|
前端开发 JavaScript
探索现代Web应用的微前端架构
【10月更文挑战第40天】在数字时代的浪潮中,Web应用的发展日益复杂多变。微前端架构作为一种新兴的设计理念,正逐步改变着传统的单一前端开发模式。本文将深入探讨微前端的核心概念、实现原理及其在实际项目中的应用,同时通过一个简单的代码示例,揭示如何将一个庞大的前端工程拆分成小而美的模块,进而提升项目的可维护性、可扩展性和开发效率。
|
2月前
|
开发框架 搜索推荐 数据可视化
Django框架适合开发哪种类型的Web应用程序?
Django 框架凭借其强大的功能、稳定性和可扩展性,几乎可以适应各种类型的 Web 应用程序开发需求。无论是简单的网站还是复杂的企业级系统,Django 都能提供可靠的支持,帮助开发者快速构建高质量的应用。同时,其活跃的社区和丰富的资源也为开发者在项目实施过程中提供了有力的保障。
139 62
|
25天前
|
开发框架 小程序 前端开发
圈子社交app前端+后端源码,uniapp社交兴趣圈子开发,框架php圈子小程序安装搭建
本文介绍了圈子社交APP的源码获取、分析与定制,PHP实现的圈子框架设计及代码编写,以及圈子小程序的安装搭建。涵盖环境配置、数据库设计、前后端开发与接口对接等内容,确保平台的安全性、性能和功能完整性。通过详细指导,帮助开发者快速搭建稳定可靠的圈子社交平台。
|
2月前
|
前端开发 JavaScript 搜索推荐
HTML与CSS在Web组件化中的核心作用及前端技术趋势
本文探讨了HTML与CSS在Web组件化中的核心作用及前端技术趋势。从结构定义、语义化到样式封装与布局控制,两者不仅提升了代码复用率和可维护性,还通过响应式设计、动态样式等技术增强了用户体验。面对兼容性、代码复杂度等挑战,文章提出了相应的解决策略,强调了持续创新的重要性,旨在构建高效、灵活的Web应用。
56 6
|
2月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
54 2
|
2月前
|
前端开发 JavaScript API
前端界的秘密武器:掌握这些框架,让你轻松秒杀99%的同行!
前端开发日新月异,掌握几个明星框架如React、Vue.js和Angular,不仅能让工作更得心应手,还能轻松超越同行。React以高效的虚拟DOM和组件化著称;Vue.js简洁易懂,灵活性高;Angular提供全面的解决方案,适合大型应用。此外,轻量级的Svelte也值得关注,其编译时处理设计提升了应用性能。掌握这些框架,结合深刻理解和灵活运用,助你在前端领域脱颖而出。
41 9
|
2月前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
178 1
|
2月前
|
消息中间件 前端开发 JavaScript
探索微前端架构:构建现代Web应用的新策略
本文探讨了微前端架构的概念、优势及实施策略,旨在解决传统单体应用难以快速迭代和团队协作的问题。微前端允许不同团队独立开发、部署应用的各部分,提升灵活性与可维护性。文中还讨论了技术栈灵活性、独立部署、团队自治等优势,并提出了定义清晰接口、使用Web组件、状态管理和样式隔离等实施策略。
|
2月前
|
监控 前端开发 JavaScript
探索微前端架构:构建可扩展的现代Web应用
【10月更文挑战第29天】本文探讨了微前端架构的核心概念、优势及实施策略,通过将大型前端应用拆分为多个独立的微应用,提高开发效率、增强可维护性,并支持灵活的技术选型。实际案例包括Spotify和Zalando的成功应用。

热门文章

最新文章