「ちるなり|短歌の投稿サイト」の技術的な話のメモです。
複雑な処理になると自分で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 });
});
});
静的ファイルだけ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
},
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント