Go和Angular的Web应用开发~直到Angular的展示~
首先
用Go和Angular创建Web应用程序。
由于是第一次尝试,所以发布将分几次进行。
此外,在使用Go进行Web应用程序开发时,我认为应该考虑使用已经存在的框架,如gin或gorilla,但同时也可以将其作为学习的机会进行自主开发。
-
- Github
- https://github.com/ponta-dev/angular-go
希望
这次我们将使用Go的Web服务器来显示通过ng new创建的Angular项目的初始显示页面,而不是使用ng serve。
构建环境
Angular CLI: 8.0.1
Go 版本:go1.12.5 windows/amd64
假设Node.js已经安装。
使用Go的模块模式,将项目创建在GOPATH以外的其他位置。
git init //適当なディレクトリで
go mod init github.com/ponta-dev/angular-go
根据需要创建.gitignore等文件。项目层次结构如下所设想。
root
|-server //GOのサーバ側実装(github.com/ponta-dev/angular-go/serverパッケージ)
|-template //Angularのビルド結果のjsやindex.htmlが出力される場所
|-ui //Angularのプロジェクト
go.mod
.gitignore
创建Angular项目
ng new ui
cd ui //以下起動確認
ng serve --open
确认Go的构建
在server/main目录下创建一个main.go和main_test.go文件
内容只需要用fmt.Println(“hello world”)之类的执行确认就可以了
go run ./server/main/main.go //GOの実行確認
go test -v github.com/ponta-dev/angular-go/server/main //テストの実行確認
这是可以在同一个目录中确认Go和Angular运行的位置。
构建设置
更改Angular的配置
想要更改的配置有以下两个:
1. 更改构建结果的输出路径
2. 设置基本URL
以下是中文翻译:
1. 第一个问题是,在使用ng build构建时,输出目标路径默认情况下位于Angular项目内,但对于Go来说略微不舒服,所以需要将输出目标更改为项目根目录下的template目录。
2. 第二个问题是,为了将http://localhost:8080/angular-go作为主页URL对GO的Web服务器进行设置,需要进行基本URL(/angular-go/)的配置。
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "../template", //出力先の変更
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [],
"baseHref": "/angular-go/" //ベースURLの設定
},
在进行ng build和ng serve之前,需要进行基本的URL设置。要注意的是,如果baseHref设置为”angular-go”之类的值,可能无法正确设置(应设置为”/angular-go/”)。
Go语言的实现
使用Go的Web服务器通过net/http包进行实现。 对于特定URL的HTTP请求,注册处理程序并执行某些服务器处理操作。 在这种情况下,对于主页URL的请求,可以返回输出到template目录的index.html。
如果实现了http.Handler接口并且实现了ServeHTTP(ResponseWriter, *Request)函数,那么它就是一个合适的处理程序。
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
当在HandleServeHTTP函数中实现以下内容时,可以返回index.html文件。
//index.htmlテンプレートの取得
index := template.Must(template.ParseFiles(HTMLTemplatePath + "/" + IndexHTML)) // "template/index.html"
//index.htmlの書き込み
if err := index.Execute(w, nil); err != nil {
log.Fatal("index.html Write Error", err)
}
template.Must是html/template包中返回*template.Template的方法的包装器函数。当尝试获取index.html时发生错误时(例如路径错误),它会引发恐慌。
通过将上述处理程序注册到主页URL,可以创建一个Go Web服务器,它将返回使用Angular创建的index.html。
资源访问
虽然可以返回index.html,但是这样做无法在http://localhost:8080/angular-go上显示Angular的用户界面。这是因为无法获取index.html引用的资源文件,例如~~.js和~~.ico。因此,需要允许Go的Web服务器访问这些资源。
然而,资源文件的访问URL是/angular-go/~~.js之类的,因此当前情况下会触发与/angular-go/主页URL相关的处理程序。
即使对所有资源访问都注册处理程序也不太合理,因此需要找到一种巧妙的方法来解决这个问题。
关于这个问题可能有几种解决方案,在我搜索的结果中,出现了以下文章。
-
- Getting Started With Angular and Go :
-
- https://medium.com/@anshap1719/getting-started-with-angular-and-go-setting-up-a-boilerplate-project-8c273b81aa6
AngularのプロジェクトをビルドしてGolangで動かす:
这次笔者打算用一种与上述方法不同的方式来允许资源访问。
请谅解实现可能不够完美或存在不应该使用的实现的可能性。
首先,所有对资源文件的访问都将在主页URL的处理程序中进行处理。使用Go的regexp包的正则表达式来检查请求的路径,以将资源文件(如.js文件)和对主页URL的访问分开。对于对主页URL的访问,将在上述处理程序中返回index.html;而对于对资源文件的访问,则将其作为文件服务器返回相应的资源文件。使用regexp进行正则表达式判定的示例如下所示。
//constで下記のような定数を定義し
ResourceRegexp = `.*\.js$|.*\.ico$|.*\.js\.map$`
// *regexp.Regexp構造体の取得
ResourceRegexp := regexp.MustCompile(ResourceRegexp)
if ResourceRegexp.MatchString(r.URL.Path) {
// リソースファイルに対する処理
}else {
// index.htmlの返却
}
在Go中,文件服务器可通过http.FileServer进行更好的实现。
由于它应该禁止对指定目录以外的访问,所以从安全性的角度来看是推荐的。
http.FileServer的返回值是http.Handler接口的实现,因此只需执行ServeHTTP函数就可以执行文件服务器的处理程序。
// http.StripPrefixでベースURL(/angular-go/を除外する
// http.FileServer(http.Dir(HTMLTemplatePath))でファイルサーバのハンドラを取得
fileServer := http.StripPrefix(HomePrefix, http.FileServer(http.Dir(HTMLTemplatePath)))
// ServeHTTP
// 自前のServeHTTPの引数のリクエストとレスポンスをそのまま受け渡す
if ResourceRegexp.MatchString(r.URL.Path) {
//FileServerのServeHTTPをキック
fileServer.ServeHTTP(w, r)
}
下一次计划
这次我介绍了如何在Go的Web应用程序中显示Angular的Hello World。
下次计划介绍以下内容之一。
-
- PostgreSQLとGoサーバーの通信
- GoサーバをRestのWebAPI化