Visual Studio Code でpackage.jsonが複数ある場合に各scriptsの内容をタスクランナーから実行する方法
何がしたいのか
package.jsonがカレントディレクトリになく、 且つ package.jsonが複数のサブディレクトリにまたがって複数存在する場合に、 VSCodeのタスクランナーからそれぞれのpackage.jsonの scripts に指定されているscriptを実行したい!!!!
したい!!!
どうしてそう思った
Webのフロントもサーバーも両方TypeScriptで書いていて、 フロントとサーバーを別々のフォルダで管理して、pacakge.jsonもそれぞれ別々に用意していると、 以下のようなフォルダ構成なることが考えられる。
というか、なった!
こういう構成にするのが馬鹿だって石投げつけられたら、もうそのまま石投げつけられますが!
root/ ←ここから VSCode で開いている │ ├ client/ ← フロントエンド用プロジェクト Angular2とかやる方 │ ├ index.ts │ ├ webpack.config.json │ │ ...etc │ └ package.json ← フロントエンド用の packatge.json こっちにフロントのビルド用scriptが書いてある │ └ server/ ← バックエンド用プロジェクト Express 使ってAPI作る ├ app.ts │ ...etc └ package.json ← バックエンド用の packatge.json こっちにサーバーのビルド用scriptが書いてある
で、俺は開いた。VSCodeのタスクランナーを。意気揚々と。Command + shift + P からの task からの Enter ターンッ !! npm を選択して Enter ターンッ!!!
あれ?カレントディレクトリに package.json にない場合どうするんだ??? というか複数のpackage.jsonを扱いたい場合どうするんだ? 絶望しました。
まぁ、VSCodeには端末機能あるからそこでコマンド叩けばいいんだけど、やっぱりタスクランナーがあるんだったらそれでやりたい!!!
pacakge.jsonのscriptsの内容
client/package.json
フロント側のpackage.json webpack使ってビルドしてる。 webpackの方で、ビルドした.jsファイルを server/public/script/ に吐き出してる。 とりあえず VSCodeのタスクランナーから build と watch を叩きたい
{ // 省略 "scripts": { "build": "webpack --progress --colors --config webpack.config.dev.js", "watch": "webpack --progress --colors --watch --config webpack.config.dev.js", "build-product": "webpack --progress --colors --config webpack.config.prod.js", "watch-product": "webpack --progress --colors --watch --config webpack.config.prod.js" }, // 省略 }
server/package.json
サーバー側のpackage.json 一番使ってるのが dev だから最悪これだけでもタスクランナーから叩きたい
{ // 省略 "scripts": { "start": "node ./app.js", "dev": "tsc --watch & node-dev ./app.js", "build": "tsc", "watch": "tsc --watch" }, // 省略 }
結論
できた!
できた!
こうする!
これを(タスクの種類で npm を選んだ場合の初期状態)
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "0.1.0", "command": "npm", "isShellCommand": true, "showOutput": "always", "suppressTaskName": true, "tasks": [ { "taskName": "install", "args": ["install"] }, { "taskName": "update", "args": ["update"] }, { "taskName": "test", "args": ["run", "test"] } ] }
こうする!
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "0.1.0", "command": "sh", "isShellCommand": true, "showOutput": "always", "suppressTaskName": true, "args": ["-c"], "tasks": [ { "taskName": "build", "args": ["npm -prefix ./client run build && npm -prefix ./server run build;"] }, { "taskName": "watch", "args": ["npm -prefix ./client run watch & npm -prefix ./server run dev;"] } ] }
ポイント1
shコマンドを指定する。npmじゃなくてsh。発想の転換
"command": "sh",
ポイント2
-cオプションをつける。 shellとか詳しくないけど、ようは端末で打った内容をそのまま実行するためのオプションらしい。
"args": ["-c"]
ポイント3
args にもう全部書いちゃう!
"args": ["npm -prefix ./client run build && npm -prefix ./server run build;"]
つまりこういうことだね。知らんけど。
$ sh -c npm -prefix ./client run build && npm -prefix ./server run build;
ポイント4
-prefix をつける。
npm -prefix ./client run build
https://docs.npmjs.com/cli/prefix
こういうことらしいです。
なるほどね ← 分かってない
ポイント5
&& とか & とか使って、フロント側の npm run と サーバー側の npm run をまとめて実行してやる。
今回は build の方は実行した一発だけでいいから &&(http://itpro.nikkeibp.co.jp/article/COLUMN/20060224/230604/) watchの方は両方はバックグラウンドで動かしたいから &(http://itpro.nikkeibp.co.jp/article/COLUMN/20060224/230589/) を使った。← よくわかってない。
npm -prefix ./client run build && npm -prefix ./server run build;
npm -prefix ./client run watch & npm -prefix ./server run dev;
まぁ、普段は IntelliJ使ってるんだけどな!!!!!!!!!!!
Visual Studio Code で TypeScript2.0を書いたらハマったこと
前回の記事から2ヶ月?くらいたっていて、気がついたらTypeScript2.0がリリースされていた…
ので、Visual Studio Code で TypeScript2.0 を書こうとしたらハマったところと解決策のメモ。 まぁ、普段は IntelliJ IDEA で書いているだけど。
まず、以下のようなコードを TypeScript で書いて、Visual Studio Code のタスクランナーでコンパイル使用としたら怒られた。
'use strict'; class Singleton { /** instanceを保持します。 */ private static instance: Singleton; /** * コンストラクタ * TypeScript2.0からconstructor に private が指定できるようになった。 */ private constructor() { // do nothing. } /** * インスタンス取得メソッド * @return {Singleton} Singletonのインスタンス */ public static getInstance() : Singleton { if (!Singleton.instance) { Singleton.instance = new Singleton(); } return Singleton.instance; } public sayHello() : void { console.log('Hello World'); } } Singleton.getInstance().sayHello();
どこで怒られたかっていうと、コンストラクタのところ。
/** * コンストラクタ * TypeScript2.0からconstructor に private が指定できるようになった。 */ private constructor() { // do nothing. }
コンストラクタに private が指定できるようになったのは TypeScript2.0 からで、どうもVisual Studio Code が内部的に使っているTypeScriptは1.8らしい。
なので、Visual Studio Code 側の設定を変えてあげる必要がある。「ワークスペース設定」を開き…
以下のように、ワークスペースの設定でTypeScriptを自分がインストールしたものを指定してあげる。
すると、
うまくいった!めでたしめでたし。
TypeScriptの環境を整えた話
TypeScript用開発環境を整えたのでメモ
TypeScript用開発環境を整えるのでなんやかんや試して、自分なりにミニマムで開発しやすい環境を作れたので、それのメモ。 個人的には一番 IntelliJ IDEA 上でステップ実行できたってのがでかい。
一応作ったソースとか設定とかはGitHub上にあげておきます。
やりたいこと
- TypeScriptを書きたい
- ソースはモジュール化しておきたい
- import/export などを解決したい
- 今回はフロントエンドに使用したいので、jQueryも使えるようにしておきたい
- IntelliJ IDEA 上でステップ実行したい
やったこと
まずは作業ディレクトリに移動
$ cd <作業ディレクトリのパス>
なにはともあれ npm init
$ npm init
とりあえずEnter連打。 細かいところはあとから修正します。
typescriptをインストール
$ npm install typescript -g
webpackをインストール
今回は依存関係の解決にwebpackを使用するのでwebpackもインストールします。 一緒に、webpackでtypescriptを扱うためのts-loaderもインストールします。
$ npm install webpack -g $ npm install ts-loader --save-dev
webpack.confing.jsを作成
次にwebpack用設定ファイルを作成する。
// コマンドメモ // --watch : ファイルの変更を監視 ビルドの自動化 // $ webpack --progress --colors --watch var path = require('path'); module.exports = { // エントリーポイント entry: './script/src/main.ts', // ソースマップ出力 devtool: "#source-map", // 出力先設定 output: { path: __dirname, filename: './script/dist/bundle.js' }, module: { loaders: [ { test: /\.ts$/, loader: 'ts-loader' } ] }, resolve: { // ここに登録した拡張子は import時に省略できる extensions: ['', '.ts', '.js'] } };
tsconfig.json を作成
TypeScriptからJavaScriptへ変換する際の設定ファイル(とお思います。) とりあえず以下のコピペで問題ない(と思います。)
{ "compilerOptions": { "module": "commonjs", "target": "es5", "noImplicitAny": false, "sourceMap": true }, "exclude": [ "typings/main.d.ts", "typings/main", "node_modules" ] }
その2 に続く
Go言語でAPI作った話
書くこと
Go言語でRestAPIつくりましたって話
参考にした本とか記事とか
環境構築とか
書いたソースと簡単な説明とか
その他感想とか
Go言語でRestAPI作りましたって話
RestAPIって言っても、ランダムに運勢をJSON形式で返すだけの おみくじAPIです。 GETメソッドで omikuji.json を叩くと運勢が帰ってきます。 ブラウザで直接開いた場合以下のような感じです。まんまJSONです。
参考にした本とか記事とか
まず一通り基本的な文法とか、お作法的なところを↓の本で勉強しました。 ちなみに今回はKindle版を買った。検索は対応してるっぽいです。
https://www.amazon.co.jp/%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0Go%E8%A8%80%E8%AA%9E-%E6%9D%BE%E5%B0%BE%E6%84%9B%E8%B3%80-ebook/dp/B01FH3KRTI?ie=UTF8&qid=&ref_=tmm_kin_swatch_0&sr=www.amazon.co.jp
で、RestAPI作りたいなーって思ったら以下の記事を見つけたので参考にさせていただきました。
環境構築とか
上の記事で使用されている go-json-rest なるライブラリを使いましょうという方針でいく。 が、俺の環境にはまだそんなライブラリを落としてきていない。ので落としてくるのだが、じゃあどうやるのかというと、 俺は↓の記事を参考に ghq なる物をインストールし、ghqを使用して go-json-rest をインストールしました。
書いたソースと簡単な説明とか
構成
パッケージ構成は以下のようにしました。 ソース内の packaege ~~~ も実際のフォルダ構成と同じ。
main ├ bin/ └ main/ ├ OmikujiApi.go │ ├ data/ │ └ OmikujiData.go │ └ resource └ Omikuji.go
OmikujiApi.go
なんかいろいろやってる。 go-json-rest ライブラリのAPIをちゃんと読まないといけないんだけど、 たぶん、 * 受け付けるメソッドの設定(GETとかPOSTとかDELETEとか)、 * パスのルーティング(? っていう言葉でいいのかな) http:// ... /omikuji.json というパスとそのパスにアクセスされた場合に実行する処理の紐付け * 何番のポートを使うかの設定 (今回は 8081番)
をやっている。(つもりになってます。)
package main import ( "net/http" "github.com/ant0ine/go-json-rest/rest" "./resource" "log" ) func main() { api := rest.NewApi() api.Use(rest.DefaultDevStack...) api.Use(&rest.CorsMiddleware{ RejectNonCorsRequests: false, OriginValidator: func(origin string, request *rest.Request) bool { return true }, AllowedMethods: []string{"GET"}, AllowedHeaders: []string{ "Accept", "Content-Type", "X-Custom-Header", "Origin"}, AccessControlAllowCredentials: true, AccessControlMaxAge: 3600, }) router, err := rest.MakeRouter( rest.Get("/omikuji.json", resource.GetOmikuji), ) if err != nil { log.Fatal(err) } api.SetApp(router) log.Fatal(http.ListenAndServe(":8081", api.MakeHandler())) }
OmikujiData.go これが実際にJSON形式にして返すデータ。 SetUnsei() を使うと運勢がランダムにセットされる。
package data import ( "time" "math/rand" ) type OmikujiData struct { Unsei string } func (omikujiData *OmikujiData) SetUnsei() { unseiMap := map[int]string{ 0: "大吉", 1: "中吉", 2: "小吉", 3: "末吉", 4: "吉", 5: "凶", 6: "末凶", 7: "小凶", 8: "中凶", 9: "大凶", } rand.Seed(time.Now().UnixNano()) unsei := unseiMap[rand.Intn(10)] omikujiData.Unsei = unsei }
Omikuji.go
OmikujiData構造体をJSONにして返す関数を書いた。
package resource import ( "github.com/ant0ine/go-json-rest/rest" "../data" ) func GetOmikuji(w rest.ResponseWriter, r *rest.Request) { omikujiData := new (data.OmikujiData) omikujiData.SetUnsei() w.WriteJson(omikujiData) }
その他感想とか
正直、ここまでめっちゃスムーズにできたと思う。 JavaでJAX-RSのプロジェクト作って、RestAPIの動作確認まで…とかと比べてだけど。 たぶん Go言語の方がずっと詰まるところが少なかったと思う。
動作が確認できるまでの途中途中での、「なんかうまくいかないんだが?」っていうのってモチベーションの維持に非常に関わるので、 そういうのが少ないのって素晴らしいと思う。まる。
webpack + Babel + React(ES2015使用)の設定
やりたいこと。 * ReactをJSXを使用して書きたい。 * EcmaScriptの構文も使用して書きたい * .jsファイルと、.jsxファイルに変更があった場合自動的にビルドしてほしい。 * 自動的にソースマップも出力してほしい。
webpack.config.js
// コマンドメモ // -p : minify // --watch : ファイルの変更を監視 ビルドの自動化 // $ webpack -p --progress --colors --watch var path = require('path'); var webpack = require('webpack'); module.exports = { // エントリーポイント entry: './script/src/main.jsx', // ソースマップ出力 devtool: "#source-map", // 出力先設定 output: { path: __dirname, filename: './script/dest/bundle.js' }, module: { loaders: [ // .jsxファイル用 { test: /.jsx?$/, loader: 'babel-loader', exclude: /node_modules/, query: { presets: ['es2015', 'react'] } }, // .jsファイル用 { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/, query: { presets: ['es2015'] } } ] }, resolve: { // ここに登録した拡張子は import時に省略できる extensions: ['', '.js', '.jsx'] } };
以下のコマンドで実行
$ webpack -p --progress --colors --watch
俺がBracketsに入れてるエクステンションまとめ
Mac でも Windows でも使えて、動作が安定していて、標準で日本語に対応していてライブプレビューできて簡易サーバー立ち上げられる最強伝説エディタ Bracketsに俺がよく追加しているエクステンションまとめた。
相変わらずUTF-8のファイルしか扱えないけど、そこは割り切っていこう。
React (.jsx) language mode for Brackets
React(.jsx)モードを追加するエクステンション
Go-IDE
Go言語モードを追加するエクステンション
Monokai Dark Soda
テーマを変更するやつ。 黒ベースで最高にCoolだぜ。
FuncDocr
JSDocのテンプレートを挿入してくれるやつ。 ためしてないけどPHPでもいけるっぽい。
Tabs - Custom Working
開いてるファイルをタブ表示してくれるやつ。
Show Whitespace
スペースとかタブとかを可視化してくれるやつ。 可視化されてないと不安になるので、精神衛生上とても重要なエクステンション。
Indent Guides
インデントにあわせて縦線を表示してくれるやつ。 上の Show Whitespace とのコンボで最強になれる。
Brackets Exclude Indexing FileTree
開いているフォルダー内に 30000以上ファイルがあるとエラーになるんだが、node_moduleフォルダとかあると簡単に30000ファイルくらい超えるので、node_moduleを編集対象のフォルダから除外してくれるエクステンション。
上にあげたエクステンションのみ有効にした場合こんな感じになる。
もっとゴテゴテにカスタマイズしてた時もあったけど、今はシンプルに保つのもいいかなと思ったりしているところ。
「UXデザイン入門」読みました
↑の「UXデザイン入門」を読んだ。
というのも、UIを作る技術があっても、UIといっしょに語られることが多いUXについてほとんど勉強したことがなかったので。
本の内容としては、UXを設計する過程で行うべきアンケートとかインタビューとかの方法が詳しく解説されていた。
一方で「UXデザイン入門」と言っているだけあり、どういう場合にどういうコンポーネントを使うと効果的とかいう話はほとんどなかった。そもそも、そういう定石みたいなものなんて無いのか。
面白いなーって思ったのは、設計する上で、そのアプリケーションを使用想定するターゲット(ペルソナ)を詳細に(名前や趣味まで)設定すべきっていうところで、はぁーなるほどぉってなった。
まる。