Webpack打包AWS-CDK库后Node无法解析文件夹绝对路径如何解决
我正尝试使用TypeScript构建一个AWS-CDK库,使用Webpack来完成库的构建与打包工作。
由于项目需要用到存放在项目根目录的静态文件,我在webpack配置中使用了Copy-Plugin,将静态文件输出到dist文件夹中。
之后我尝试引用该文件夹时,无法得到正确的绝对路径,控制台仅输出/swagger-ui,同时CDK抛出如下异常:
Error: Cannot find asset at /swagger-ui
我引用文件夹路径的代码如下:
const swaggerUiPath = path.resolve(__dirname, './swagger-ui') new s3deploy.BucketDeployment(this, 'swagger-ui', { sources: [s3deploy.Source.asset(swaggerUiPath)], destinationBucket: apiDocBucket })
我尝试了多种获取文件夹全路径的方法,仍然遇到相同问题,可能是我遗漏了某些配置,或是Webpack存在我不了解的底层处理逻辑,恳请大家帮忙解决,谢谢!
webpack.config.js配置内容:
const path = require('path'); const NodePolyfillPlugin = require("node-polyfill-webpack-plugin") const CopyPlugin = require("copy-webpack-plugin") const nodeExternals = require('webpack-node-externals') module.exports = { entry: './lib/index.ts', target: 'node', module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, ], }, resolve: { extensions: ['.ts', '.js'], }, output: { filename: 'index.js', path: path.resolve(__dirname, 'dist'), libraryTarget: 'commonjs', globalObject: 'this', }, plugins: [ new NodePolyfillPlugin(), new CopyPlugin({ patterns: [ { from: "swagger-ui", to: "swagger-ui" } ], }), ], // 用于忽略node_modules文件夹下的所有模块 externals: [nodeExternals()], };
package.json配置内容:
{ "name": "aws-openapi-ui", "version": "0.1.0", "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "webpack", "watch": "tsc -w" }, "devDependencies": { "@aws-cdk/assert": "1.114.0", "@types/jest": "^26.0.10", "@types/jszip": "^3.4.1", "@types/node": "10.17.27", "@types/swagger-ui": "^3.47.1", "copy-webpack-plugin": "^9.0.1", "node-polyfill-webpack-plugin": "^1.1.4", "ts-loader": "^9.2.3", "typescript": "~3.9.7", "webpack": "^5.45.1", "webpack-cli": "^4.7.2", "webpack-node-externals": "^3.0.0" }, "peerDependencies": { "@aws-cdk/core": "1.114.0" }, "dependencies": { "@aws-cdk/aws-s3": "1.114.0", "@aws-cdk/aws-s3-deployment": "1.114.0", "@aws-cdk/core": "1.114.0", "jszip": "^3.6.0" }, "files": [ "dist" ] }
问题根因
Webpack在打包Node端代码时,默认会对__dirname全局变量做替换处理,默认值为/,所以你代码中拼接的路径最终会变成/swagger-ui,自然找不到对应资源。
具体修改
在webpack.config.js的配置根节点添加node配置项,关闭Webpack对__dirname和__filename的默认重写逻辑:
module.exports = { // 原有其他配置保持不变 target: 'node', // 新增以下配置 node: { __dirname: false, __filename: false, }, // 原有其他配置保持不变 }
该配置会让Webpack保留Node原生的__dirname变量逻辑,运行时__dirname会正确指向当前执行文件所在的目录绝对路径。
你当前CopyPlugin已经把swagger-ui文件夹复制到了dist根目录,打包后的入口文件index.js也在dist根目录,原有路径拼接代码不需要修改,重新执行npm run build后即可正常读取到对应路径。
注意事项
每次代码修改后需要重新执行构建命令生成最新的dist目录,确保静态资源和打包代码同步。你当前package.json的files配置已经包含了dist目录,发布后安装的依赖包会完整包含静态资源,不会出现资源缺失问题。
内容的提问来源于stack exchange,提问作者JBDev

