2019年10月16日水曜日

firebase clound functionsをTypeScript + webpackでalias(絶対パス)付きでビルドしてみる的なお話

  • このエントリーをはてなブックマークに追加

firebaseが昨今注目されまくってて色々と情報があるわけで。
まぁAWSでいうlambdaみたいなものなんだけどこれがまた便利だったりするわけで。
ということでcron的な感じでts-nodeを使って色々と回してたTypeScript製のやつをfirebaseに載せちゃおうと思ったりなんだり。

tscでビルドするなりfirebase deployするなり色々と面倒な工程が増えたわけだけどもそれでも十分得るものは大きいなぁと。
けどその中で特に面倒だったのがtsconfig.jsonで絶対パスとしてファイルを読み込むために設定していたpathsがビルドされると自動で変換されないっていう。

ということで今日は絶対パスで記述していたtsファイルをビルドしてfirebase serveするまで的なお話をば。

■firebase funcitonsをinit

$ firebase init functions

# after init
myproject
 +- .firebaserc
 +- firebase.json
 +- functions/
      +- .eslintrc.json
      +- package.json
      +- index.js
      +- node_modules/

まずはfirebase functionsをこれで初期化。
そうすると上のようにfirebasercとかjsonとかが追加されたりfunctionsディレクトリっていうのが作成されて中に色々とファイルが入ってたり。

けどすでにプロジェクトルートにpackage.jsonとかあったりするからなんとなくfunctionsの中にpackage.jsonとかがあると気持ち悪いなぁ的な。
それにeslintも別設定になると困るというかルートリポジトリに.vscodeでsettings.jsonでeslintの設定とかもあるわけで。

ってことでfunctionsの中をindex.jsだけにするんだけど、そもそもtypescriptなのでindex.jsもtypescriptにしちゃってね的な。

■webpackでビルドする準備

$ npm install --save-dev webpack webpack-cli ts-loader webpack-node-externals
$ npm install --save firebase-admin firebase-functions

webpackでビルドしたいからwebpackとか諸々必要なものをインストールしましょう的な。
あとfirebase系のライブラリもちゃんと入れないといけないですよ的な。

{
  "scripts": {
    "lint": "tslint --project tsconfig.json",
    "build": "webpack",
    "serve": "npm run build && firebase serve --only functions",
    "shell": "npm run build && firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log",
    ...
  },
}

次にプロジェクトルートのpackage.jsonのscriptsに諸々記載。
重要なのはbuildをwebpackにしたところ。

const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  mode: 'production',
  entry: './functions/src/index.ts',
  output: {
    filename: 'index.js',
    path: `${__dirname}/functions/lib`,
    libraryTarget: 'this',
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.json'],
    alias: {
      app: path.resolve(__dirname, './'),
    },
  },
  target: 'node',
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        loader: 'ts-loader',
        options: {
          configFile: path.resolve(__dirname, 'tsconfig.json'),
        },
      },
    ],
  },
  externals: [nodeExternals()],
};

で、プロジェクトルートにwebpack.config.jsを作ってあげる。
entryポイントを指定してoutputを指定して、あとはimport用のパスを絶対パスにしたいからresolvealiasを指定。
externalsにwebpack-node-externalsを指定してあげればそれで完了。

ちなみにtsconfig.jsonにもパス解決用のbaseUrlとかpathsをちゃんと記述しておきましょう的な。

■ローカルで走らせるためにserveしてみる

myproject
 +- .firebaserc
 +- firebase.json
 +- functions/
      +- index.ts
 +- src/
 +- package.json
 +- webpack.config.js
 ...

こんな感じになるはずなんじゃないかなと。
srcの中に色々とtsが入ってたりして、functions/index.tsとかで絶対パスでimportしたりすると。

$ npm run serve

そうするとfunctions/lib内にtypescriptがwebpackを通してts-loaderでビルドされ、さらにresolveのaliasでパスを解決したjsが生成されるって感じ。
で、serveでローカル環境で確認することができるっていう。
これでpackage.jsonも1つだけになるし、全部絶対パスで記述できるしっていう。

個人的にはfirebase functionsを使うためにpackage.jsonがもう1つ生成されるとかが嫌いだからこれがいいなぁと。
まぁでもwebpackとか通さずともtscがちゃんと絶対パスビルドできるようにしてくれれば楽なのになぁ的なみたいな。

0 件のコメント:

コメントを投稿

Adsense