LoginSignup
17
6

More than 5 years have passed since last update.

Serverlessで任意のディレクトリ配下に、関数毎にディレクトリを切ってソースを配置する with webpack building

Last updated at Posted at 2018-02-27

おーばーびゅー

AWSでAPI Gateway/Lambdaの組み合わせでREST APIを運用しています。
以前はLambdaのdeployにApexを使用していたのですが、今回API Gatewayの設定も同時に記述したく、Serverless Frameworkへの移行を決めました。
その際serverless create --template aws-nodejs --path my-service等のコマンドで生成されるディレクトリ構成が気に入らず...
この記事は私の望むディレクトリ構成を得るまでの軌跡です。

環境

macOS Sierra v10.12.6
node.js v9.2.0
yarn v1.3.2
Serverless Framework v1.25.0

いやなところ

--template aws-nodejsで生成したプロジェクト

my-service
├── handler.js
└── serverless.yml

function増やすには...?と調べてみるとエントリポイントは全部handler.jsで、中身だけ別ファイルに書いて、それをhandler.jsでexportしている実装がちらほら
そもそもエントリポイントはfunction別にあったほうがよくない?
functionを増やすとトップレベルに沢山ファイルが出来そうだし...

babel-dynamically-entriesのプロジェクト例

babel-dynamically-entries
├── event.json
├── first.js
├── package.json
├── second.js
├── serverless.yml
├── webpack.config.js
└── yarn.lock

function分けられてるけど結局トップレベルかーい!

こうしたい

api
├── functions
│   └── hello
│       └── index.js
├── package.json
├── serverless.yml
├── webpack.config.js
└── yarn.lock

こんな感じでfunctions以下に関数毎にディレクトリを切りたい

どうやる

init

$ serverless create --template aws-nodejs --path my-best-sls-structure
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/XXXXX/my-best-sls-structure"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.25.0
 -------'

Serverless: Successfully generated boilerplate for template: "aws-nodejs"

$ # globalにserverlessがない場合は下記のコマンド等で適宜導入のほど
$ # npm install -g serverless
$ # yarn global add serverless --prefix /usr/local
$ cd my-best-sls-structure
$ yarn init -y
yarn init v1.3.2
warning The yes flag has been set. This will automatically answer yes to all questions which may have security implications.
success Saved package.json
✨  Done in 0.05s.

install dependencies

一応serverlessも入れてます

$ yarn add babel-core babel-loader webpack serverless serverless-webpack

edit files

serverless.yml
service: my-best-sls-structure

provider:
  name: aws
  runtime: nodejs6.10

# コレが大事
# 
# ref.: https://serverless.com/framework/docs/providers/aws/guide/packaging/#packaging-functions-separately
package:
  individually: true

# webpackと連携するためにserverless-webpackを導入
plugins:
  - serverless-webpack

functions:
  hello:
    handler: functions/hello/index.handler
webpack.config.js
const path = require('path');
const slsw = require('serverless-webpack');

module.exports = {
  // Serverlessのpackage.individuallyを使用する場合にはentryをserverless-webpackに任せる必要がある(slsw.lib.entries)
  // 基本的に問題は起こらないと思うが、entryが足りない!みたいなケースには下記の様なコードで対応しろとのこと(_はlodashなので適宜導入下さい)
  // entry: _.assign({myCustomEntry1: './custom/path/something.js'}, slsw.lib.entries)
  entry: slsw.lib.entries,
  target: 'node',
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  }
};
functions/hello/index.js
// このコードはServerless Frameworkのテンプレートに入ってるアレ
export function handler(event, context, callback) {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event
    })
  };

  callback(null, response);
}

うごかす

ビルドだけ

$ serverless webpack
Serverless: Bundling with Webpack...
Time: 544ms
                   Asset     Size  Chunks             Chunk Names
functions/hello/index.js  2.98 kB       0  [emitted]  functions/hello/index
   [0] ./functions/hello/index.js 257 bytes {0} [built]

localで叩く

$ serverless invoke local --function hello
Serverless: Bundling with Webpack...
Time: 647ms
                   Asset     Size  Chunks             Chunk Names
functions/hello/index.js  2.98 kB       0  [emitted]  functions/hello/index
   [0] ./functions/hello/index.js 257 bytes {0} [built]
{
    "statusCode": 200,
    "body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":\"\"}"
}

うまくビルド出来ていますね

まとめ

api
├── functions
│   └── hello
│       └── index.js
├── package.json
├── serverless.yml
├── webpack.config.js
└── yarn.lock

の様な、任意のディレクトリ(functions)配下で、関数毎にディレクトリを切ってソースを配置するには、下記2点が大事

  • serverless.yml
    • package.individually
  • webpack.config.js
    • entry: slsw.lib.entries

こちらからは以上です。
お疲れ様でした。

17
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
6