You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Serverless AWS Lambda转TypeScript遇模块外import语句错误

问题:Serverless Lambda迁移TypeScript时出现import语法运行时错误

我正在将Serverless AWS Lambda微服务API迁移至TypeScript,计划保留现有JS文件并逐步新增TS文件。但配置Webpack与TypeScript后,调用getInstitutionInfo Lambda函数时触发以下运行时错误:

× Unhandled exception in handler 'getInstitutionInfo'.
× Runtime.UserCodeSyntaxError: SyntaxError: Cannot use import statement outside a module
      at _loadUserApp (C:\git\my-project\node_modules\serverless-offline\src\lambda\handler-runner\in-process-runner\aws-lambda-ric\UserFunction.js:307:15)
      at async module.exports.load (C:\git\my-project\node_modules\serverless-offline\src\lambda\handler-runner\in-process-runner\aws-lambda-ric\UserFunction.js:341:21)
      at async InProcessRunner.run (file:///C:/git/my-project/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/InProcessRunner.js:41:21)
      at async MessagePort.<anonymous> (file:///C:/git/my-project/node_modules/serverless-offline/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js:24:14)
× SyntaxError: Cannot use import statement outside a module

怀疑问题出在第三方依赖包而非自身代码,当前使用的tsconfig.json与Webpack配置如下:

tsconfig.json

{
  "$schema": "https://json.schemastore.org/tsconfig",
  "compilerOptions": {
    "lib": [
      "es2020"
    ],
    "module": "commonjs",
    "target": "es2020",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "sourceMap": true,
    "allowJs": true,
    "outDir": ".erb/dll"
  }
}

Webpack配置文件

const path = require('path');
const slsw = require('serverless-webpack');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  devtool: slsw.lib.webpack.isLocal ? 'source-map' : 'cheap-source-map',
  entry: slsw.lib.entries,
  target: 'node',
  resolve: {
    extensions: ['.cjs', '.mjs', '.js', '.ts'],
  },
  output: {
    libraryTarget: 'commonjs2',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
  },
  externals: ['aws-sdk', nodeExternals()],
  module: {
    rules: [
      {
        test: /\.[jt]s?$/,
        loader: 'ts-loader',
        exclude: [
          [
            /node_modules/,
            path.resolve(__dirname, '.webpack'),
            path.resolve(__dirname, '.serverless'),
          ],
        ],
        options: {
          transpileOnly: true,
          experimentalFileCaching: true,
        },
      },
    ],
  },
  plugins: [new ForkTsCheckerWebpackPlugin()],
};

解决方案

1. 处理第三方ES模块依赖

你的Webpack配置使用了nodeExternals(),会将所有node_modules中的依赖排除在打包流程外。如果某个第三方依赖本身是ES模块(使用import/export语法),Node.js会因为Lambda产物是CommonJS格式而无法识别,触发语法错误。

修改externals配置,把有问题的依赖包加入allowlist,让Webpack将其打包并转译为CommonJS:

externals: ['aws-sdk', nodeExternals({
  allowlist: ['有问题的第三方包名'] // 替换为实际出问题的包,比如'axios'
})],

如果多个包有问题,可以用正则匹配,比如allowlist: /^@your-org\/.+/匹配特定组织的包。

2. 优化TypeScript与Webpack的模块配置

  • 给tsconfig.json添加moduleResolution: 'node',确保模块解析逻辑符合Node.js规范:
    "compilerOptions": {
      // ... 原有配置
      "moduleResolution": "node"
    }
    
  • 将Webpack的target设为你Lambda实际使用的Node.js版本(比如Node.js 18),提升兼容性:
    target: 'node18', // 对应Lambda的Node.js 18.x运行时
    

3. 确保JS文件被正确转译

虽然你怀疑是第三方包的问题,但仍需确认现有JS文件是否混用了ES模块与CommonJS语法。可以调整Webpack的loader规则,确保JS文件被ts-loader正确处理:

{
  test: /\.[jt]s?$/,
  use: ['ts-loader'],
  exclude: [/node_modules/, path.resolve(__dirname, '.webpack'), path.resolve(__dirname, '.serverless')],
}

4. 调整Serverless Offline配置

在serverless.yml中给serverless-offline添加useChildProcesses: true,避免本地运行时的模块加载冲突:

plugins:
  - serverless-webpack
  - serverless-offline
custom:
  serverless-offline:
    useChildProcesses: true

内容的提问来源于stack exchange,提问作者Real World

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 21:27:11