ビルド時にデータベースのデータをJSファイルに埋め込む

webpackでビルドするときに、外部データベースのデータをJSファイル内に埋め込む方法。
機密にする必要がなくて、ほぼ変更しないデータがあったので、毎回サーバーから受けとるよりもJSファイルのなかに埋め込んでしまえば、通信するコストがかからないと思ったのでやってみた。

最初、gulp-dataを使えばできるんじゃないかと思ったけど、どうやらそれでは無理らしく、webpackのDefinePluginを使えばやりたいことができた。

webpackのDefinePluginは、webpackでビルドするときに設定値に値を注入することができるプラグイン
例えば、モジュールに含まれるprocess.env.NODE_ENVproductionに置き換えたりということができる。

こんな感じのコードでうまいこといった。

'use strict';
const MongoClient = require('mongodb').MongoClient;
const webpack = require('webpack');

const DATABASE_URL = 'mongodb://for_webpack:pass@ds061974.mongolab.com:61974/heroku_k4vml408';

const fetchData = query => {
  return new Promise((resolve, reject) => {
    MongoClient.connect(DATABASE_URL, (err, db) => {
      if (err) {
        return reject(err);
      }

      db.collection('posts').find(query).toArray((err, docs) => {
        if (err) {
          return reject(err);
        }

        resolve(docs);
        db.close();
      });
    });
  });
};

const build = data => {
  return new Promise((resolve, reject) => {
    webpack({
      entry: {
        app: './src/app.js'
      },

      output: {
        path: './dist',
        filename: '[name].js'
      },

      plugins: [
        new webpack.DefinePlugin({
          FETCHED_DATA: JSON.stringify(data)
        })
      ]
    }, (err, stats) => {
      if (err) {
        return reject(err);
      }

      console.log(stats.toString({ colors: true }));
      resolve();
    });
  });
};

fetchData({})
  .then(build);

これで、モジュール中のFETCHED_DATAが取得したデータに置き換えられる。

mongodbのURLは、以前作ったブログのデータベース。
一応読み取り専用のユーザーにしてる。

全コードはここに置いた。