あいつの日誌β

働きながら旅しています。

完全栄養食パスタ BASE PASTA を調理してみた

2017-03-04 追記あり

懸念点として茹でた栄養素について記述したところコメントを頂いたので追記しました。

f:id:okamuuu:20170301154328j:plain

あらすじ

実は以前から完全栄養食に関心があったので早速 Amazon.jp で注文してみましたので食感をレポートしました。

BASE PASTAパスタとは

厚生労働省が定めた「日本人の食事摂取基準(2015年版)」に基いて、1食に必要な栄養素をすべて賄えるように作られたパスタです。

完全栄養食とは

人間が生きていくために必要な栄養素がすべて入った食品のことです。ソイレントと呼ばれるミルクのような流動食などがそうであると言われています。私は完全栄養食の概念は Geek House のブログで知りました。完全栄養食を自作するなんてとてもギークですね。

それはさておき、栄養素は一要素でも不足すると不健康になりやすいという「生命の鎖」理論というものがあるので以前から食生活に取り入れたいと思っていました。

生命の鎖理論とは

世界的に有名な栄養学者であるロジャー・ウィリアムス博士によると、生命を維持するには必須となる栄養素が存在し、それらのうち1つが水準以下となれば不健康や病気となる、という 46種類だと言われています。

内海 聡氏の facebook から引用:

ロジャー・ウィリアム博士によると、生命の鎖を構成する栄養素は九種類の必須アミノ酸、一六種類のミネラル、二〇種類のビタミンなどだが、これらのどれにも絶対必要最低水準というものがあり、どの一つがその水準以下になっても不健康となったり、病気となると提唱する。

簡単にいうとまんべんなく栄養とりましょう。という理論です。

完全栄養食を食べたら後は何も要らないのか?

そもそも人間が生きていくために必要な栄養素が入っていてもそれを100%体内で吸収できるかどうかは別問題だと思います。 なのですが、生命の鎖理論のように、各栄養素は単体では働かない、ということを鑑みると、栄養のとりこぼしを防ぐために完全栄養食を選ぶという選択肢が増えたことはとても良いことなんじゃないかと思います。

調理してみた

お皿に取り出したところです。生麺です。美味しそうですね。実際に麺は割と美味しかったです。

f:id:okamuuu:20170301154902j:plain

パスタソースはこちらを使いました。生麺とは相性よくないのかな?まあインスタントですからねえ。

f:id:okamuuu:20170301154514j:plain

はい、できました。

f:id:okamuuu:20170301155243j:plain

懸念点

表記されている栄養価は茹でる前であって茹でた後はどうなるのかわからない。

f:id:okamuuu:20170301154242j:plain

追記: 2017-03-04

茹でた際の栄養素に関しては以下のコメントを頂きました。ありがとうございます。

まとめ

割と美味しいですし、栄養価が高いので悪い印象はなかったです。 茹で汁に栄養素が流れていると思うのでなにか有効活用できればいい感じになるかも。できるのかな?

日頃から常用するとなるとちょっとお値段が高いのかもしれません。マルチビタミンマルチミネラルサプリメントとるほうがコスパはいいと思います。

逆に言い換えるとサプリメントで栄養をとるより食事でとりたい人にとってはとてもいいものになるんじゃないかなあと思います。おしまい。

Amazon アソシエイツ

参考URL

ES2015 でとまどいがちな記法 Object initializer と Spread Operator

あらすじ

ES6 の記法を全て覚えてから ES6 を書くよりも、書きながら勉強したほうが効率が良かったりします。 なんですが写経している時に分からない記法が出てきた場合検索しづらくて困ると思います。

というわけで私がどうやって Google に質問すればいいのか分からなかった記法を2つ紹介します。

Object initializer: オブジェクト初期化子

以下のような ES5 の記法が

const a = 1
const b = 2 
const c = 3
const object = {a: a, b: b, c: c}

ES6 では以下のように省略できます。

const a = 1
const b = 2 
const c = 3
const object = {a, b, c}

また、以下のような ES5 の記法が

function x(obj) {
  const a = obj.a
  const b = obj.b
  console.log(a, b)
}

const a = 1 
const b = 2 
x({a: a, b: b})

ES6 では以下のように省略できます。

function x({a, b}) {
  console.log(a, b)
}

const a = 1 
const b = 2 
x({a, b}) 

この書き方は最初慣れないと気持ち悪いですが使っているうちにだんだん気持ちよくなります。

Spread Operator: スプレッド演算子

...array とか ...object を初めて見た人は多分意味が分からなくて困ると思います。

array を spread する

ES5 では以下のように記述していたものが

function f(array) {
  console.log([array[0], array[1], array[2], 4, 5])
}

f([1, 2, 3])

ES6 では以下のように省略できます。

function f(array) {
  console.log([...array, 4, 5])
}

f([1, 2, 3])

object を spread する

ES5 では以下のように記述していたものが

function f(obj) {
  const a = obj.a
  const b = obj.b
  const c = obj.c
  console.log({a: a, b: b, c: c, d: 4, e: 5}) 
}

const a = 1 
const b = 2 
const c = 3 
f({a: a, b: b, c: c}) 

ES6 では以下のように省略できます。

function f(obj) {
  console.log({...obj, d: 4, e: 5}) 
}

const a = 1 
const b = 2 
const c = 3 
f({a, b, c})

npm publish を念頭において React Components 用のプロジェクトを作成する

あらすじ

先日 react-paginators という React components な module を publish しました。

github.com

その時に色々調べた事があるので備忘録として残します。

作成手順

create-react-appstorybook を使ってプロジェクトの雛形を作成します。create-react-app を使うと webpack の事を考えなくて良いのでとても楽でよいです。

create-react-app react-xxxxx && cd $_
getstorybook

必要なディレクトリとファイルを作成します

mkdir test
touch .envrc .babelrc .npmignore .travis.yml CHANGELOG.md test/xxxxx.test.js 
npm install --saave react react-dom
npm install --save-dev babel babel-cli babel-preset-es2015 babel-preset-react babel-preset-stage-0
npm install --save-dev assert eslint eslint-plugin-react rimraf
npm install --save-dev in-publish safe-publish-latest

create CHANGELOG.md

# Change Log

## v0.1.0
 - Initial commit

そういえば $_ って何ですか?と聞かれる事があったのですがこれは前回使用したコマンドの最後の引数が格納される変数です。 上記のコマンドだと create-react-app react-xxxxxreact-xxxxx となります。

npm run test の環境を整える

雛形ができたら npm test の環境を整えます

create test/xxxxx.test.js

import assert from 'assert'

describe('XXX', function() {
  it('should ...', () => {
    assert.ok(true)
  })  
})

動作確認します。雛形として生成された src/App.test.js と test/xxxxx.test.js が実行されるのを確認します。 ちなみに環境変数 CI=true を忘れると launch mode で起動します

CI=true npm test

> react-xxxxx@0.1.0 test /Users/okamuuu/react-xxxxx
> react-scripts test --env=jsdom

 PASS  src/App.test.js
 PASS  test/xxxxx.test.js

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.167s
Ran all test suites.

src/App.test.js は不要となった時点で適宜 remove してください

npm run version の環境を整える

check-changelog と check-only-changelog-changed

airbnb が公開している react-dates の真似をします。

https://github.com/airbnb/react-dates

github.com

彼らは version コマンドを実行する時は CHANGELOG.md 以外の差分が無い状態でしか実行できないようにしています。 npm-scripts に check-changelogcheck-only-changelog-changed を追加します。

edit package.json:

--- a/package.json
+++ b/package.json
     "start": "react-scripts start",
     "build": "react-scripts build",
     "test": "react-scripts test --env=jsdom",
-    "eject": "react-scripts eject"
+    "eject": "react-scripts eject",
+    "check-changelog": "expr $(git status --porcelain 2>/dev/null| grep \"^\\s*M.*CHANGELOG.md\" | wc -l) >/dev/null || (echo 'Please edit CHANGELOG.md' && exit 1)",
+    "check-only-changelog-changed": "(expr $(git status --porcelain 2>/dev/null| grep -v \"CHANGELOG.md\" | wc -l) >/dev/null && echo 'Only CHANGELOG.md may have uncommitted changes' && exit 1) || exit 0"
   }
 }

以下のような使い方を想定しいています。

CI=true npm run test && npm run check-changelog && npm run check-only-changelog-changed

上記のコマンドは以下の状態でないとエラーが発生するので version up の際に一貫性が生まれます。

git status
  modified:   CHANGELOG.md

postversion, version, preversion を準備

npm version をそのまま使うと Git working directory not clean. と怒られてしまうので --no-git-tag-version オプションをつけて実行します。 package.jsonnpm run version:patch, npm run version:minor, npm run version:major を用意します。

preversion に先ほど準備した test の実行と CHNAGELOG.md のチェックを行います。 postversion で package.json(verson が変更されている) と CHANGELOG.md をcommit します。コミットも自動的に行います。git tag でタグを切り、その tag も push します。

edit package.json

--- a/package.json
+++ b/package.json
     "test": "react-scripts test --env=jsdom",
     "eject": "react-scripts eject",
     "check-changelog": "expr $(git status --porcelain 2>/dev/null| grep \"^\\s*M.*CHANGELOG.md\" | wc -l) >/dev/null || (echo 'Please edit CHANGELOG.md' && exit 1)",
-    "check-only-changelog-changed": "(expr $(git status --porcelain 2>/dev/null| grep -v \"CHANGELOG.md\" | wc -l) >/dev/null && echo 'Only CHANGELOG.md may have uncommitted changes' && exit 1) || exit 0"
+    "check-only-changelog-changed": "(expr $(git status --porcelain 2>/dev/null| grep -v \"CHANGELOG.md\" | wc -l) >/dev/null && echo 'Only CHANGELOG.md may have uncommitted changes' && exit 1) || exit 0",
+    "tag": "git tag v$npm_package_version",
+    "version:patch": "npm --no-git-tag-version version patch",
+    "version:minor": "npm --no-git-tag-version version minor",
+    "version:major": "npm --no-git-tag-version version major",
+    "preversion": "CI=true npm run test && npm run check-changelog && npm run check-only-changelog-changed",
+    "postversion": "git commit package.json CHANGELOG.md -m \"Version $npm_package_version\" && npm run tag && git push && git push --tags"
   }
 }

後ほど postversion の最後に npm publish を追加しますす

gh-pages へのデプロイを準備する

react の component を公開するので実際に見た目がどのように表示されるのかを皆さんに伝える必要があります。 gh-pages に static page をデプロイする方法は色々ありますが、@kadira/storybook-deployer を install するだけで実現できます。

npm install --save-dev @kadira/storybook-deployer

edit package.json

     "version:major": "npm --no-git-tag-version version major",
     "preversion": "CI=true npm run test && npm run check-changelog && npm run check-only-changelog-changed",
-     "postversion": "git commit package.json CHANGELOG.md -m \"Version $npm_package_version\" && npm run tag"
+    "postversion": "git commit package.json CHANGELOG.md -m \"Version $npm_package_version\" && npm run tag",
+    "deploy-storybook": "storybook-to-ghpages"
  }
}

npm run deploy-storybook を実行して gh-pages を確認します。

npm run build

src/ 以下に ES6 で書かれた Javascript を lib/ 以下に ES5 に変換したものを配置します。 npm publish しないのであれば不要な作業ですが、現時点では node_modules/ 配下に install するモジュールは es5 が前提だと思いますのでその習慣に従います。

babel コマンドを実行します。もしかしたら react-scripts が bundle しない 6to5 なコマンドを用意しているのかもしれないのですがよくわからないので自前で babelrc を用意します。

create .babelrc

{
  "presets": ["react", "es2015", "stage-0"]
}

以下を実行し、lib 以下に es5 のコードが生成されることを確認します。

$(npm bin)/babel -d lib/ src/

lib 配下は git で管理する必要が無いので .gitignore に追加します

echo "/lib/" >> .gitignore

また lib 配下は npm publish で使用されるので build 直前で clearn にするようにしておきます。 そして main, files も同様に npm publish される前提の修正を行います。

edit package.json

--- a/package.json
+++ b/package.json
-  "private": true,
+  "license": "MIT",
+  "main": "lib/index.js",
+  "files": "lib",
+  "author": "okamuuu<okamuuu@gmail.com>",
   "devDependencies": {
     "@kadira/storybook": "^2.21.0",
     "@kadira/storybook-deployer": "^1.2.0",
   },
   ...
   "scripts": {
     "start": "react-scripts start",
-    "build": "react-scripts build",
+    "build": "rimraf lib && babel -d lib/ src/",
     "test": "react-scripts test --env=jsdom",
     "eject": "react-scripts eject",
     "check-changelog": "expr $(git status --porcelain 2>/dev/null| grep \"^\\s*M.*CHANGELOG.md\" | wc -l) >/dev/null || (echo 'Please edit CHANGELOG.md' && exit 1)",

npm run publish

最後に publish の設定を行います。

postversion のタイミングで npm publish が実行されるようにします。 npm prepublish は、npm install 時に実行してしまいます。npm run buildnpm install の時に実行しないようにします。 それから npm publish が成功した場合は gh-pages の更新を行うようにします

-    "postversion": "git commit package.json CHANGELOG.md -m \"Version $npm_package_version\" && npm run tag",
+    "postversion": "git commit package.json CHANGELOG.md -m \"Version $npm_package_version\" && npm run tag && git push && git push --tags && npm publish --registry=https://registry.npmjs.org/",
...
+    "build-storybook": "build-storybook -s public",
+    "prepublish": "in-publish && safe-publish-latest && npm run build || not-in-publish",
+    "postpublish": "npm run deploy-storybook"
   }

package されるファイルを確認する

npm publish --dryrun のようなコマンドを実行したいのですが現時点では存在しないようです:(

代わりに npm pack を利用します。 http://qiita.com/inuscript/items/5b3c1466a6ddb9ba6231

実際に package されるファイルを確認するコマンドは下記のとおりです。 npm pack -s はこの記事の通りに設定していると react-xxxxx-0.1.X.tgz という標準出力を一行だけ吐き出します。 npm buildprebuild, postbuild の設定にもよると思うのでもし同じ状況にならなかったら各自修正をお願いします。

tar -tf $(npm pack -s) && $(npm bin)/rimraf $_

一連の作業をコマンド化します。npm run build で lib 配下を最新版にし、$(npm pack -s) で packing とファイル名を取得し、それに含まれるファイル一覧を取得します。ついでに不要となった tgz ファイルも削除しましょう。 再び $_ が登場しますが、これは最後に実行したコマンドが tar -tf ARG なので tgz ファイルを指しています。

+    "build:test": "npm run build >/dev/null && tar -tf $(npm pack -s) && rimraf $_",

このコマンドで視認しながら .npmignore に不要なファイルを追加していきます。

.babelrc
.envrc
.storybook
.travis.yml
stories
src
test
public

期待しているファイルが publish されることを確認します。

% npm run build:test

> react-xxxxx@0.1.3 build:test /Users/okamuuu/react-xxxxx
> tar -tf $(npm pack -s) && rimraf $_

package/package.json
package/.npmignore
package/README.md
package/lib/App.js
package/lib/App.test.js
package/lib/index.js
package/CHANGELOG.md

.travis.yml

手元の環境では動くのだけどもデプロイすると動かなかったりしますので CI 環境を用意します。 ここでは travis.yml を使っていますが CircleCI でも Wercker でも OK だと思います。

注意点として create-react-app で作成したプロジェクトの test は環境変数に CI=true をセットしていない場合は launch します。

create .travis.yml

language: node_js
node_js:
  - "6"
  - "4"
env:
  CI: true
sudo: false

npm publish

最後に npm publish を実行します。無事成功したら最後に package.json を以下の通りに修正します。

- "postversion": "git commit package.json CHANGELOG.md -m \"Version $npm_package_version\" && npm run tag && gitpush && git push --tags",
+ "postversion": "git commit package.json CHANGELOG.md -m \"Version $npm_package_version\" && npm run tag && gitpush && git push --tags && npm publish",

おしまい

react-paginators という npm module を publish しました

github.com

どんなの?

こんなの

f:id:okamuuu:20170302173403g:plain

作った経緯

最初は react-paginate を使う予定でした

https://github.com/AdeleD/react-paginate

なんですが最初のページを指定する機能がどうやら動作しない模様

https://github.com/AdeleD/react-paginate/issues/124

initialPage, forcePage ともにうまく動かなかったのとソースコードを読んだ感じだとロジックと View が混在していて直しづらそうだったので自前で実装しようと思いました。

なんとなく車輪の再発明をしているような気もしなくもないですが良かったら試して見てください。 https://okamuuu.github.io/react-paginators/

ところで

4月1日から働きたいのですがサーバーサイドもしくはフロントエンドなフリーランスのエンジニアを雇ってくれる会社をご存知の方教えて下さい。

getstorybook で Unsupported Project type. (code: UNDETECTED)

以下のコマンドを実行すると

mkdir example-project && cd $_
npm init -y
getstorybook

以下のようなエラーが表示される

 getstorybook - the simplest way to add a storybook to your project. 

 • Detecting project type. ✓
    Unsupported Project type. (code: UNDETECTED)
    Visit http://getstorybook.io for more information.

原因

getstorybook コマンドは package.json の中身を見て判断しています。

https://github.com/storybooks/getstorybook/blob/master/lib/detect.js

どうやら最低限 react.js が install されていれば良さそうです ということで先に react を install します

npm install --save react react-dom

この状態で retry します。

getstorybook

npm run storybook を実行できるようになります。おしまい

React Storybook で Material-UI を試す

create-react-app material-ui-storybook && cd $_
getstorybook
npm install --save react-tap-event-plugin material-ui
npm install --save-dev  storybook-addon-material-ui

edit `src/stories/index.js

 import React from 'react';
-import { storiesOf, action, linkTo } from '@kadira/storybook';
+import { storiesOf, action, linkTo, addDecorator } from '@kadira/storybook';
 import Button from './Button';
 import Welcome from './Welcome';
+import {muiTheme} from 'storybook-addon-material-ui';
+import RaisedButton from 'material-ui/RaisedButton';
 
 storiesOf('Welcome', module)
   .add('to Storybook', () => (
@@ -15,3 +17,9 @@ storiesOf('Button', module)
   .add('with some emoji', () => (
     <Button onClick={action('clicked')}>😀 😎 👍 💯</Button>
   ));
+
+storiesOf('Material-UI', module)
+  .addDecorator(muiTheme())
+  .add('RaiseButton', () => (
+    <RaisedButton label="Default" />
+  ));

open http://localhost:9009

Google App Engine の let's encrypt を更新する手順の備忘録

3ヶ月前に okamuuu.com を作った時についでに https に対応させたんですが、忘れた頃に更新しないといけないので備忘録

手元の MacOSX 上で最初にデプロイできるか確認

とりあえず自分のアプリがデプロイできるかどうかを確認します。 この3ヶ月でマシンを新調していたので gcloud コマンドがはいってなかった...

which gcloud
gcloud not found

ここからダウンロードする。 https://cloud.google.com/sdk/docs/quickstart-mac-os-x

そのあと ./install.sh を実行して SHELL を再起動します。

事前にデプロイの手順を確認する理由は証明書を作成する手順を実行している最中に指定されたファイルを GAE にアップする必要があるためです。

Google clouls shell で GAE 上で証明書を作成します。

let's encrypt を準備します。すでに letsencrypt ディレクトリができていたら前回すでに実行しているので git pull しておきましょう。

git clone https://github.com/letsencrypt/letsencrypt && cd letsencrypt

証明書を作成します。モジュールが入っていない場合は結構時間がかかります。

cd ~/letsencrypt
sudo ./letsencrypt-auto -a manual certonly

以下ダイアログ。

  • Emailアドレスを入力
  • 規約に同意
  • Electronic Frontier Foundation にアドレスを Share するかに答える
  • 該当するドメインを指定
  • IP を記録する事に同意
Enter email address (used for urgent renewal and security notices)  If you
really want to skip this, you can run the client with
--register-unsafely-without-email but make sure you then backup your account key
from /etc/letsencrypt/accounts   (Enter 'c' to cancel):okamuuu@gmail.com
-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree
in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A
-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: Y
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel):okamuuu.com
Are you OK with your IP being logged?
-------------------------------------------------------------------------------
(Y)es/(N)o: Y

そうすると下記ようのようなチャレンジコードが画面に表示されます。

Make sure your web server displays the following content at
http://okamuuu.com/.well-known/acme-challenge/123456789xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx before continuing:
123456789xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

これは http://okamuuu.com/.well-known/acme-challenge/123456789xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx に Request したら 123456789xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy を返すようにしてね。という事を言っています。

この画面を表示させたまま(Enter をまだ押さない)状態で GAE に Static file をアップします。その後 Enter を押します。

その後に Cloud Shell の次のコマンドで公開鍵証明書の中身を取得しておきます。

sudo less /etc/letsencrypt/live/okamuuu.com/fullchain.pem

次に秘密鍵

sudo openssl rsa -inform pem -in /etc/letsencrypt/live/okamuuu.com/privkey.pem -outform pem | less

上記の2つの鍵を Google Console 上で SSL 証明書として登録すれば作業完了

参考

http://blog1.erp2py.com/2016/06/gaessllets-encrypt.html