雑なDart入門
雑なDart入門
はじめに
これは軽く個人的にまとめたもので厳密な内容にはなっていません。
詳しい内容はドキュメントを参照してください。
基本
main関数から実行される。main関数は必須。現状文末セミコロンは必須。
mainはGoやJavaなどと同じ感じ。
main() { var hoge = 'hoge'; print(hoge); }
変数
var, dynamicなどあるが基本的には後述するconstとfinalを多用することになる と思う。JSでconstを基本的に使うのと同様。
varは型が推論されるためnameにはString型の'hoge'が入る。
var name = 'hoge';
dynamicはdynamic型(動的な型)になる。
dynamic name = 'hoge';
下記のように型を明示的に書くことも可能。
String name = 'hoge';
デフォルト値
デフォルト値(ゼロ値)はすべてnullになる。
String hoge; assert(hoge == null);
Finalとconst
constもfinalも再代入不可だがfinalはJSのconstに似ている挙動(finalは参照先が変わる可能性がある)
組み込み型
- numbers (int, double)
- strings
- booleans
- lists
- sets
- maps
- runes
- symbols
関数
Javaっぽく前置型で型を書いてJavascriptっぽく書けばDartになるってイメージ。よく聞くJavaっぽいJavaScriptまま。
String hoge() { return 'hoge'; }
オプションパラメータ
String echo({ String word }) { print(word); return word; } echo(word: 'hello');
名前付きオプションパラメータの定義時には{}をつけて記述する。
[]で囲んだ引数はオプションになる。
String echo([String word]) { print(word); return word; } echo('hello'); echo();
関数は第一級オブジェクト
JSと同じように関数を関数に渡せるよってだけ。
無名関数
var list = ['apples', 'bananas', 'oranges']; list.forEach((item) { print('${list.indexOf(item)}: $item'); });
() {}
で無名関数になる。
まとめ
他にもいろいろあるけどだいたいちょっと変わったJavaっぽいJavaScriptという認識で軽くドキュメント見れば基本的には書けるイメージ。
個人的に気になったいくつかの書き方(今回と重複あり)はあとでまとめる。
参考文献
Next軽く使ってみたので振り返り
とりあえず Docs に軽く目を通して、 Learn Next.js で雰囲気を掴んで、examples を参考にする形でプロフィールサイトなるものを作っていった。
完成してはいないが現在の構造としては下記のような感じになっている。
. ├── components │ ├── Home.js │ ├── RedirectChecker.js │ ├── common │ │ ├── AppBase.js │ │ └── Navbar.js │ ├── form_helpers │ │ └── renderField.js │ └── forms │ └── RedirectChecker.js ├── constants │ └── index.js ├── containers │ ├── RedirectChecker.js │ └── common │ └── Navbar.js ├── ducks │ ├── index.js │ ├── navBar.js │ └── redirectChecker.js ├── env-config.js ├── next.config.js ├── package-lock.json ├── package.json ├── pages │ ├── _app.js │ ├── index.js │ └── redirect_checker.js ├── store.js ├── styles │ └── style.sass └── validators ├── required.js └── url.js
package.jsonは現状下記のような感じ
{ "name": "prof", "version": "2.0.0", "scripts": { "dev": "next", "build": "next build", "start": "next start", "export": "next export", "deploy": "npm run build && npm run export" }, "dependencies": { "@zeit/next-sass": "^1.0.1", "axios": "^0.18.0", "bulma": "^0.7.2", "next": "7.0.2", "next-redux-wrapper": "latest", "node-sass": "^4.11.0", "react": "16.7.0", "react-dom": "16.7.0", "react-redux": "5.0.7", "redux": "4.0.0", "redux-devtools-extension": "2.13.2", "redux-form": "^8.1.0", "redux-thunk": "^2.2.0", "validator": "^10.10.0" }, "license": "ISC", "devDependencies": { "@fortawesome/fontawesome-free": "^5.6.3", "babel-eslint": "^10.0.1", "babel-plugin-transform-define": "^1.3.1", "eslint": "^5.12.0", "eslint-config-prettier": "^3.4.0", "eslint-config-standard": "^12.0.0", "eslint-config-standard-react": "^7.0.2", "eslint-plugin-import": "^2.14.0", "eslint-plugin-node": "^8.0.1", "eslint-plugin-prettier": "^3.0.1", "eslint-plugin-promise": "^4.0.1", "eslint-plugin-react": "^7.12.3", "eslint-plugin-standard": "^4.0.0", "prettier": "^1.15.3" } }
ducks、 flux-standard-action、 with-redux-wrapper、 with-next-sass、 with-universal-configuration-build-timeを参考にして実装を進めていった。
Deploy Next.js project to Netlifyを参考にしてnetlifyにホスティングした。
今後は with-typescript を参考にしてTypeScriptに移行したり、 Atomic Designに従ったディレクトリ構成の検証等もしていく予定。
とりあえずNextはルーティング周りで辛みがないので幸せだった。
よくあるリダイレクトチェックツールを作ってみた
github.com
axiosでリダイレクト一覧を取得できる機能のプルリクが出ているのでそれを利用させてもらって、serverlessで下記のような雑なコードをバックエンドとして書いた。
'use strict' const axios = require('axios') const ACCESS_CONTROL_ALLOW_ORIGIN = process.env.ACCESS_CONTROL_ALLOW_ORIGIN module.exports.trace = async (event, context) => { const { headers, body } = event const parsedBody = JSON.parse(body) try { const { redirects } = await axios.get(parsedBody.url, { trackRedirects: true }) return { statusCode: 200, headers: { "Access-Control-Allow-Origin": ACCESS_CONTROL_ALLOW_ORIGIN }, body: JSON.stringify({ redirects }) } } catch (e) { if (!e.response) return { statusCode: 400, headers: { "Access-Control-Allow-Origin": ACCESS_CONTROL_ALLOW_ORIGIN }, body: JSON.stringify({ error: 'invalid url' }) } return { statusCode: 200, headers: { "Access-Control-Allow-Origin": ACCESS_CONTROL_ALLOW_ORIGIN }, body: JSON.stringify({ redirects: e.response.redirects }) } } }
serverless.ymlは下記のような感じ
service: redirect-checker-backend provider: name: aws runtime: nodejs8.10 region: ap-northeast-1 stage: ${opt:stage, self:custom.defaultStage} environment: ACCESS_CONTROL_ALLOW_ORIGIN: ${self:custom.accessControlAllowOrigin.${self:provider.stage}} custom: defaultStage: dev accessControlAllowOrigin: dev: http://localhost:5000 prod: https://example.com plugins: - serverless-offline functions: trace: handler: handler.trace memorySize: 128 events: - http: path: trace method: post cors: true
フロントが別ドメインのため、cors: true
をserverless.ymlに設定して、ヘッダーにACCESS_CONTROL_ALLOW_ORIGINを付与している。
zlibエラーへの対応(macOS Mojave)
macOS Mojaveでpyenvを用いてpython 3.7.2をインストールしようとした際に下記エラーに遭遇したので共有
zipimport.ZipImportError: can't decompress data; zlib not available make: *** [install] Error 1
上記エラーは下記コマンドの実行で解決する
xcode-select --install sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
brewでzlibを入れようとしても解決しないので注意
参考
[MacOS Mojave]pyenvでpythonのインストールがzlibエラーで失敗した時の対応
macOS mojaveでzlibが見つからない場合の対処法
最低限の努力でターミナル周りを少し良くする(Macでbash, terminalを使っている人向け)
Serverless + Ruby で作る LINE Bot
まずLINE Developers にて Messaging API でチャネルを作成する。
LINE周りは、1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefestなどを参考にすると良いと思う。Qiitaにいろいろ記事があるので誰でも作れるはず。
流れとしては下記のような形になる。
プロバイダー作成→Messaging APIでチャネル作成→アクセストークン発行、「Webhook送信」を「利用する」に設定、「LINE@機能」全て「利用しない」に設定。
* 2019年1月4日時点では「Webhook送信」を「利用する」に設定しても反映されないバグがある模様。リロードすると、「利用しない」に戻っていることがある。接続確認は動いてしまうようなので注意。
WebhookURLは後ほど設定する。
上記リンク先の作業に続けて行う。
bundle init
上記コマンド実行後、生成されたGemfileに下記を追加する。
gem 'line-bot-api', '~> 1.3'
その後下記コマンドを実行する。
bundle install --path vendor/bundle
serverless.ymlは下記のような形に変更する。secret.ymlファイルからLINEのシークレットやトークンを読み込む形にしてある。
service: aws-ruby-example provider: name: aws runtime: ruby2.5 region: ap-northeast-1 stage: ${opt:stage, self:custom.defaultStage} environment: LINE_CHANNEL_SECRET: ${self:custom.lineChannelSecret.${self:provider.stage}} LINE_CHANNEL_ACCESS_TOKEN: ${self:custom.lineChannelAccessToken.${self:provider.stage}} custom: defaultStage: dev lineChannelSecret: dev: ${file(./secret.yml):lineChannelSecret.dev} prod: ${file(./secret.yml):lineChannelSecret.prod} lineChannelAccessToken: dev: ${file(./secret.yml):lineChannelAccessToken.dev} prod: ${file(./secret.yml):lineChannelAccessToken.prod} functions: handle: handler: handler.handle memorySize: 128 events: - http: path: handle method: post
handler.rbは下記のような形に変更する。Follow時、Join時に特定のメッセージを返し、メッセージが送られてきた場合にオウム返しする実装。
require 'json' require 'line/bot' def client @client ||= Line::Bot::Client.new do |config| config.channel_secret = ENV["LINE_CHANNEL_SECRET"] config.channel_token = ENV["LINE_CHANNEL_ACCESS_TOKEN"] end end def reply_text(event, text) client.reply_message( event['replyToken'], { type: 'text', text: text } ) end def handle_message(event) case event.type when Line::Bot::Event::MessageType::Text reply_text(event, event.message['text']) else reply_text(event, "I don't know.") end end def handle(event:, context:) body = event['body'] signature = event['headers']['X-Line-Signature'] return { statusCode: 400 } unless client.validate_signature(body, signature) events = client.parse_events_from(body) events.each do |_event| case _event when Line::Bot::Event::Message handle_message(_event) when Line::Bot::Event::Follow reply_text(_event, "Thank you for following") when Line::Bot::Event::Join reply_text(_event, "Thank you for joining") end end { statusCode: 200 } end
色々したい場合には、kitchensinkを参考にすると良いと思う。 Messaging APIリファレンスにコードも載っているのでリファレンスも参考にすると良いと思う。
secret.ymlファイルを生成して、下記のsecretとtokenをLINE developersから取得したものに変更する。
lineChannelSecret: dev: dev_secret prod: prod_secret lineChannelAccessToken: dev: dev_token prod: prod_token
下記コマンドを実行してデプロイする。
sls deploy
WebhookURLにAPI Gatewayから取得したURLを設定して完成。
完成後のものをgithubに載せた。 github.com
掃除は下記コマンド実行で行える
sls remove
lambdaがruby対応したので今更ながらlambdaでrubyを使ってみる。
serverlessを使う。
sls create --template --help
上記コマンドでaws-rubyのtemplateがあるかを確認する。
なければ下記コマンド実行で入るはず
npm i -g serverless
下記コマンドでプロジェクトを作成
sls create --template aws-ruby --path aws-ruby-example
serverless.ymlを下記のように変更
service: aws-ruby-example provider: name: aws runtime: ruby2.5 region: ap-northeast-1 stage: ${opt:stage, self:custom.defaultStage} custom: defaultStage: dev functions: hello: handler: handler.hello memorySize: 128 events: - http: path: hello method: get
下記コマンドを実行してデプロイ
sls deploy
URLの呼び出し/helloにアクセスして、下記が返ってくればとりあえずOK
"Go Serverless v1.0! Your function executed successfully!"