当我serverless offline
同时使用 Node 和 Python 运行时运行时,在访问 Python 端点时出现以下错误:
Traceback (most recent call last):
File "/foo/node_modules/serverless-offline/dist/lambda/handler-runner/python-runner/invoke.py", line 76, in <module>
module = import_module(args.handler_path.replace(os.sep, '.'))
File "/foo/venv/lib/python3.6/importlib/__init__.py", line 121, in import_module
raise TypeError(msg.format(name))
TypeError: the 'package' argument is required to perform a relative import for '.webpack.service.src.utilsPy'
我可以成功点击 Node 运行时。
如果我改为运行serverless offline --location .
,我能够成功转到 Python 端点,但 Node 端点给了我这个错误
Failure: Cannot find module '/foo/src/utils'
Require stack: <removed stack trace>
有没有办法同时离线运行?我可以部署两个运行时并且它可以工作,它只是无服务器离线,不起作用。源文件如下。
PS:我在serverless-offline repo 上创建了一个问题。
示例代码
- 文件:serverless.yml
service :
name: ${self:custom.serviceName}
custom :
packageJson : ${file(./package.json)}
serviceName : ${self:custom.packageJson.name}
webpack :
webpackConfig : ./webpack.config.js
includeModules: true
serverless-offline:
httpPort: 4000
pythonRequirements:
dockerizePip: true
plugins:
- serverless-webpack
- serverless-offline
- serverless-pseudo-parameters
- serverless-python-requirements
provider :
name : aws
runtime : nodejs12.x
<removed a bunch of parameters not relevant to this>
functions:
- ${file(some-other-file-not-relevant.yml)}
- health:
name : ${self:service}-${self:provider.stage}-health
description: Health check endpoint
handler : src/utils.handler
memorySize : 128
timeout : 10
events :
- http:
path : /health
method: GET
cors : true
- health-py:
name : ${self:service}-${self:provider.stage}-health-py
runtime : python3.6
description: Health check endpoint for python
handler : src/utilsPy.handler
memorySize : 128
timeout : 10
events :
- http:
path : /health-py
method: GET
cors : true
- 文件:webpack.config.js
const path = require('path');
const slsw = require('serverless-webpack');
const nodeExternals = require('webpack-node-externals');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
// CUSTOM CODE: Remove Python files as entry points
const entries = {};
Object.keys(slsw.lib.entries).forEach(
key => {
if (!slsw.lib.entries[key].match(/\.py$/)) {
entries[key] = [slsw.lib.entries[key]]
}
}
);
module.exports = {
context: __dirname,
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
entry: entries, // CUSTOM CODE: Uses custom entry above
devtool: slsw.lib.webpack.isLocal ? 'cheap-module-eval-source-map' : 'source-map',
resolve: {
extensions: ['.mjs', '.json', '.ts'],
symlinks: false,
cacheWithContext: false,
},
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, '.webpack'),
filename: '[name].js',
},
target: 'node',
externals: [nodeExternals()],
module: {
rules: [
// all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
{
test: /\.(tsx?)$/,
loader: 'ts-loader',
exclude: [
[
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, '.serverless'),
path.resolve(__dirname, '.webpack'),
],
],
options: {
transpileOnly: true,
experimentalWatchApi: true,
},
},
],
},
plugins: [
// new ForkTsCheckerWebpackPlugin({
// eslint: true,
// eslintOptions: {
// cache: true
// }
// })
],
};
- 文件:utils.ts
import { APIGatewayProxyHandler } from 'aws-lambda';
import 'source-map-support/register';
/**
* A simle health check endpoint...
* @param event
* @param _context
*/
export const handler: APIGatewayProxyHandler = async (event, _context) => {
return {
statusCode: 200,
body: JSON.stringify({
message: 'Healthy!',
input: event,
}, null, 2),
};
};
- 文件:utilsPy.py
"""
A simple health checkpoint for python
"""
import json
def handler(event, context):
return {
'statusCode': 200,
'body':
json.dumps({
'message':'Healthy Python!',
'input': event
})
}