使用Webpack打包含fontkit的AWS Lambda函数失败求助
AWS Lambda邮件脚本PDF生成功能Webpack 4打包问题
我正尝试为基于AWS Lambda实现的邮件脚本添加PDF生成功能,该功能在本地运行正常,但使用Webpack 4打包时出现问题。
我的Webpack配置
'use strict'; const webpack = require('webpack'); const path = require('path'); module.exports = { node: { __dirname: true }, entry: './src/index.js', output: { library: 'mylib', libraryTarget: 'commonjs2' }, resolve: { extensions: ['.json', '.jsx', '.js', '.mjs'], alias: { 'tiny-lru': path.join( process.cwd(), './node_modules/tiny-lru/lib/tiny-lru.cjs.js' ), // pdfkit: 'pdfkit/js/pdfkit.js', 'unicode-properties': 'unicode-properties/unicode-properties.cjs.js' } }, target: 'node', optimization: { minimize: true }, externals: [ 'aws-sdk', 'pino-pretty', 'uglify-es', 'uglify-es/package.json' ], plugins: [ new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/), new webpack.IgnorePlugin(/^pg-native$/) ], module: { rules: [ { test: /unicode-properties[\/\\]unicode-properties/, loader: 'transform-loader?brfs' }, // { test: /pdfkit[/\]js[/\]/, loader: 'transform-loader?brfs' }, { test: /fontkit[\/\\]index.js$/, loader: 'transform-loader?brfs' }, // { // test: /linebreak[\/\\]src[\/\\]linebreaker.js/, // loader: 'transform-loader?brfs' // } { test: /\.mjs$/, include: /node_modules/, type: "javascript/auto"} ] } };
打包错误信息
ERROR in ./node_modules/fontkit/dist/module.mjs 7463:26 Module parse failed: Unexpected token (7463:26) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
尝试过的方案及问题
- 将fontkit设为外部依赖后可完成编译,但运行时报错:
Runtime.ImportModuleError: Error: Cannot find module 'fontkit' - 配置
{ test: /fontkit[\/\\]index.js$/, loader: 'transform-loader?brfs' }和{ test: /\.mjs$/, include: /node_modules/, type: "javascript/auto"},均无效果
解决建议
1. 适配fontkit的ES模块语法
Webpack 4对部分ES模块语法处理存在兼容性问题,可通过babel转译fontkit的mjs文件解决:
- 先安装依赖:
npm install --save-dev babel-loader @babel/core @babel/preset-env - 更新Webpack配置的module.rules:
module: { rules: [ // 保留原有规则 { test: /fontkit\/dist\/module\.mjs$/, use: { loader: 'babel-loader', options: { presets: [['@babel/preset-env', { targets: { node: '14' } }]] // 匹配你的Lambda运行时Node版本 } } }, { test: /\.mjs$/, include: /node_modules/, exclude: /fontkit/, type: "javascript/auto"} ] }
2. 强制使用fontkit的CommonJS版本
在resolve.alias中指定fontkit的CommonJS入口,避免加载ES模块:
resolve: { alias: { // 保留原有alias 'fontkit': path.join(process.cwd(), './node_modules/fontkit/dist/fontkit.cjs.js') } }
同时调整loader规则:
{ test: /fontkit[\/\\]dist[\/\\]fontkit\.cjs\.js$/, loader: 'transform-loader?brfs' }
3. 修正externals的部署逻辑
如果坚持用externals,需确保Lambda环境能找到fontkit:
- 把fontkit留在package.json的dependencies中(不要放到devDependencies)
- 部署时将node_modules一起打包上传,或用Lambda层管理依赖
- 确保Webpack的externals配置包含
'fontkit'
4. 降级fontkit版本
新版本fontkit的ES模块语法可能与Webpack 4兼容性差,尝试降级到稳定旧版本:
npm install fontkit@2.0.2
内容的提问来源于stack exchange,提问作者Igor Shmukler
相关产品推荐
相关产品推荐

