BETA

短歌投稿サイト「ちるなり」の技術メモ

投稿日:2019-06-06
最終更新:2019-10-10

この記事について

ちるなり|短歌の投稿サイトの技術的な話のメモです。

functionの配列を受け取ってasync.parallelする

複雑な処理になると自分でasync/awaitやPromiseをごにょごにょして書くのがつらいことがあるので、よくcaolan/asyncを使います。このなかのasync/parallelはfunctionの配列やオブジェクトを第一引数に、すべてのタスクのあとに実行するコールバックを第二引数に受け取ります。このとき、第一引数に渡されるfunctionはその第一引数としてコールバックをトリガーするfunctionを受け取るのでなければなりません。

で、そのようなfunctionの配列を任意のオブジェクトをわたして生成してasync.parallelしたかったときの実装のサンプルです。lodash/curryとかを使っています。

const express = require("express");  
const async = require("async");  
const _ = require("lodash");  

const router = express.Router();  

const admin = require("../admin/admin.js");  
const refusers = admin.database.ref().child("users");  // firebaseのRealtimeDBの参照です  

router.patch("/hogehoge", (req, res) => {  
    const closures = _.partial(function (callback, album) {  
        return _.map(req.body.patches, (patch, key) => {  
            return _.curry(function (callback) {  

                /*  
                    何かの処理  
                */  

                callback(null, null);  

            })(callback);  
        });  
    });  
    function execClosures (album) {  
        async.parallel(closures(_, album), (err, result) => {  
            res.status(200).end();  
        });  
    }  
    refusers.child(req.body.uid).once("value", (snapshot) => {  
        if (snapshot) {  
            const album = snapshot.val();  
            execClosures(album);  
        } else {  
            res.status(500).send({ err: "No snapshot found" });  
        }  
    }).catch(err => {  
        res.status(403).send({ err: err });  
    });  
});  

HerokuにデプロイしたNuxt.jsのプロジェクトの静的ファイルをFirebase Hostingから配信する

静的ファイルだけvuepressで生成したページとあわせてHostingにあげます。package.jsonに以下のようなことを書きます。YOUR_TOKENの部分はfirebase-toolsのlogin:ciというコマンドであらかじめ取得しておいたトークンに読み替えてください。

  "scripts": {  
    "dev": "cross-env NODE_ENV=\"development\" nodemon server/index.js --watch server",  
    "build": "cross-env NODE_ENV=\"production\" nuxt build",  
    "start": "cross-env NODE_ENV=\"production\" forever --killSignal=SIGTERM -c 'nodemon --exitcrash' server/index.js",  
    "inspect": "cross-env NODE_ENV=\"development\" node --require dotenv/config --optimize_for_size --max_old_space_size=920 --gc_interval=100 --inspect server/index.js",  
    "docs:dev": "vuepress dev docs",  
    "docs:build": "vuepress build docs",  
    "deploy:nuxt": "rimraf docs/.vuepress/dist/nuxt && mkdirp docs/.vuepress/dist/nuxt && cpy .nuxt/dist docs/.vuepress/dist/nuxt",  
    "deploy:static": "rimraf docs/.vuepress/dist/static && mkdirp docs/.vuepress/dist/static && cpy static/contents docs/.vuepress/dist/static",  
    "deploy:hosting": "firebase deploy --token 'YOUR_TOKEN' --except functions",  
    "deploy:functions": "firebase deploy --only functions",  
    "heroku-postbuild": "yarn build && yarn run docs:build && yarn run deploy:nuxt && yarn run deploy:static && yarn run deploy:hosting"  
  },  
  "devDependencies": {  
    "cpy-cli": "^2.0.0",  
    "cross-env": "^5.2.0",  
    "dotenv": "^7.0.0",  
    "firebase-tools": "^6.5.3",  
    "forever": "^1.0.0",  
    "mkdirp": "^0.5.1",  
    "nodemon": "^1.18.10",  
    "rimraf": "^2.6.3",  
    "vuepress": "^1.0.0-alpha.47"  
  }  

nuxt.config.jsでアセットをFirebase Hostingから取得するように設定します。ローカルで開発しているときには手元のファイルを参照したいので、production時のみにしましょう。

const isdev = (process.env.NODE_ENV === "development")  

module.exports = {  
    // buildのところだけ抜粋  
    build: {  
        publicPath: isdev ? "/_nuxt/" : "https://your_project_name.firebaseapp.com/nuxt",  
    }  
}  

firebase.jsonのhostingの設定をします。ヘッダーを設定しないとクロスオリジン制約で配信できなくなるので、ここで必ず設定します。

  "hosting": {  
    "public": "docs/.vuepress/dist",  
    "ignore": [  
      "firebase.json",  
    ],  
    "headers": [  
      {  
        "source" : "**/assets/**",  
        "headers" : [{  
          "key" : "Access-Control-Allow-Origin",  
          "value" : "*"  
        }]  
        }, {  
        "source" : "**/nuxt/**",  
        "headers" : [{  
          "key" : "Access-Control-Allow-Origin",  
          "value" : "*"  
        }]  
        }, {  
        "source" : "**/static/**",  
        "headers" : [{  
          "key" : "Access-Control-Allow-Origin",  
          "value" : "*"  
        }]  
    }],  
    "cleanUrls": true,  
    "trailingSlash": false  
  },  
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!