Go + Vue.js + Docker でSPAを作るまで - 第2章 Vue CLI でアプリケーション開発環境を準備する(TypeScript, Stylus使用) -
Vue CLIでプロジェクトを作成(アプリケーション開発環境を準備する)には サブコマンドの createを使用する。
※ 2.x系ではvue init
を使用していたが、3.x系ではvue create
なので注意
基本的には公式の情報こそ正義だと思っているので、まずはそれをみるといいと思います。
ここでは手順の確認を行うだけなので適当な名前のプロジェクト名の開発環境をセットアプする。
vue create test-project
すると以下のような選択を求められる。defaultを選択すると基本的なBabel + ESLintセットアップと、
付属のデフォルトプリセットでプロジェクトが開始される。
後からTypeScript等を導入することも可能らしいが、自動でセットアップしてもらったほうが安心なので、
今回はManually select featuresを選択する
Vue CLI v3.0.4 ? Please pick a preset: default (babel, eslint) ❯ Manually select features
すると以下のような選択画面に移行する。
英語で書いてある通り、
ここでは TypeScriptとCSS Pre-processorsを追加で選択する。
Vue RouterやVuexが必要な場合はそれも選択。
Vue CLI v3.0.4 ? Please pick a preset: Manually select features ? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection) ❯◉ Babel ◉ TypeScript ◯ Progressive Web App (PWA) Support ◯ Router ◯ Vuex ◉ CSS Pre-processors ◉ Linter / Formatter ◯ Unit Testing ◯ E2E Testing
すると以下のように追加の設定を求められる。
特にPick a CSS pre-processorでは今回はStylusにするのを忘れないように。。。
? Use class-style component syntax? (Y/n) Y ? Use Babel alongside TypeScript for auto-detected polyfills? Y ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): (Use arrow keys) Sass/SCSS Less ❯ Stylus ? Pick a linter / formatter config: (Use arrow keys) ❯ TSLint ESLint with error prevention only ESLint + Airbnb config ESLint + Standard config ESLint + Prettier ? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection) ❯◉ Lint on save ◯ Lint and fix on commit ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arrow keys) ❯ In dedicated config files In package.json ? Save this as a preset for future projects? (y/N) N
それらの設定が完了するとセットアップが進行し、最終的に以下のような内容がターミナルに出力する。
🎉 Successfully created project test-project. 👉 Get started with the following commands: $ cd test-project $ npm run serve
あとは指示の通りnpm run serve
を実行して起動できればとりあえずのセットアップは完了です。
Go + Vue.js + Docker でSPAを作るまで - 第1章 Vue CLI を導入する -
まずはフロント部分で使用するVue.jsの環境構築をVue CLIを使って行うため、ライブラリを導入する。 なお、node.jsとnpmについては入っている前提で進める。
npm --version > 6.4.1 node --version > v8.11.1
1. Vue CLIの導入
Vue CLIはバージョン3を使います。
npm install -g @vue/cli
作成時点では3.04が最新のバージョン
vue --version > 3.0.4
特別必要というわけではないが以下のライブラリもインストールすると簡単にプロトタイプがつくれます。
npm install -g @vue/cli-service-global echo '<template><h1>Hello!</h1></template>' > App.vue vue serve
それについては以下のサイトに説明を任せます。
FN1807003 | Vue CLI 3入門 03: プロトタイプを簡単につくる | HTML5 : テクニカルノート
Go + Vue.js + Docker でSPAを作るまで
GoとVue.js の勉強のために一つ一つ段階を踏んでいく。
javascriptではTypeScript、CSSではStylusを使用する。
Goのio.Writer と標準出力、標準エラー出力についてちょっと深掘りしてみた
1. 導入
io.Writerインターフェースは馴染み深いところでいうとFprintやFprintlnなどのfmtパッケージの関数の第一引数に指定され、
それぞれのメソッド内ではw.Write(p.buf)
(w は io.Writer型のレシーバ)を呼び出したりする。
このFprintlnもまた、おなじみのfmt.Printlnの内部で第一引数にos.Stdoutを取って呼び出されている。
また、io.Writerを満たす構造体としては、os.Create("test.txt")の返り値として返される*Fileなどがio.Writerインターフェースを満たしてる。
(*FileもWriteメソッドを定義しており、ファイルへの書き込みを行う)
2. io.Writerの実装
io.goにおけるio.Writer
インターフェースの定義は以下の通りとてもシンプルである。
// Writer is the interface that wraps the basic Write method. // // Write writes len(p) bytes from p to the underlying data stream. // It returns the number of bytes written from p (0 <= n <= len(p)) // and any error encountered that caused the write to stop early. // Write must return a non-nil error if it returns n < len(p). // Write must not modify the slice data, even temporarily. // // Implementations must not retain p. type Writer interface { Write(p []byte) (n int, err error) }
実装側が満たすべき仕様はバイト配列p
を引数とし、書き込んだバイト数n
と、エラーが発生した場合はその内容を返すといった程度である。
(コメントを見ると、書き込みバイト数n
とバイト配列の長さが一致しない場合はnil
以外のエラーを返す必要がある、と記載されている)
このようにインターフェースがシンプルなのでWrite
メソッドを実装している型次第で、標準出力・ファイル、バッファ、HTTPリクエスト等への
書き込み処理をWrite
メソッドを通して実現することができる。
3. 標準出力、標準エラー出力の定義調査
導入 に書いたfmt
パッケージの関数Fpint
やFprintln
を使う場合、一般的には標準出力os.Stdout
、標準エラー出力os.Stderr
に流したり、テストのためにbytes.Buffer
に書き込んだりして使用することが多い。
では標準出力os.Stdout
、標準エラー出力os.Stderr
と一体なんなのか調べて見るためにos
パッケージのStdout
、Stderr
について深く見ていくと
・file.go(osパッケージ)
// Stdin, Stdout, and Stderr are open Files pointing to the standard input, // standard output, and standard error file descriptors. // // Note that the Go runtime writes to standard error for panics and crashes; // closing Stderr may cause those messages to go elsewhere, perhaps // to a file opened later. var ( Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin") Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout") Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr") )
・syscall_unix.go(syscallパッケージ): macの場合
var ( Stdin = 0 Stdout = 1 Stderr = 2 )
・file_unix.go(osパッケージ): macの場合
// NewFile returns a new File with the given file descriptor and // name. The returned value will be nil if fd is not a valid file // descriptor. func NewFile(fd uintptr, name string) *File { return newFile(fd, name, kindNewFile) }
という実装になっており、標準入力os.Stdin
、標準出力os.Stdout
、標準エラー出力os.Stderr
も結局はファイルの作成os.Create
やオープンos.Open
同様に*File
を返すようになっている。
*FIle
のWrite
メソッドの呼び出しを追っていくと、最終的にpoll
パッケージのfd_unix.goのWrite
メソッドに行き着き、
// Write implements io.Writer. func (fd *FD) Write(p []byte) (int, error) { if err := fd.writeLock(); err != nil { return 0, err } defer fd.writeUnlock() if err := fd.pd.prepareWrite(fd.isFile); err != nil { return 0, err } var nn int for { max := len(p) if fd.IsStream && max-nn > maxRW { max = nn + maxRW } n, err := syscall.Write(fd.Sysfd, p[nn:max]) if n > 0 { nn += n } if nn == len(p) { return nn, err } if err == syscall.EAGAIN && fd.pd.pollable() { if err = fd.pd.waitWrite(fd.isFile); err == nil { continue } } if err != nil { return nn, err } if n == 0 { return nn, io.ErrUnexpectedEOF } } }
syscall.Write
の第一引数で指定したファイルディスクリプタに対して書き込むようにシステムコールをしていることがわかります。
(本当はsyscall.Write
の定義元へとさらに潜れるがここでは割愛)
ここで出てくるファイルディスクリプタfd.Sysfd
の値はNewFile
の第一引数で指定した値と一致し(詳しくはfile_unix.goのnewFile
関数参照)、
前述の通り標準入力os.Stdin
、標準出力os.Stdout
、標準エラー出力os.Stderr
においてはそれぞれ0, 1, 2になる。
これは0: 標準入力Stdin
、1: 標準出力Stdout
、2: 標準エラー出力Stderr
の3つについてはOSが最初にファイルディスクリプタとして割り当てるためである。
ちなみにos.Create
やos.Open
の場合はともにsyscall.Open
が呼び出され、syscall.Open
の第一戻り値がファイルディスクリプタに設定される。
といった感じでGoでは比較的簡単に低いレイヤーについて深掘りできるので大変学びが深い。
Goならわかるシステムプログラミングは良書。
GCPでCloud SQL に Cloud SQL Proxy で接続できるようにする
プログラマのためのGoogle Cloud Platform入門(https://www.amazon.co.jp/dp/B0721JNVGT) を読み進めながら備忘録として書く。
文章の推敲はあとでする(多分しない)。実行環境はGCEでlinuxならどれでもいけるはずです。
実際GCPの変更で危殆化する可能性あるんですが、そうなる前に必要になる可能性もあるんで書きます。
本家: https://cloud.google.com/sql/docs/mysql/external-connection-methods?hl=ja
1. Cloud SQL Admin API を有効化する。
[ナビゲーションバー]
->[APIとサービス]
->[ライブラリ]
->[Cloud SQL Admin API]
有効化する。プログラマのためのGoogle Cloud Platform入門だと「Cloud SQL API」ってなってるけど
名前が変わったぽい。
2.データベースの作成
割愛(create database hoge_db; とか)。
ついでにroot以外のユーザも作っておくとイイ(grant all privileges on hoge_db.* to hoge_user@"%" identified by 'password' with grant option; とか)。
3.Cloud SQL Proxy のインストール
Cloud SQL Proxy のダウンロード
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
プロキシを実行できるようにします。
chmod +x cloud_sql_proxy
プロキシ ソケットを格納するディレクトリを作成する(Unix ソケットを使う場合)。
sudo mkdir /cloudsql; sudo chmod 777 /cloudsql
プロキシを開始する。サービスとして登録し、自動起動すると便利。
./cloud_sql_proxy -dir=/cloudsql -instances=<Cloud SQL におけるインスタンス接続名>
4.MySQL セッションを開始。
mysql -u <USERNAME> -p -S /cloudsql/<Cloud SQL におけるインスタンス接続名>
何やかんややっぱり公式情報が一番だと思う。(https://cloud.google.com/sql/docs/mysql/connect-compute-engine?hl=ja)
GCEでインスタンスを立てる時の手順、設定あれこれ
プログラマのためのGoogle Cloud Platform入門(https://www.amazon.co.jp/dp/B0721JNVGT) を読み進めながら備忘録として書く。
文章の推敲はあとでする(多分しない)。
1.プロジェクトを作成
[ナビゲーションバー]
->[ホーム]
->[プロジェクト設定]
->[リソースを管理]
->[プロジェクトを作成]
適当な名前をつけてプロジェクトを作成。ここら辺は勘でいける
2.VMインスタンスを作成
[ナビゲーションバー]
-> [Compute Engine]
-> [VM インスタンス]
-> [作成]
- 名前(インスタンスの名前) : 任意
- リージョン・ゾーン : 任意
- マシンタイプ(スペック) : 任意(用途による、デフォルトはvCPU x 1)
- ブートディスク : 好きなOSを選ぶ (CentOS, Ubuntuももちろんある)
- ID と API へのアクセス : VMで実行されるアプリケーションはサービスアカウントを
使用して各Google Cloud API を呼び出す。[各 API にアクセス権を設定]を
選ぶとAPIごとに権限設定ができる。任意 - ファイアウォール : デフォルトではSSH, RDP, ICPM以外の外部ネットワークから受信する全てのトラフィックがブロックされる
webサーバとして使用する際に外部IPを固定する場合は、[管理、セキュリティ、ディスク、ネットワーキング、単一テナンシー]から [ネットワーキング]のタブをクリックし、
[ネットワーク インターフェース]
-> [外部 IP]
-> [IPアドレスを作成]
で名前、説明(任意)を入力し予約(ネットワーク サービス階層は東京リージョンだとプレミアム固定)
上記の設定が完了したのち、[作成]ボタンをクリックしインスタンスを作成する。