package.json学习笔记

265 阅读3分钟

每个项目的根目录下,一般都有一个 package.json 文件,定义了这个项目所需的各种模块,以及项目的配置信息(比如:名称、版本、许可证、依赖等元数据)。npm install 命令根据这个配置文件,自动下载所需的模块,也就是配置项目所需的运行和开发环境。


本文旨在记录个人对 package.json 文件常用字段的理解,以下会逐个记录 package.json 中出现的字段

name 名称

  • name: 项目名称。
    {
        "name": "my-project"
    }
    

version 版本

  • version: 项目版本。
    // version 的格式为:大版本.次版本.小版本
    {
        "version": "v1.0.0"
    }
    

description 描述

  • description: 项目描述。
    {
        "description": "This is my first project"
    }
    

keywords 关键字

  • keywords: 项目关键字,是一个字符串数组,会在 npm search 当中列出,便于别人发现此项目。
    {
        "keywords": [
            "first-project",
            "test",
            "cli"
        ]
    }
    

author 作者

  • author: 人员字段,创建人,作者。
    
    {
        // 此字段可以是对象
        "author": {
            "name": "aidenxiong",
            "email": "aiden_xiong@163.com",
            "url": "https://github.com/aidening"
        },
        // 也可以是字符串
        "author": "aidenxiong <aiden_xiong@163.com> (https://github.com/aidening)"
    }
    

scripts 脚本指令

  • scripts: 可执行的脚本指令。
    {
        "scripts": {
            "test: "npx jest",
            "preversion": "npm run changelog",
            "changelog": "conventinal-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md"
        }
    }
    

bin 可执行文件

  • bin: 可执行文件。在安装时,npm 会将该文件符号链接到 prefix/bin 全局安装 或者 ./node_modules/.bin/ 本地安装。例如:下方例子会创建一个 cli.js 脚本到 /use/local/bin/ifcloud .

    注意:被 bin 引用的文件必须是以 #! /usr/bin/env node 开头的文件

    {
        // 可以是对象
        "bin": {
            // ifcloud 可以理解为 执行 cli.js 文件的别名
            "ifcloud": "./cli/cli.js"
        },
        // 可以是字符串
        "bin": "./cli/cli.js"
    }
    

engines 引擎要求

  • engines: 指定适用的节点版本。
    {
        "engines": {
            "node": ">=0.10.3 <0.12",
            "npm": "~1.0.20"
        }
    }
    

files 文件集

  • files: 文件。描述的是,当项目作为依赖项安装时要包含的条目。如果省略 files 数组,则除了自动排除的文件之外的所有内容都将包含在您的发布中。可以理解为:files 数组内的文件都是 白名单
    {
        // 数组
        "files: [
            "lib",
            "bin",
            "esc",
            "src"
        ]
    }
    

main 入口

  • main: 模块ID,是程序的主要入口点。例如:包名为 foo,用户安装了它,然后银引用 require("foo"),那么主模块的导出对象将被返回。
    {
        "main": "./index.js"
    }
    

license 许可证

  • license: 许可证。通过这个许可证,告知可以如何适用这个包以及对这个包的限制。许可证的值应该选择 OSD批准的一种。
    {
        "license": "MIT"
    }
    

repository 仓库

  • repository: 代码 git 仓库(存储库)。
    {
        // 可以是对象
        "repository": {
            "type": "git",
            "url": "https://github.com/aidening/ifcloud-package-cli.git"
        },
        // 可以是字符串
        "repository": "https://github.com/aidening/ifcloud-package-cli.git"
    }
    

dependencies 依赖

  • dependencies: 依赖。

    注意:不要在 dependencies 对象中放置 测试工具 或 转移器

    {
        "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"
        }
    }
    

devDependencies 开发依赖

  • devDependencies: 开发依赖。在执行时 npm linknpm install 从包的根目录安装,并且可以像任何其他 npm 配置参数一样进行管理。
    {
        "devDependencies": {
            "antd": "^4.0.0",
            "formily": "^1.0.21",
            "@commitlint/cli": "^11.0.0",
            "@commitlint/config-conventional": "^11.0.0", 
            "@types/jest": "^26.0.15",
            "conventional-changelog-cli": "^2.1.0",
            "husky": "^4.3.0",
            "jest": "^26.6.0",
            "prettier": "^2.1.2",
            "pretty-quick": "^3.1.0"
        }
    }
    

private 私有包

  • private: 私有的。若 private: true ,那么 npm 将拒绝发布。这是一种防止意外发布私有存储库的方法。
    {
        "private": true
    }
    

config 变量配置

  • config: 添加命令行的环境变量。
    {
        "config": {
            "api-server": "192.168.120.1",
            "port": "32630",
        }
    }
    

workspaces 工作空间

  • workspaces: 工作空间,文件模式数组。npm 官方文档是这么解释的:描述了本地文件系统内的位置,安装客户端是应该查找这些位置,以找到需要的符号链接到顶级文件夹的每个工作区的 node_modules

    个人理解:workspaces 的作用就是将其包含的 package 作为需要解析的文件,比如,yarn install 时就会去查找这些 packagepackage.json 并进行 自动化链接,即 自动 npm link 到顶层的 node_modules。在 Monorepo 多包管理模式下常常会用到 workspaces 字段。

    注意:在使用 yarn workspaces 时,必须将 private 属性设置为 true

    Monorepo 中的所有依赖都会存储在 根目录 下的 node_modules

    {
        // 数组
        "workspaces": [
            "package-a",
            "package-b"
        ],
        // 对象
        "workspaces": {
            "packages": [ "package-a", "package-b" ],
            
        }
    }
    
    

    yarn workspaces 新增了一个属性 nohoist。以下对 nohoist 做简单的说明:

    Monorepo 当中,我们使用了 workspaces 属性之后,所有位于 workspaces 属性下所有的 package 自身的依赖,都会被提升到最外层的 node_modules 之中,但是实际使用当中会存在这样一个问题:

    (1) package-a 有一个 formily@^1.0.0 版本的依赖
    (2) package-b 有一个 formily@^2.0.0 版本的依赖
    (3) formily@^1.0.0formily@^2.0.0 版本内部依赖有很多冲突

    这个时候,我们可以使用 nohoist 字段,被 nohoist 包裹的 package 安装依赖时,包里依赖不会被提升到顶层的 node_modules 目录下。
    nohoist 语法如下:

    {
        "workspaces: {
           "packages: [ "package-a", "package-b", "package-c" ],
           // 这是在根级别指定,package-a 和 package-b 的依赖不安装到 根目录下的 node_modules
           "nohoist": [
               // 必须双重指定每个包
               "**/package-a",
               "**/package-a/**",
               // 必须双重指定每个包
               "**/package-b",
               "**/package-b/**",
           ]
        }
    }
    
    {
        // 还有一种方式,是直接在 package 内部修改即可
        "workspaces: {
           "nohoist": ["**"]
        }
    }
    

    注意:在修改了相关的设置之后,需要删除所有的跟 nohoist 相关的文件夹(即 根目录和各 package 目录下的node_modules

       # delete node_modules on linux
       rm -rf ./packages/*/node_modules
       rm -rf ./node_modules
    
       # install again
       yarn install --check-files
    

Custom Properties 自定义属性

  • Custom Properties: package.json 还可以作用在包特定的命令上,例如:babeleslintjesthusky 等等。

参考文章:

npm - package.json

package.json 文件

lerna-cli

工作区仍在起吊的nohoist