Adventar 2019 の技術構成概要

Adventar を支える技術 Advent Calendar 2019 の1日目です。 Adventar はサービスを開始した2012年以来、Rails を利用してサービスを提供してきました。今年はそのシステムを一から設計し直し、以下のような技術要素を使って実装しました。 Nuxt.js による S…

Nginx で grpc-web の proxy

Envoy より Nginx のほうが慣れているので Nginx を使いたい。一応公式でも Docker でビルドできるようになってるけど、無駄にサイズがでかい(2GB超え)しコンパイルオプションがいじりたいので alpine でビルドできるようにしてみた。 https://github.com/…

navigator.sendBeacon で Content-Type を指定したい

計測用のリクエストみたいな小さいリクエストを投げるためのnavigator.sendBeaconっていうAPIがあって、fetchやXHRと違ってunload時でもリクエストが送信されるのが保証されるのが売りらしい。メジャーなブラウザには実装されつつある。 Navigator.sendBeaco…

npm scripts のコマンドライン引数は sh で展開される

package.jsonに "scripts": { "lint": "eslint src/**/*.{js,jsx}" } と書いた場合、npm run lintやyarn run lintは、このコマンドをシェルを通して実行する。このときデフォルトではshが使われる。例えばmacOSだとshはbashなので、bashがsrc/**/*.{js,jsx}…

Railsのネストしたネームスペースのautoload

こんな感じのコードがあったとして # app/models/user.rb class User end # app/models/admin/user.rb module Admin class User end end # app/controllers/admin/first_controller.rb class Admin::FirstController def index p User end end # app/control…

SmartHRの体験入社にいってきた

tech.smarthr.jp 人事制度として興味あるし、他の会社で働いてみることにも興味があったので発表された直後に反射的に応募したところ、きていいよ(意訳)と返事をもらったのでほいほいと行ってきた。 一日のコースで、こんな感じのことをやってきた。 午前…

developmentでridgepole applyしたときにtest DBもつくる

Rails標準のMigrationを使う場合はdevelopmentのDBをアップデートしたらschema.rbが更新されてspec/rails_helper.rbとかに書いてある ActiveRecord::Migration.maintain_test_schema! っていうのでrspec実行前にtest DBをmigrationしてくれる。 ridgepoleを…

ruby 2.5で変更されたtoplevel constant lookupの挙動

こういうコードがあったとして class Foo; end class Bar; end p Foo::Bar #=> Bar ruby 2.4まではwarning: toplevel constant Bar referenced by Foo::Bar を出しつつFoo::BarはBarを返す。 これはrubyの定数探索が継承関係を遡って探すという仕様と、トッ…

ngrepでリクエストだけ出力する

ngrepで3000番ポートに対する通信を見る場合こんな感じで見れるけど $ sudo ngrep -W byline -q -d any port 3000 レスポンスはいらないのでリクエストだけみたい、という場合はdst portにすればよい。 $ sudo ngrep -W byline -q -d any '' dst port 3000 '…

RailsのAPI onlyでOmniAuthがエラる

RailsのAPI onlyのアプリケーションだとセッションが無効化されているのでOmniAuthを使おうとするとOmniAuth::NoSessionErrorで落ちる。 READMEに書いてあった。 https://github.com/omniauth/omniauth/blob/650943c16de33c7cdf16708b74766e95ad369610/READM…

頑張らないeslint

自分で頑張って真心込めて設定書いてたけどメンテ不可能なので頑張らないことにした。 フォーマット系はprettierに委ねる printWidthだけ120にして後は委ねる 基本設定はrecommendedに委ねる eslint:recommendedは控えめな感じでよい 本当にほしいやつだけ追…

TypeScriptのLint

JavaScriptもTypeScriptも混じっているプロジェクトで、Lintのルールをなるべく共通化して運用したいというモチベーションがある。 JavaScriptのLinterはESLintを使いたい。TypeScriptのLinterはTSLintがデファクトだが、TSLintはESLintと比べて実装されてい…

BdashというBIツールをリリースしました

BdashというアプリケーションをElectronで作りました。 bdash-app/bdash: A simple business intelligence application. 以下からダウンロードしてインストールできます(現状まだMac版だけ)。 https://github.com/bdash-app/bdash/releases ざっくりとこん…

element.querySelectorで直下の要素を指定する

例えばel(DOM Element)の直下の.fooを取りたいときに、以下のようにしたい。 el.querySelectorAll('> .foo'); これだとエラーになるんだけど:scopeを使えばいける。 el.querySelectorAll(':scope > .foo'); Chrome、Firefoxでは動いた。

macOSでアプリケーションが署名されてるかどうか確認する

mac

codesignコマンドで確認できる。 $ codesign -vd /Applications/Hyper.app Executable=/Applications/Hyper.app/Contents/MacOS/Hyper Identifier=co.zeit.hyper Format=app bundle with Mach-O thin (x86_64) CodeDirectory v=20200 size=269 flags=0x0(non…

ISUCON6 4位でした

会社の同僚の@wata_devと@osadake212とISUCON6本戦に出場して4位でした。チームメンバー全員普段アプリケーション書いてるエンジニアでインフラ寄りのメンバーがいなくて複数台構成の本戦はきついだろうなと思ってたので、4位という結果はかなり健闘したほう…

sqlite3でカラム定義の変更

sqlite3だとalter table change columnみたいのがないらしいのでnot nullとかdefault valueを変更するのどうすればいいんだろうと思ってrailsがどうしてるか見てみた。 class CreateTodos < ActiveRecord::Migration[5.0] def change create_table :todos do…

ISUCON6 予選の記録

ISUCON6にしましまスペシャルというチーム名で会社の同僚と参加して最終スコア147,028で予選通過できました。言語はRubyです。コードはここに公開してます。 https://github.com/hokaccha/isucon2016_qualifying 以下やったこととかのメモ。 10時-11時 下準…

Railsのscopeとclass method

http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Named/ClassMethods.html#method-i-scope ARのscopeはclass methodとだいたい同じ scopeはnilやfalseを返した時にallを返すのでメソッドチェインをブロックしない 必ずActiveRecord::Relationを返…

Babel 6.xでErrorとかArrayをextendsしたときの挙動がおかしい

class FooError extends Error {} console.log(new FooError() instanceof FooError); //=> false console.log(new FooError() instanceof Error); //=> true class FooArray extends Array {} console.log(new FooArray() instanceof FooArray); //=> false…

GraphQLでNonNullなList

フィールド自身がNonNull 要素がNonNull その両方 があって let QueryType = new GraphQLObjectType({ name: 'Query', fields: { list1: { type: new GraphQLNonNull(new GraphQLList(GraphQLString)), resolve: () => arr1, }, list2: { type: new GraphQLL…

module_function

moduleに普通にメソッドを定義するとインスタンスメソッドとして定義される。 module Foo def foo end puts instance_methods.include?(:foo) #=> true puts private_instance_methods.include?(:foo) #=> false puts singleton_methods.include?(:foo) #=> …

FactoryGirlでActiveRecord以外のデータをつくる

例えばHashie::Mashを返したい場合はこんな感じ。 FactoryGirl.define do factory :post, class: Hashie::Mash do title "foo" body "bar" end end FactoryGirl.build(:post).class #=> Hashie::Mash FactoryGirl.build(:post) #=> {"title"=>"foo", "body"=…

ES6でN個の配列

Array.prototype.keysはIteratorを返すのでArray.fromに食わせる Array.from(Array(5).keys()); //=> [0, 1, 2, 3, 4] もしくは Array.from({ length: 5 }).map((v, k) => k); //=> [0, 1, 2, 3, 4] Array.fromの第二引数はmap的な役割があるので Array.from…

ShadowDOMの外から内部の要素を取得する

shadowRootでshadowRootが取れるのでそこから辿れる。 var proto = Object.create(HTMLElement.prototype); proto.createdCallback = function() { var shadowRoot = this.createShadowRoot(); shadowRoot.innerHTML = '<span class="foo">text</span>'; }; document.registerElement(…

Shadow-Piercing descendant combinator is deprecated

最近Web Componentsのアップデート全然見てなかったけどCSSで外からShadow DOMをスタイリングするための/deep/(>>>)、::shadowがdeprecatedになってた。 Shadow-Piercing descendant combinator, '/deep/' (aka '>>>') - Chrome Platform Status

gitでトラッキングされてないファイルも含めてstashする

git

なんとなく $ git stash --allってやったら、ignoreされてるファイルも全部消えてファッってなった。 $ git stash -u # or $ git stash --include-untrackedが正しいっぽい。以下helpより。 If the --include-untracked option is used, all untracked files ar…

Polymer/platform.jsでdocument.currentScriptが動かない

Web ComponetsのPolyfillのPolymer/platform.jsでHTML import使ったときに、呼び出される側のHTMLのJSのdocumentを取得したいときに、 var doc = document.currentScript.ownerDocument; ってやればとれるらしいんだけど、これがうまくPolyfillできなくて動…

最近のAndroid Chromeのリモートデバッグ

以前はAndroidのChrome側にWebデバッグを有効にするみたいなのがあって、PC側ではADB立ち上げたりする必要があったんだけど、最近はもっと簡単になってるっぽくて、1. AndroidのUSBデバッグを有効にする 2. USBでつなぐ 3. AndroidのChromeで適当なページ開…

Backbone.jsでPATCHをPUTに書き換える

Backbone.jsでsaveするときに patch: true にするとPATCHメソッドになってsaveに渡した引数だけをbodyに含める(patch :true しないとmodelの全attributesをbodyにしてPUTする)んだけど、API側がPATCHメソッドに対応してなかったりPATCHメソッドを通さないp…