yarn publish 与 npm publish 的不同之处

🍺 问题

在写一个 Yeoman generator 的时候, 按照官方文档的写法,在 package.json 中写上了 files 字段,如下:

{
  "name": "generator-webpack-babel",
  "version": "0.6.0",
  "description": "",
  "files": [
    "generators"
  ],
  "keywords": ["yeoman-generator"],
  "dependencies": {
    "yeoman-generator": "^1.0.0"
  }
}

我使用 yarn publish 命令将其发布到 npm 上,然后通过 yarn global add generator-webpack-babel 命令安装这个包的时候,报错:

npm error - Couldn't find a package.json (or bower.json) file in /Users/hugo/.yarn-cache/npm-generator-webpack-babel-0.6.0  
……
……

🍺 探究经过

经过测试,如果去掉 files 字段,则可以正常安装与使用。

那么这个 files 到底是什么,起什么作用?

npm 官方文档的说明如下:

files

The "files" field is an array of files to include in your project. If you name a folder in the array, then it will also include the files inside that folder. (Unless they would be ignored by another rule.)

You can also provide a ".npmignore" file in the root of your package or in subdirectories, which will keep files from being included, even if they would be picked up by the files array. The .npmignore file works just like a .gitignore.

Certain files are always included, regardless of settings:

package.json  
README (and its variants)  
CHANGELOG (and its variants)  
LICENSE / LICENCE

Conversely, some files are always ignored:

.git
CVS  
.svn
.hg
.lock-wscript
.wafpickle-N
*.swp
.DS_Store
._*
npm-debug.log  

这文档写的真简略:"The 'files' field is an array of files to include in your project",就为了包含在项目中?包含在项目中以后干啥用?

经过王子亭、鹏程的指点,明白了这个字段就是给发包用的,跟 .npmignore 是相反的作用。

从文档中可以注意到,package.json、README、CHANGELOG、LICENSE 这种文件总会自动包含的,不管你设置不设置;而 .DS_Store、npm-debug.log 、.git 等文件或文件夹则是永不包含。

再看看 Yarn 的文档

files is a list of files that should be included in your package when published and installed. If unspecified Yarn will include every file.  

"when published and installed", "If unspecified will include every file", 这个文档就清晰多了,明确地说是发包的时候用的;并且没有其他处理,如果不写明 files,就包含所有文件。

这时候报错的原因就显而易见了:

"files": ["generators"] 这种写法对于 npm publish 来说,它会将主代码文件夹和 package.json 一起打包发布,在安装时当然没有问题;

但对于 yarn publish 而言,它会忽略掉 files array 之后的所有文件,甚至连 package.json 文件都忽略掉!因此导致了我的包在安装时报错。

🍺 解决方法

可以简单的改写为:

"files": [
  "generators",
  "package.json",
  "README.md",
  "LICENSE",
  ...
],

也可以放弃 files 字段,改用 .npmignore 文件:

coverage  
test  
.git
...

小技巧一则:可以使用 yarn pack 命令在本地打包,验证打包之后的内容是否正确。

Hugo Jing

Shanghai, China https://changshiban.com
温馨提示:以下为赞助商广告,用以维持服务器费用,从而继续创作原创内容,敬请谅解