Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

おーばーびゅー

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

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

wara_be
TypeScriptとかReactとかServerlessとか
mohikanz
エンジニアのための雑談コミュニティ
https://mohikanz.slack.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした