使用AWS SDK时无法将TypeScript转译为ES5的问题排查
问题:k6加载AWS模块时因未转译ES6+语法报错
我在用k6(基于Go构建的负载测试工具)做测试,它会将JavaScript代码加载到JS虚拟机中执行。我配置了Webpack+Babel,计划先把代码转译为ES5,再将打包后的bundle传入虚拟机执行,但只要导入AWS相关模块就会报错,错误指向空值合并运算符(??),扩展运算符等ES6+语法也会出现类似问题。
报错信息
Unexpected token (416:34) 414 | } = {}, viaHeader, payloadHash, expiresIn) { 415 | const credentials = await this.credentialProvider(); > 416 | const region = signingRegion ?? (await this.regionProvider());
示例代码
import { S3Client, ListObjectsV2Command, } from "@aws-sdk/client-s3"; import { getDefaultClientConfiguration, resolveDefaultRuntimeConfig } from '@smithy/types/dist-es/extensions' const S3 = new S3Client({ region: "auto", });
Webpack配置
const path = require('path'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin'); const GlobEntries = require('webpack-glob-entries'); module.exports = { mode: 'production', entry: GlobEntries('./src/**/*.ts'), // 为每个测试生成单独的入口 output: { path: path.join(__dirname, 'dist'), libraryTarget: 'commonjs', filename: '[name].js', }, resolve: { extensions: ['.ts', '.js'], }, module: { rules: [ { test: /\.(ts|js)$/, use: 'babel-loader', exclude: /node_modules\/(?!aws-sdk|@aws-sdk|@smithy).*/, }, { type: 'javascript/auto', test: /\.json$/, use: 'json-loader' }, ], }, target: 'node', externals: /^(k6|https?:\/\/)(\/.*)?/, // 生成编译脚本的映射文件 devtool: "source-map", stats: { colors: true, }, plugins: [ new CleanWebpackPlugin(), // 复制静态资源,方便测试中引用(比如测试视频) // 可参考`src/post-file-test.ts`中的使用示例 new CopyPlugin({ patterns: [{ from: path.resolve(__dirname, 'assets'), noErrorOnMissing: true }], }), ], optimization: { // 不需要压缩,因为不在浏览器中使用 minimize: false, }, };
Babel配置
{ "presets": ["@babel/env", "@babel/typescript"], "plugins": [ "@babel/proposal-class-properties", "@babel/plugin-proposal-object-rest-spread", "@babel/plugin-proposal-nullish-coalescing-operator" ] }
问题分析与解决
你的核心问题在于Babel未明确指定目标兼容环境,且Webpack的排除规则存在匹配漏洞:
- @babel/env需明确指定ES5目标环境
默认情况下@babel/env不会主动转译所有ES6+语法,必须明确告知它要兼容的环境。k6的JS虚拟机仅支持ES5,因此需要修改Babel配置,指定目标为ES5级别:
{ "presets": [ ["@babel/env", { "targets": { "ie": "11" // 用IE11代表ES5兼容环境 }, "useBuiltIns": "usage", "corejs": 3 }], "@babel/typescript" ], "plugins": [ "@babel/proposal-class-properties", "@babel/plugin-proposal-object-rest-spread", "@babel/plugin-proposal-nullish-coalescing-operator" ] }
- 修正Webpack的exclude正则规则
你当前的正则/node_modules\/(?!aws-sdk|@aws-sdk|@smithy).*/无法正确匹配@aws-sdk/client-s3这类带子路径的包,导致这些子模块未被Babel处理。调整为以下正则:
exclude: /node_modules\/(?!(@aws-sdk|@smithy|aws-sdk)\/).*/
确保这些包的所有子模块都会被Babel转译。
调整Webpack的target设置
k6的运行环境并非标准Node.js,建议将target: 'node'改为target: 'web',避免Webpack注入Node.js特有的API,引发虚拟机报错。优化@smithy模块的导入路径
你直接导入了@smithy/types/dist-es/extensions这个ES模块源码路径,建议改为直接导入@smithy/types,让Webpack自动处理正确的入口,避免引入未转译的ES代码:
import { getDefaultClientConfiguration, resolveDefaultRuntimeConfig } from '@smithy/types'
验证步骤
- 修改Babel和Webpack配置后,重新执行打包命令
- 查看dist目录下的bundle文件,搜索
??或扩展运算符,确认是否已被转译为ES5语法 - 使用k6运行打包后的文件,检查是否还出现语法错误
内容的提问来源于stack exchange,提问作者user38643
相关产品推荐
相关产品推荐

