parcel-plugin-static-files-copy 踩坑记录

423 阅读2分钟

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 的版本问题,但本人最近在找工作,实在有点忙,暂时就不继续深入研究了。