减少无服务器框架

时间:2017-07-13 08:31:39

标签: node.js npm dependencies aws-lambda serverless-framework

我正在使用the serverless framework编写一些nodejs函数。 package.json文件需要一些依赖项:

{
  "name": "adam-test-sls",
  "version": "0.1.0",
  "description": "Test package to play with sls/lambda",
  "main": "handler.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Adam Matan <adam@binaris.com>",
  "license": "UNLICENSED",
  "dependencies": {
    "aws-sdk": ">= 2.0.9",
    "json": "^9.0.6",
    "underscore": "^1.8.3",
    "uuid": "^3.1.0"
  },
  "devDependencies": {
    "eslint": "^4.2.0",
    "eslint-config-airbnb": "^15.0.2",
    "eslint-config-airbnb-base": "^11.2.0",
    "eslint-plugin-import": "^2.7.0"
  }
}

node-modules目录的大小差不多是50mb:

# du -smc node_modules
47  node_modules
47  total

部署时间超过35秒,拉码大小约为9.5MB:

# time serverless deploy function --function hello -v
Serverless: Packaging function: hello...
Serverless: Uploading function: hello (9.46 MB)...
Serverless: Successfully deployed function: hello
serverless deploy function --function hello -v  4.28s user 1.15s system 15% cpu 35.165 total

这有点低效 - 我只更改了一个文件,但每当我做出最轻微的改动时,我都必须打包所有未更改的依赖项。

任何想法如何减少zip大小(可能删除devDependencies),或只上传更改的文件?

4 个答案:

答案 0 :(得分:5)

aws-sdk在24MB左右,从it's already available到lambda函数你不需要它。一种选择是将其移至dev-dependencies,然后将dev-dependencies放在父目录的package.json中。

还有一些工具可以提供帮助:

serverless-plugin-include-dependencies插件 - 以为我不确定如果排除功能被破坏它的效果如何:https://github.com/dougmoscrop/serverless-plugin-include-dependencies

Webpack也可以与serverless-webpack插件一起使用来控制依赖项。 Webpack的死代码消除可以产生相当大的差异。

不理想,但您也可以在部署之前运行npm prune --production。 (您需要在之后再次运行npm install

答案 1 :(得分:4)

您可以使用无服务器功能排除某些不需要的软件包(例如,您可以保证here the manual

不幸的是,从版本1.16开始,似乎存在一个问题,即那些排除被忽略(版本1.15.1创建了更小的拉链,并且从1.16开始,zip包含node_modules中的任何内容)。我开了一个issue,但仍然没有答案。

答案 2 :(得分:1)

我为此使用了层:层用于以层的形式引入其他代码和内容。这将使您的lambda函数保持较小状态,并将在运行时从层中提取依赖项。 >

步骤1: 在名为nodejs

的位置创建一个文件夹
cd Desktop
mkdir nodejs
cd nodejs
npm init

步骤2: 在此文件夹中安装较大的依赖项。例如:

npm install --save geoip-lite

第3步: 压缩它,输入您选择的名称。

步骤4: 登录到AWS控制台,转到lambda服务,然后选择“创建图层”。然后上传您创建的zip文件。 (正如上面所说,如果该zip文件大于10 mb,则可以将其上传到S3)

在此步骤中,您可以进入lambda函数并为您在上述步骤中创建的自定义图层添加图层,从而为lambda分配图层。

如果您有兴趣添加图层,请使用yml config

functions:
  hello:
   handler: handler.hello
   layers:
    - arn:aws:lambda:region:XXXXXX:layer:LayerName:Y

答案 3 :(得分:0)

为解决此问题,我使用了一个名为serverless-plugin-scripts的插件,并编写了一个在after:package:createDeploymentArtifacts钩子上运行的shell脚本。

该脚本解压缩部署软件包removes node_modules目录,运行npm install --only=prod并将所有内容打包回来。由于某种原因,npm prune --production对我来说根本无法正常工作。

这是配置(serverless.yml):

service: my-service-name
provider:
  name: aws
  runtime: nodejs8.10
  region: us-east-1
  environment:
    NODE_ENV: ${self:custom.stage}

custom:
  stage: ${opt:stage, self:provider.stage}
  region: ${opt:region, self:provider.region}
  scripts:
    hooks:
      'after:package:createDeploymentArtifacts': >
        printf "[after:package:createDeploymentArtifacts hook] Removing development dependencies " &&
        (cd .serverless && unzip -qq my-service-name.zip -d my-service-name)          && printf "." &&
        (cd .serverless && rm -rf my-service-name/node_modules)                       && printf "." &&
        (cd .serverless/my-service-name && npm install --only=prod > /dev/null 2>&1)  && printf "." &&
        (cd .serverless/my-service-name/ && zip -q -FSr ../my-service-name.zip .)     && printf ".\n" &&
        rm -rf .serverless/my-service-name/ &&
        printf "[after:package:createDeploymentArtifacts hook] Done\n"

functions:  
  scheduledHandler:
    handler: src/handlers.scheduledHandler
    events:
      - schedule: rate(10 minutes)

package:
  exclude:
  - .vscode/**
  - .idea/**
  - test/**
  - build/**
  - .build/**

plugins:
  - serverless-plugin-scripts