概述本⽂档是⾃⼰看官⽅⽂档的理解+翻译,内容是package.json配置⾥边的属性含义。package.json必须是⼀个严格的json⽂件,⽽不仅仅是js⾥边的⼀个对象。其中很多属性可以通过npm-config来⽣成。
namepackage.json中最重要的属性是name和version两个属性,这两个属性是必须要有的,否则模块就⽆法被安装,这两个属性⼀起形成了⼀个npm模块的唯⼀标识符。模块中内容变更的同时,模块版本也应该⼀起变化。name属性就是你的模块名称,下⾯是⼀些命名规则:
name必须⼩于等于214个字节,包括前缀名称在内(如 xxx/xxxmodule)。name不能以\"_\"或\".\"开头不能含有⼤写字母
name会成为url的⼀部分,不能含有url⾮法字符下⾯是官⽹⽂档的⼀些建议:
不要使⽤和node核⼼模块⼀样的名称
name中不要含有\"js\"和\"node\"。 It's assumed that it's js, since you're writing a package.json file, and you can specify the engine usingthe \"engines\" field. (See below.)
name属性会成为模块url、命令⾏中的⼀个参数或者⼀个⽂件夹名称,任何⾮url安全的字符在name中都不能使⽤,也不能以\"_\"或\".\"开头
name属性也许会被写在require()的参数中,所以最好取个简短⽽语义化的值。创建⼀个模块前可以先到后边的⽹址查查name是否已经被占⽤.
name属性可以有⼀些前缀如 e.g. @myorg/mypackage.在npm-scope(7)的⽂档中可以看到详细说明
versionversion必须可以被npm依赖的⼀个node-semver模块解析。具体规则见下⾯的dependencies模块
description⼀个描述,⽅便别⼈了解你的模块作⽤,搜索的时候也有⽤。
keywords⼀个字符串数组,⽅便别⼈搜索到本模块
homepage项⽬主页url
注意: 这个项⽬主页url和url属性不同,如果你填写了url属性,npm注册⼯具会认为你把项⽬发布到其他地⽅了,获取模块的时候不会从npm官⽅仓库获取,⽽是会重定向到url属性配置的地址。
(原⽂档中⽤了 spit(吐)这个单词,作者表⽰他不是在开玩笑:)
bugs填写⼀个bug提交地址或者⼀个邮箱,被你的模块坑到的⼈可以通过这⾥吐槽,例如:{ \"url\" : \"https://github.com/owner/project/issues\", \"email\" : \"project@hostname.com\"}
url和email可以任意填或不填,如果只填⼀个,可以直接写成⼀个字符串⽽不是对象。如果填写了url,npm bugs命令会使⽤这个url。
license和⽤户相关的属性: author, contributors\"author\"是⼀个码农, \"contributors\"是⼀个码农数组。 \"person\"是⼀个有⼀些描述属性的对象,如下 like this:{ \"name\" : \"Barney Rubble\", \"email\" : \"b@rubble.com\"
, \"url\" : \"http://barnyrubble.tumblr.com/\"}
files\"files\"属性的值是⼀个数组,内容是模块下⽂件名或者⽂件夹名,如果是⽂件夹名,则⽂件夹下所有的⽂件也会被包含进来(除⾮⽂件被另⼀些配置排除了)
你也可以在模块根⽬录下创建⼀个\".npmignore\"⽂件(windows下⽆法直接创建以\".\"开头的⽂件,使⽤linux命令⾏⼯具创建如git bash),写在这个⽂件⾥边的⽂件即便被写在files属性⾥边也会被排除在外,这个⽂件的写法\".gitignore\"类似。
mainmain属性指定了程序的主⼊⼝⽂件。意思是,如果你的模块被命名为foo,⽤户安装了这个模块并通过require(\"foo\")来使⽤这个模块,那么require返回的内容就是main属性指定的⽂件中 module.exports指向的对象。
它应该指向模块根⽬录下的⼀个⽂件。对⼤对数模块⽽⾔,这个属性更多的是让模块有⼀个主⼊⼝⽂件,然⽽很多模块并不写这个属性。
bin很多模块有⼀个或多个需要配置到PATH路径下的可执⾏模块,npm让这个⼯作变得⼗分简单(实际上npm本⾝也是通过bin属性安装为⼀个可执⾏命令的)
如果要⽤npm的这个功能,在package.json⾥边配置⼀个bin属性。bin属性是⼀个已命令名称为key,本地⽂件名称为value的map如下:{ \"bin\" : { \"myapp\" : \"./cli.js\" } }
模块安装的时候,若是全局安装,则npm会为bin中配置的⽂件在bin⽬录下创建⼀个软连接(对于windows系统,默认会在
C:\\Users\ame\\AppData\\Roaming\\npm⽬录下),若是局部安装,则会在项⽬内的./node_modules/.bin/⽬录下创建⼀个软链接。因此,按上⾯的例⼦,当你安装myapp的时候,npm就会为cli.js在/usr/local/bin/myapp路径创建⼀个软链接。
如果你的模块只有⼀个可执⾏⽂件,并且它的命令名称和模块名称⼀样,你可以只写⼀个字符串来代替上⾯那种配置,例如:{ \"name\": \"my-program\", \"version\": \"1.2.5\"
, \"bin\": \"./path/to/program\" }作⽤和如下写法相同:{ \"name\": \"my-program\"
, \"version\": \"1.2.5\"
, \"bin\" : { \"my-program\" : \"./path/to/program\" } }
man制定⼀个或通过数组制定⼀些⽂件来让linux下的man命令查找⽂档地址。
如果只有⼀个⽂件被指定的话,安装后直接使⽤man+模块名称,⽽不管man指定的⽂件的实际名称。例如:{ \"name\" : \"foo\", \"version\" : \"1.2.3\"
, \"description\" : \"A packaged foo fooer for fooing foos\", \"main\" : \"foo.js\"
, \"man\" : \"./man/doc.1\"}
通过man foo命令会得到 ./man/doc.1 ⽂件的内容。
如果man⽂件名称不是以模块名称开头的,安装的时候会给加上模块名称前缀。因此,下⾯这段配置:{ \"name\" : \"foo\", \"version\" : \"1.2.3\"
, \"description\" : \"A packaged foo fooer for fooing foos\", \"main\" : \"foo.js\"
, \"man\" : [ \"./man/foo.1\}
会创建⼀些⽂件来作为man foo和man foo-bar命令的结果。
man⽂件必须以数字结尾,或者如果被压缩了,以.gz结尾。数字表⽰⽂件将被安装到man的哪个部分。{ \"name\" : \"foo\"
, \"version\" : \"1.2.3\"
, \"description\" : \"A packaged foo fooer for fooing foos\", \"main\" : \"foo.js\"
, \"man\" : [ \"./man/foo.1\}
会创建 man foo 和 man 2 foo 两条命令。
directoriesdirectories.lib
告诉⽤户模块中lib⽬录在哪,这个配置⽬前没有任何作⽤,但是对使⽤模块的⼈来说是⼀个很有⽤的信息。
directories.bin
如果你在这⾥指定了bin⽬录,这个配置下⾯的⽂件会被加⼊到bin路径下,如果你已经在package.json中配置了bin⽬录,那么这⾥的配置将不起任何作⽤。
directories.man
指定⼀个⽬录,⽬录⾥边都是man⽂件,这是⼀种配置man⽂件的语法糖。
directories.doc
在这个⽬录⾥边放⼀些markdown⽂件,可能最终有⼀天它们会被友好的展现出来(应该是在npm的⽹站上)
directories.example
放⼀些⽰例脚本,或许某⼀天会有⽤ - -!
repository指定⼀个代码存放地址,对想要为你的项⽬贡献代码的⼈有帮助。像这样:\"repository\" : { \"type\" : \"git\"
, \"url\" : \"https://github.com/npm/npm.git\" }
\"repository\" : { \"type\" : \"svn\"
, \"url\" : \"https://v8.googlecode.com/svn/trunk/\" }
若你的模块放在GitHub, GitHub gist, Bitbucket, or GitLab的仓库⾥,npm install的时候可以使⽤缩写标记来完成:\"repository\": \"npm/npm\"\"repository\": \"gist:11081aaa281\"
\"repository\": \"bitbucket:example/repo\"\"repository\": \"gitlab:another/repo\"
scriptsconfig⽤来设置⼀些项⽬不怎么变化的项⽬配置,例如port等。⽤户⽤的时候可以使⽤如下⽤法:
http.createServer(...).listen(process.env.npm_package_config_port){ \"name\" : \"foo\"
, \"config\" : { \"port\" : \"8080\" } }
dependenciesversion 精确匹配版本
>version 必须⼤于某个版本>=version ⼤于等于 ~version \"约等于\",具体规则详见semver⽂档^version \"兼容版本\"具体规则详见semver⽂档1.2.x 仅⼀点⼆点⼏的版本 http://... 见下⾯url作为denpendencies的说明任何版本\"\" 空字符,和*相同 version1 - version2 相当于 >=version1 <=version2.range1 || range2 范围1和范围2满⾜任意⼀个都⾏git... 见下⾯git url作为denpendencies的说明user/repo See 见下⾯GitHub仓库的说明tag 发布的⼀个特殊的标签,见npm-tag的⽂档path/path/path 见下⾯本地模块的说明下⾯的写法都是可以的:{ \"dependencies\" : { \"foo\" : \"1.0.0 - 2.9999.9999\" , \"bar\" : \">=1.0.2 <2.1.2\" , \"baz\" : \">1.0.2 <=2.3.4\" , \"boo\" : \"2.0.1\" , \"qux\" : \"<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0\" , \"asd\" : \"http://asdf.com/asdf.tar.gz\" , \"til\" : \"~1.2\" , \"elf\" : \"~1.2.3\" , \"two\" : \"2.x\" , \"thr\" : \"3.3.x\" , \"lat\" : \"latest\" , \"dyl\" : \"file:../dyl\" }} URLs as Dependencies在版本范围的地⽅可以写⼀个url指向⼀个压缩包,模块安装的时候会把这个压缩包下载下来安装到模块本地。 Git URLs as DependenciesGit url可以像下⾯⼀样: git://github.com/user/project.git#commit-ishgit+ssh://user@hostname:project.git#commit-ishgit+ssh://user@hostname/project.git#commit-ishgit+http://user@hostname/project/blah.git#commit-ishgit+https://user@hostname/project/blah.git#commit-ish commit-ish 可以是任意标签,哈希值,或者可以检出的分⽀,默认是master分⽀。 GitHub URLs⽀持github的 username/modulename 的写法,#后边可以加后缀写明分⽀hash或标签:{ \"name\": \"foo\ \"version\": \"0.0.0\ \"dependencies\": { \"express\": \"visionmedia/express\ \"mocha\": \"visionmedia/mocha#4727d357ea\" }} Local Pathsnpm2.0.0版本以上可以提供⼀个本地路径来安装⼀个本地的模块,通过npm install xxx --save 来安装,格式如下:../foo/bar~/foo/bar./foo/bar/foo/bar package.json ⽣成的相对路径如下:{ \"name\": \"baz\ \"dependencies\": { \"bar\": \"file:../foo/bar\" }} 这种属性在离线开发或者测试需要⽤npm install的情况,⼜不想⾃⼰搞⼀个npm server的时候有⽤,但是发布模块到公共仓库时不应该使⽤这种属性。 devDependencies如果有⼈想要下载并使⽤你的模块,也许他们并不希望或需要下载⼀些你在开发过程中使⽤的额外的测试或者⽂档框架。在这种情况下,最好的⽅法是把这些依赖添加到devDependencies属性的对象中。 这些模块会在npm link或者npm install的时候被安装,也可以像其他npm配置⼀样被管理,详见npm的config⽂档。 对于⼀些跨平台的构建任务,例如把CoffeeScript编译成JavaScript,就可以通过在package.json的script属性⾥边配置prepublish脚本来完成这个任务,然后需要依赖的coffee-script模块就写在devDependencies属性种。例如: { \"name\": \"ethopia-waza\ \"description\": \"a delightfully fruity coffee varietal\ \"version\": \"1.2.3\ \"devDependencies\": { \"coffee-script\": \"~1.6.3\" }, \"scripts\": { \"prepublish\": \"coffee -o lib/ -c src/waza.coffee\" }, \"main\": \"lib/waza.js\"} prepublish脚本会在发布之前运⾏,因此⽤户在使⽤之前就不⽤再⾃⼰去完成编译的过程了。在开发模式下,运⾏npm install也会执⾏这个脚本(见npm script⽂档),因此可以很⽅便的调试。 peerDependencies有时候做⼀些插件开发,⽐如grunt等⼯具的插件,它们往往是在grunt的某个版本的基础上开发的,⽽在他们的代码中并不会出现require(\"grunt\")这样的依赖,dependencies配置⾥边也不会写上grunt的依赖,为了说明此模块只能作为插件跑在宿主的某个版本范围下,可以配置peerDependencies:{ \"name\": \"tea-latte\ \"version\": \"1.3.5\ \"peerDependencies\": { \"tea\": \"2.x\" }} 上⾯这个配置确保再npm install的时候tea-latte会和2.x版本的tea⼀起安装,⽽且它们两个的依赖关系是同级的:├── tea-latte@1.3.5 └── tea@2.2.0 这个配置的⽬的是让npm知道,如果要使⽤此插件模块,请确保安装了兼容版本的宿主模块。 bundledDependencies上⾯的单词少个d,写成bundleDependencies也可以。指定发布的时候会被⼀起打包的模块。 optionalDependencies如果⼀个依赖模块可以被使⽤, 同时你也希望在该模块找不到或⽆法获取时npm继续运⾏,你可以把这个模块依赖放到 optionalDependencies配置中。这个配置的写法和dependencies的写法⼀样,不同的是这⾥边写的模块安装失败不会导致npm install失败。当然,这种模块就需要你⾃⼰在代码中处理模块确实的情况了,例如:try { var foo = require('foo') var fooVersion = require('foo/package.json').version} catch (er) { foo = null} if ( notGoodFooVersion(fooVersion) ) { foo = null} // .. then later in your program ..if (foo) { foo.doFooThings()} optionalDependencies 中的配置会覆盖dependencies中的配置,最好只在⼀个地⽅写。 engines你可以指定项⽬运⾏的node版本范围,如下: { \"engines\" : { \"node\" : \">=0.10.3 <0.12\" } } 和dependencies⼀样,如果你不指定版本范围或者指定为*,任何版本的node都可以。也可以指定⼀些npm版本可以正确的安装你的模块,例如: { \"engines\" : { \"npm\" : \"~1.0.20\" } } 要注意的是,除⾮你设置了engine-strict属性,engines属性是仅供参考的。 engineStrict注意:这个属性已经弃⽤,将在npm 3.0.0 版本⼲掉。 os可以指定你的模块只能在哪个操作系统上跑:\"os\" : [ \"darwin\ 也可以指定⿊名单⽽不是⽩名单:\"os\" : [ \"!win32\" ] 服务的操作系统是由process.platform来判断的,这个属性允许⿊⽩名单同时存在,虽然没啥必要这样搞... cpu限制模块只能在某某cpu架构下运⾏\"cpu\" : [ \"x64\同样可以设置⿊名单:\"cpu\" : [ \"!arm\cpu架构通过 process.arch 判断 preferGlobal如果您的软件包主要⽤于安装到全局的命令⾏应⽤程序,那么该值设置为true ,如果它被安装在本地,则提供⼀个警告。实际上该配置并没有阻⽌⽤户把模块安装到本地,只是防⽌该模块被错误的使⽤引起⼀些问题。 private如果这个属性被设置为true,npm将拒绝发布它,这是为了防⽌⼀个私有模块被⽆意间发布出去。如果你只想让模块被发布到⼀个特定的npm仓库,如⼀个内部的仓库,可与在下⾯的publishConfig中配置仓库参数。 publishConfig这个配置是会在模块发布时⽤到的⼀些值的集合。如果你不想模块被默认被标记为最新的,或者默认发布到公共仓库,可以在这⾥配置tag或仓库地址。 DEFAULT VALUESnpm设置了⼀些默认参数,如: \"scripts\": {\"start\": \"node server.js\ 如果模块根⽬录下有⼀个server.js⽂件,那么npm start会默认运⾏这个⽂件。\"scripts\":{\"preinstall\": \"node-gyp rebuild\ 如果模块根⽬录下有binding.gyp, npm将默认⽤node-gyp来编译preinstall的脚本\"contributors\": [...] 若模块根⽬录下有AUTHORS ⽂件,则npm会按Name (url)格式解析每⼀⾏的数据添加到contributors中,可以⽤#添加⾏注释 参考⽂档列表()semver(7)npm-init(1)npm-version(1)npm-config(1)npm-config(7) npm-help(1)npm-faq(7)npm-install(1)npm-publish(1)npm-rm(1) 因篇幅问题不能全部显示,请点此查看更多更全内容