私のプログラミング備忘録

spring, docker, aws etc.

localstack起動時のMounts deniedエラー

以下を参考にdocker-compose upしたところ、このようなエラーが。。
LocalStackをつかってローカルでLambdaを実行してみた | Developers.IO

ERROR: for localstack  Cannot start service localstack: Mounts denied:
The path /var/folders/nv/xxxxxxxxxxxx/T
is not shared from OS X and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> File Sharing.
See https://docs.docker.com/docker-for-mac/osxfs/#namespaces for more info.

解決策がガッツリ載っててよかった
atlassian / localstack / issues / #40 - getting mounts failed on docker-compose up — Bitbucket

これをするだけ

TMPDIR=/private$TMPDIR docker-compose up

angular.ioのaot-compilerを読む

はじめに

index.html

  • AOTとroolupは時間がかかるので、開発時はJIT、本番ではAOTに分ける必要があります。src/index.htmlをaot配下にコピーして、aot/index.htmlに対して変更を加えていきます。
  • バンドルのロードにSystemJSのようなモジュールローダーを必要としないので、aot/index.htmlから不要部分を削除します。
    <script src="node_modules/systemjs/dist/system.src.js"></script>

    <script src="systemjs.config.js"></script>
    <script>
      System.import('main.js').catch(function(err){ console.error(err); });
    </script>
  • 代わりにバンドルファイルをロードするのでbodyタグの閉じタグの後にscriptタグを挿入します。
<script src="dist/build.js"></script>

main.ts

  • AOTとJITは大部分は同じように起動しますが、bootstrapが大きく異なります。JITではAppModuleによるbootstrapではなく、tsconfig-aotに沿ってコンパイルされる時に出力されるNgFactoryファイル群によってbootstrapされます。
  • main.tsと同階層にmain-aot.tsを作成し、NgFactoryをimportします。
import { platformBrowser }    from '@angular/platform-browser';
import { AppModuleNgFactory } from '../aot/src/app/app.module.ngfactory';

platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

typescript configuration

  • AOTではTree Shaking(のRollup)でimport/exportをトレースするのでes2015(es6)でトランスパイルされる必要があるのに対して、JITではcommonJSでトランスパイルされるのが好ましいので、configファイルは明示的に分けるべきです。
  • tsconfig-aot.jsonとして、以下のように準備します。
{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [ "es2015", "dom" ],
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "typeRoots": [
      "./node_modules/@types/"
    ]
  },

  "files": [
    "src/app/app.module.ts",
    "src/main-aot.ts"
  ],

  "angularCompilerOptions": {
   "genDir": "aot",
   "skipMetadataEmit" : true
 }
}

tree shaking

  • tree shakingの1つとしてRollUpが実行されます。
  • configファイルとしてrollup-config.jsを以下のように設定し、ルート配下に配置します。
// import rollup      from 'rollup'
import nodeResolve from 'rollup-plugin-node-resolve'
import commonjs    from 'rollup-plugin-commonjs';
import uglify      from 'rollup-plugin-uglify'

export default {
  entry: 'src/main-aot.js',
  dest: 'aot/dist/build.js', // output a single application bundle
  sourceMap: true,
  sourceMapFile: 'aot/dist/build.js.map',
  format: 'iife',
  onwarn: function(warning) {
    // Skip certain warnings

    // should intercept ... but doesn't in some rollup versions
    if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }

    // console.warn everything else
    console.warn( warning.message );
  },
  plugins: [
      nodeResolve({jsnext: true, module: true}),
      commonjs({
        include: 'node_modules/rxjs/**',
      }),
      uglify()
  ]
}

Running the application

パッケージのインストー

  • platform-serverがなければ入れる。
npm install @angular/compiler-cli @angular/platform-server --save
npm install rollup rollup-plugin-node-resolve rollup-plugin-commonjs rollup-plugin-uglify --save-dev

copy-dist-files

  • AOT配布ファイルをaot/配下にコピーするスクリプトを作成します。
var fs = require('fs');
var resources = [
  'node_modules/core-js/client/shim.min.js',
  'node_modules/zone.js/dist/zone.min.js',
  'src/styles.css'
];
resources.map(function(f) {
  var path = f.split('/');
  var t = 'aot/' + path[path.length-1];
  fs.createReadStream(f).pipe(fs.createWriteStream(t));
});
  • pakcage.jsonのcopy-dist-filesを実行します。
node copy-dist-files

起動

  • AOTコンパイル、Rollup、lite-serverによる起動を行います。
npm run build:aot && npm run serve:aot

上記のコマンド内を1つずつ見ていきます。

AOTコンパイル
  • typescriptコンパイラ(tsc)の代わりに、@angular/compiler-cliで提供されるngcコンパイラで実行します
    • -pオプションは設定ファイルの指定
    • 設定ファイルのgendirで指定したフォルダにhoge.ngfactory.tsができる
      • JITではインメモリに展開されるけど、AOTでは物理ファイルとして明示的に作成される
node_modules/.bin/ngc -p tsconfig-aot.json
Rollup実行
node_modules/.bin/rollup -c rollup-config.js
lite-server
  • bs-config.aot.jsonにある通り8080ポートで起動されます。
lite-server -c bs-config.aot.json

tree shaking補足

  • tree shakingはAOTコンパイラによってセットされたステージ上のファイルを全検索して不要なコードを除きます。これによってアプリケーションサイズが小さくなります。

Rollup

  • tree shakingのプラグイン
  • import/exportのトレースによるアプリケーションの静的解析ユーティリティ
  • 再記になるがtsconfig-aot.jsonでmoduleにes2015を指定したのは、requireではなくimport/exportが使われている必要があるから
  • Rollupユーティリティをインストー
npm install rollup rollup-plugin-node-resolve rollup-plugin-commonjs rollup-plugin-uglify --save-dev
  • rollup-config.js(rollupの設定ファイル)をルート配下に作成します。内容はとりあえずサンプル通り何ですが、1行目のコードは不要なのでコメントアウトする。
// import rollup      from 'rollup'

これをしないと、以下の警告が出る

'default' is imported from external module 'rollup' but never used

RxJS
  • tree shakingのプラグイン
  • Rollupはes2015でコーディングされている前提で動作するけど、公開されている依存ライブラリの多くはcommonjsで実装されている。そういったライブラリの変換を行うためのプラグイン
Minification
  • tree shakingのプラグイン
  • gzipに圧縮することで、アプリケーションサイズが小さくできる

awslabsのcognito-apigw-angular-authを試す

はじめに

  • 今回、試してみるのはこち

https://github.com/awslabs/aws-cognito-apigw-angular-auth

手順

  • readmeに沿ってやっていくよ

1 バケットへのアップロード

  • sam/lambda.zip をバケットにアップロードして、sam/sam.yaml のバケット部分を変更
  CognitoDemoFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs4.3
      CodeUri: s3://<S3 BUCKET>/lambda.zip

2 packageとdeploy

  • packageコマンドを実行するとS3にんアップロードされるのかと思いきや、アップロードされないけど、outputファイルはできていたので、とりあえずOKか!?
  • packageコマンドを実行すると、次に実行するコマンドが標準出力されるがcapabilityが抜けてるので注意。readmeのが正解

3 google api使う準備

  • readme記載のリンク先にあるawsドキュメント通りにやっていって、oauthクライアントの追加とサービスアカウントキーの発行を行う
  • google+ apiを使用するにはアプリレビューが必要らしい。ただしテスト段階や個人利用においてはRisky Access Permissions By Unreviewed Appsグループに参加すればいいらしい。

https://developers.google.com/identity/protocols/googlescopes

  • こんな感じのエラー画面が出ると思います。

400. エラーが発生しました。

エラー: invalid_scope

このアプリは次のスコープへのアクセスの確認が完了していません: {invalid = https://www.googleapis.com/auth/contacts.readonly}。サポートについてデベロッパーにお問い合わせください。デベロッパーの方は、このプロジェクトで上記のスコープが必要な場合は、プロジェクトへのアクセス権限があるアカウントにログインして、もう一度お試しください。必要でない場合は、サポートについてデベロッパーにお問い合わせください。
Request Details

4 RESOURCE IDENTIFIERSの編集

  • /src/app/aws.service.ts のRESOURCE IDENTIFIERS部分を編集
  • googleIdは手順3で作成したoauth client id
  • それ以外はawsコンソールのCFnの出力タブに記載がある
  • regionも忘れずに

5,6,7 AUTENTICATION PROVIDERS編集

  • Federated Identitiesコンソールで作業
  • google auth client id入力

8 User Poolへ登録

  • 手順にあるコマンドを適宜変更して、awscliから登録
  • 2人ぶん登録しておく

9 cip-groupへの追加

  • User Poolコンソールにて、追加したユーザーのうち1人を選択して詳細画面を開く
  • 左上にadd to groupボタンがあるので、cip-groupへ追加する

10 angularのscaffold作成とsdk追加

  • angular-cliは1.0.0(masterのバージョンに合わせない)と動かないかも。

私の場合は1.1.2(2017年6月時点の最新バージョン)で動かしたところ、以下のエラーで動きませんでした。

Resource blocked due to MIME type mismatch (X-Content-Type-Options: nosniff)

もしくは

MIME タイプの不一致により"/path/to/hoge.js"からのリソースがブロックされました (X-Content-Type-Options: nosniff)。

  • angular-cliはグローバルではなく、1.0.0をローカルにインストール。
npm install @angular/cli@1.0.0
  • その他は記載されているコマンド実行。restApiIdはCFnの出力タブより取得

11 masterのソースとマージ

  • /srcフォルダをコピー
  • pakcage.jsonを差分だけコピー

12-14 あとは記載通り