减少无服务器框架发送的节点模块 zip 的大小
Reduce the size of the node-modules zip sent by the 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 秒,zip 大小约为 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),或者只上传更改后的文件吗?
您可以使用无服务器功能排除一些您不需要的包(例如,您保证here the manual。
不幸的是,从 1.16 版开始,似乎存在一个问题,即忽略了那些排除项(1.15.1 版创建了更小的 zip,并且从 1.16 开始,zip 包含了您 node_modules 中的任何内容)。我打开了一个 issue,但仍然无人接听。
aws-sdk
大约为 24MB,您不需要它,因为 it's already available 是 lambda 函数。一种选择是将其移至开发依赖项,然后将您的开发依赖项放入父目录的 package.json
。
还有一些工具可以提供帮助:
serverless-plugin-include-dependencies 插件 - 我不确定如果排除功能被破坏它的效果如何:https://github.com/dougmoscrop/serverless-plugin-include-dependencies
Webpack 也可以与 serverless-webpack 插件一起使用来控制依赖项。 Webpack 的死代码消除可以带来相当大的不同。
不理想,但您也可以在部署前 运行 npm prune --production
。 (之后您需要再次 运行 npm install
。
为了解决这个问题,我使用了一个名为 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
我为此使用了层:层用于以层的形式引入额外的代码和内容。这将使您的 lambda 函数保持较小并从层中提取依赖项在运行时。
第 1 步:
在某处创建一个名为 nodejs
的文件夹
cd Desktop
mkdir nodejs
cd nodejs
npm init
第 2 步:
在此文件夹中安装您的依赖项,这些依赖项的大小很大。例如:
npm install --save geoip-lite
第 3 步:
压缩它,给你选择的名字。
第 4 步:
登录到 aws 控制台,转到 lambda 服务,然后选择创建层。然后上传您创建的 zip 文件。 (正如它所说,如果它大于 10 mb,您可以将此 zip 文件上传到 S3)
在此步骤中,您可以通过进入 lambda 函数将图层分配给 lambda,并添加您在上述步骤中创建的自定义图层。
如果您有兴趣添加层是 yml 配置
functions:
hello:
handler: handler.hello
layers:
- arn:aws:lambda:region:XXXXXX:layer:LayerName:Y
我正在使用 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 秒,zip 大小约为 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),或者只上传更改后的文件吗?
您可以使用无服务器功能排除一些您不需要的包(例如,您保证here the manual。
不幸的是,从 1.16 版开始,似乎存在一个问题,即忽略了那些排除项(1.15.1 版创建了更小的 zip,并且从 1.16 开始,zip 包含了您 node_modules 中的任何内容)。我打开了一个 issue,但仍然无人接听。
aws-sdk
大约为 24MB,您不需要它,因为 it's already available 是 lambda 函数。一种选择是将其移至开发依赖项,然后将您的开发依赖项放入父目录的 package.json
。
还有一些工具可以提供帮助:
serverless-plugin-include-dependencies 插件 - 我不确定如果排除功能被破坏它的效果如何:https://github.com/dougmoscrop/serverless-plugin-include-dependencies
Webpack 也可以与 serverless-webpack 插件一起使用来控制依赖项。 Webpack 的死代码消除可以带来相当大的不同。
不理想,但您也可以在部署前 运行 npm prune --production
。 (之后您需要再次 运行 npm install
。
为了解决这个问题,我使用了一个名为 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
我为此使用了层:层用于以层的形式引入额外的代码和内容。这将使您的 lambda 函数保持较小并从层中提取依赖项在运行时。
第 1 步:
在某处创建一个名为 nodejs
cd Desktop
mkdir nodejs
cd nodejs
npm init
第 2 步: 在此文件夹中安装您的依赖项,这些依赖项的大小很大。例如:
npm install --save geoip-lite
第 3 步: 压缩它,给你选择的名字。
第 4 步: 登录到 aws 控制台,转到 lambda 服务,然后选择创建层。然后上传您创建的 zip 文件。 (正如它所说,如果它大于 10 mb,您可以将此 zip 文件上传到 S3)
在此步骤中,您可以通过进入 lambda 函数将图层分配给 lambda,并添加您在上述步骤中创建的自定义图层。
如果您有兴趣添加层是 yml 配置
functions:
hello:
handler: handler.hello
layers:
- arn:aws:lambda:region:XXXXXX:layer:LayerName:Y