TL;DR
- 如果是
The "path" argument must be of type string. Received undefined报错的话,可以试着为package.json添加"pkgdir": "./"属性。
一、前言
最近在复刻一个网页小游戏的时候,由于有遇到使用 parcel 打包 .m4a / .png 等静态文件的需求,但 parcel 本身又只支持将文件打包进 JS 包中。
在网上搜索了下相关的解决办法,基本上都提到了 parcel-plugin-static-files-copy 这个库,但在使用这个库时却遇到了一些问题。
二、安装 / 版本
本人使用的 parcel 版本为 1.9.7,安装的 parcel-plugin-static-files-copy 版本为 2.6.0。
安装插件:
npm install -D parcel-plugin-static-files-copy
三、报错:The "path" argument must be of type string. Received undefined
我们使用 parcel-plugin-static-files-copy 官方文档中的第一个案例的配置,这里给出我的 package.json:
{
"name": "test",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"staticFiles": {
"staticPath": "public",
"watcherGlob": "**"
},
"devDependencies": {
"parcel-plugin-static-files-copy": "^2.6.0"
}
}
项目目录树:
D:\test
├─package.json
├─src
| └index.html
├─public
| └target1.txt
根据文档要求安装插件并且创建静态文件目录 public 后,执行打包命令:
parcel build src/index.html
此时会提示错误:
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
我们进入 parcel-plugin-static-files-copy 源代码,查看错误所在的 184 行:
for (let singlePath of paths) {
let staticPath = path.join(pkg.pkgdir, singlePath) // 在这一行报错
if (!fs.existsSync(staticPath)) {
通过 log 结合报错提示,我们可以很容易的判断出这句话报错的原因是 pkg.pkgdir 的值为 undefined。
再 console.log(pkg),易得 pkg 就是 package.json 的对象,显然我们原始的 package.json 中并没有 pkgdir 属性。
通过语义我们也可以理解这句话的含义是:拼接项目路径和静态文件路径。
而 pkg 源自 parcel-bundler 中的异步方法 getPackage() 的返回值,由此我们可以猜测大约是 parcel-bundler 的版本问题所导致的返回值 pkg 的对象中缺少了 pkgdir 属性。
四、解决办法
至此,虽然还没有彻底搞清 parcel-bundler 中有哪些问题,但我们已经有一个简单的解决方案,在 package.json 中添加一个 pkgdir 属性,强行给予它一个项目路径即可:
{
// ...
"pkgdir": "./",
}
执行打包命令,执行打包命令,顺利在 dist 目录下获得 copy 后的静态文件。
打包后的项目目录树:
D:\test
├─package.json
├─src
| └index.html
├─public
| └target1.txt
├─dist
| ├─index.html
| └target1.txt
至此解决问题(虽然只是治标)后的 package.json:
{
"name": "test",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"pkgdir": "./",
"staticFiles": {
"staticPath": [
"public"
],
"watcherGlob": "**"
},
"devDependencies": {
"parcel-plugin-static-files-copy": "^2.6.0"
}
}
根本性的原因应该在于 parcel 的版本问题,但本人最近在找工作,实在有点忙,暂时就不继续深入研究了。