如何在Serverless Framework中自定义部署上传的服务器目录名称?
我碰到过不少开发者遇到这个问题——Serverless Framework默认会用{service name}-{stage}-{function name}作为部署后Lambda执行环境的根目录名,而不是你本地的service-dev-lambdaname,这就导致本地基于父文件夹的相对导入在云端直接失效了。下面给你几个实用的解决思路:
1. 调整导入逻辑,适配Lambda执行环境
Lambda执行时,根目录就是打包后的那个命名文件夹,所以你应该直接基于项目内的子目录(比如src、lib)来写导入语句,而不是带上本地的父文件夹名。比如把:
from service-dev-lambdaname.src.utils import helper
改成:
from src.utils import helper
本地开发时如果出现导入报错,可以在代码开头临时把项目根目录加入Python的搜索路径:
import sys from pathlib import Path # 把项目根目录(当前文件的父级父级)加入sys.path sys.path.append(str(Path(__file__).parent.parent))
这样本地和云端的导入逻辑就能保持一致了。
2. 自定义Serverless打包配置,控制目录结构
你可以在serverless.yml里通过package配置来精确控制打包的内容和结构,避免不必要的目录层级问题。比如:
package: # 如果每个函数单独打包,开启这个选项更高效 individually: true # 指定要打包的文件/目录,确保只包含需要的内容 patterns: - 'src/**' - 'lib/**' - 'python-library-1/**' - 'python-library-2/**' - '!node_modules/**' # 排除不需要的目录,如果有的话
如果需要完全自定义打包后的根目录结构,还可以写一个简单的打包脚本:先把需要的文件复制到一个临时目录(比如.serverless-temp),然后让Serverless打包这个临时目录,这样就能让云端的根目录和本地结构一致了。脚本示例(可以加到serverless.yml的custom或者用scripts执行):
mkdir -p .serverless-temp cp -r src lib python-library-1 python-library-2 .serverless-temp/
然后在serverless.yml里指定打包路径:
package: path: .serverless-temp
3. 用Lambda Layer管理第三方依赖
对于python-library-1和python-library-2这类依赖库,更推荐的做法是把它们做成Lambda Layer。Layer会被Lambda自动加到Python的site-packages路径里,这样你直接写import python_library_1就能导入,完全不用关心目录结构的问题。
配置示例:
layers: MyPythonLibs: # 把你的两个库放到layers/my-python-libs/python目录下 path: layers/my-python-libs compatibleRuntimes: - python3.10 # 替换成你使用的Python运行时版本 description: Custom Python libraries for my service functions: yourLambdaFunction: handler: src/handler.main layers: - !Ref MyPythonLibsLambdaLayer
这样不仅解决了导入路径的问题,还能让多个Lambda函数共享这些依赖,减少打包体积和部署时间。
内容的提问来源于stack exchange,提问作者curiousgeorge

