zoukankan      html  css  js  c++  java
  • 浅析nodejs中的package.json和package-lock.json作用

    一、package.json与package-lock.json文件的作用

    1、package.json文件记录了你项目中所依赖的所有模块(只记录主模块)。

      当你执行 npm install 的时候,nodeJS 会先从 package.json 文件中读取所有 dependencies 信息,然后根据 dependencies 中的信息与 node_modules 中的模块进行对比,没有的直接下载,已有的检查更新(新版的nodejs不会更新,因为有package-lock.json文件)。

      另外,package.json文件只记录你通过npm install方式安装的模块信息,而这些模块所依赖的其他子模块的信息不会记录。

    2、package-lock.json文件锁定所有模块的版本号,包括主模块和所有依赖子模块。

      当你执行 npm install 的时候,nodeJS 从 package.json 文件读取模块名称,从 package-lock.json 文件中获取版本号,然后进行下载或者更新。

      因此,正因为有了package-lock.json文件锁定版本号,所以当你执行npm install的时候,node不会自动更新package.json文件中的模块,必须用npm install packagename(自动更新小版本号)或者npm install packagename@x.x.x(指定版本号)来进行安装才会更新,package-lock.json文件中的版本号也会随着更新。

      附:当 package.json 与 package-lock.json 都不存在时,执行 npm install,nodeJS 会重新生成 package-lock.json 文件,然后把 node_modules 中的模块信息全部记入 package-lock.json 文件,但不会生成 package.json 文件,此时,你可以通过 npm init --yes 来生成 package.json 文件。

    二、使用package-lock.json的必要性

    1、遇到问题

      之前,在项目开发过程中遇到一个问题,同一个项目第一次 cnpm install 的时候还可以启动,过一段时间,把node_modules删掉,重新cnpm install,发现项目启动报错了。奇怪,项目代码和之前一样,一点都没改动。

      查其原因,发现是package.json文件的依赖模块版本号没有固定,如 "roadhog": "^2.5.0-beta.4"。这里有个 ^,安装的时候会安装2.x.x的最新版本,因为这期间该模块有更新,导致两次install的版本不一样,所以项目报错了。

    2、解决办法

      第一个想到的是我把该模块写死不就行了 "roadhog": "2.5.0-beta.4"。但是仔细一想,仍会有问题。npm最方便的地方,是它可以帮我们管理依赖,自动下载依赖。意思是假如我们依赖roadhog,roadhog又依赖模块A、B等,我们安装roadhog时,npm会自动帮我们安装好roadhog依赖的模块A、B等。我们把roadhog锁死了,但是其引用的A模块仍用的是^括号写法(即没有锁死版本),所以假如A模块更新了,仍可能会出现之前类似的问题。那么该怎么进行版本控制呢。

      所以我们要对整个依赖树做锁定,那前后编译出来的应用版本就不会存在两次安装版本不一的问题了。

      这就引出了我们的 package-lock.json 文件。它的产生就是来对整个依赖树进行版本固定的(锁死)

    3、package-lock.json定义

      引用官方解释:package-lock.json 它会在 npm 更改 node_modules 目录树或者 package.json 时自动生成的,它准确的描述了当前项目 npm 包的依赖树,并且在随后的安装中会根据 package-lock.json 来安装,保证是相同的一个依赖树,不考虑这个过程中是否有某个依赖有小版本的更新。

    4、package-lock.json生成

      默认,当我们在一个项目中npm install时候(前提该项目有package.json文件),安装完成后,会自动生成一个package-lock.json文件(位置和之前的package.json文件同级)。该文件里面记录了package.json依赖的模块,以及依赖的依赖。并且给每个依赖标明了版本, 获取地址和哈希值, 使得每次安装都会出现相同的结果,不管你在什么机器上面或什么时候安装。

      当我们下次再npm install时候,npm发现如果项目中有package-lock.json文件,会根据package-lock.json里的内容来处理和安装依赖而不再根据package.json。

      如果 package-lock.json 已经生成,我再次更新 package.json 某个模块版本(包括手动更改package.json某个版本号,然后重新npm install或者类似npm install antd@3.15.0来更新某个模块),package-lock.json都会自动更新到之前设置的版本,所以不用担心 package.json 更新了,package-lock.json 还是旧的问题。npm v5.1.0之前存在该问题,npm v5.1.0以后不存在该问题。此同步功能是作为npm v5.1.0的一部分发布的,该版本于2017年7月5日上线。

    5、cnpm不支持package-lock.json

      注意:使用cnpm install时候,并不会生成package-lock.json文件,网上搜cnpm维护者似乎并不打算支持该功能,具体大家可以去搜下。

      cnpm install 的时候,就算你项目中有 package-lock.json 文件,cnpm 也不会识别,仍会根据 package.json 来安装。所以这就是为什么之前你用 npm 安装产生了package-lock.json,后面的人用 cnpm 来安装,可能会跟你安装的依赖包不一致,这是因为 cnpm 不受 package-lock.json 影响,只会根据package.json进行下载。

    三、package.json中 ^、~ 的区别

    "dependencies": {
        "vue": "^2.5.2",
        "vue-router": "^3.0.1"
    },

      指定版本号:

    1、指定版本。比如:"vue": "2.5.2",表示安装2.5.2的版本

    2、波浪号 ~ + 指定版本。比如: "vue": "~2.5.2",表示安装2.5.x的最新版本(不低于2.5.2),但是不安装2.6.x,也就是说安装时不改变大版本号和次要版本号

    3、^ + 指定版本。比如:"vue": "^2.5.2",表示安装2.5.2及以上的版本,但是不安装3.0.0,也就是说安装时不改变大版本号。

      简言之就是:什么都不加是指定版本;波浪号 ~ 是不改变次要版本,但升级小版本;^ 是不改变大版本,但升级次要版本。

    四、package.json 文件

    1、package.json 文件作用

      package.json 文件其实就是对项目或者模块包的描述,里面包含许多元信息。比如项目名称,项目版本,项目执行入口文件,项目贡献者等等。

      npm install 命令会根据这个文件下载所有依赖模块。

    2、package.json 文件创建

      package.json 文件创建有两种方式,手动创建或者自动创建。

    (1)手动创建:直接在项目根目录新建一个 package.json 文件,然后输入相关的内容。

    (2)自动创建:也是在项目根目录下执行 npm init,然后根据提示一步步输入相应的内容完成后即可自动创建。

    3、package.json 文件配置说明

    name:项目/模块名称,长度必须小于等于214个字符,不能以"."(点)或者"_"(下划线)开头,不能包含大写字母。
    version:项目版本。
    author:项目开发者,它的值是你在https://npmjs.org网站的有效账户名,遵循“账户名<邮件>”的规则。
    description:项目描述,是一个字符串。它可以帮助人们在使用npm search时找到这个包。
    keywords:项目关键字,是一个字符串数组。它可以帮助人们在使用npm search时找到这个包。
    private:是否私有,设置为 true 时,npm 拒绝发布。
    license:软件授权条款,让用户知道他们的使用权利和限制。
    bugs:bug 提交地址。
    contributors:项目贡献者 。
    repository:项目仓库地址。
    homepage:项目包的官网 URL。
    dependencies:生产环境下,项目运行所需依赖。
    devDependencies:开发环境下,项目所需依赖。
    scripts:执行 npm 脚本命令简写,比如 “start”: “react-scripts start”, 执行 npm start 就是运行 “react-scripts start”。
    bin:内部命令对应的可执行文件的路径。
    main:项目默认执行文件,比如 require(‘webpack’);就会默认加载 lib 目录下的 webpack.js 文件,如果没有设置,则默认加载项目跟目录下的 index.js 文件。
    module:是以 ES Module(也就是 ES6)模块化方式进行加载,因为早期没有 ES6 模块化方案时,都是遵循 CommonJS 规范,而 CommonJS 规范的包是以 main 的方式表示入口文件的,为了区分就新增了 module 方式,但是 ES6 模块化方案效率更高,所以会优先查看是否有 module 字段,没有才使用 main 字段。
    eslintConfig:EsLint 检查文件配置,自动读取验证。
    engines:项目运行的平台。
    browserslist:供浏览器使用的版本列表。
    style:供浏览器使用时,样式文件所在的位置;样式文件打包工具parcelify,通过它知道样式文件的打包位置。
    files:被项目包含的文件名数组。

  • 相关阅读:
    【计算机视觉】OpenCV篇(2)
    【计算机视觉】OpenCV篇(1)
    傅立叶分析与小波分析整理
    极简Python DeBug工具——PySnooper
    透过SourceTree再谈Git
    佳文赏析:How to uninstall Linux
    AI佳作解读系列(四)——数据增强篇
    AI佳作解读系列(三)——深度学习中的合成数据研究
    java基础 序列化反序列化流 实现Serializable 接口 自动装载序列号到对象文本文件如修改不能反序列化对象文本,除非自定义long型常量 打印流
    java基础IO流 复制键盘录入的目录,复制其中的.java文件到指定目录,指定目录中有重名,则改名 对加密文件计算字母个数
  • 原文地址:https://www.cnblogs.com/goloving/p/14602743.html
Copyright © 2011-2022 走看看