zoukankan      html  css  js  c++  java
  • 从npm cache clean --force使用来浅析npm模块的安装机制

    一、解决 This is probably not a problem with npm. There is likely additional logging output above

      在执行 npm run serve 运行项目的时候报错:

    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! lianshan@2.0.0 serve: `vue-cli-service serve`
    npm ERR! Exit status 1
    npm ERR!
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /Users/.../_logs/..._10_01_084Z-debug.log

      如果出现这种报错情况,一般需要重新安装 node_modules 文件夹中的内容,但是在安装前,要把之前的内容都清空掉。

      其实大多数的主要问题是 package-lock.json 这个文件,一般使用 1、2、4 步就够了,如果不行在重新 1、2、3、4 步,因为使用了 第3步,在 $ npm install 安装会要点时间,相对较慢。

      解决步骤如下:

    1、首先删除 node_modules,可以命令行删除,也可以手动右键删除文件夹。

    2、删除 package-lock.json 文件

    3、运行命令

    npm cache clean --force

    4、重新安装依赖:npm install

    二、npm模块安装机制

    1、npm install 安装之前,npm install会先检查node_modules目录之中是否已经存在指定模块。如果存在,就不再重新安装了,即使远程仓库已经有了一个新版本,也是如此。

      如果你希望,一个模块不管是否安装过,npm 都要强制重新安装,可以使用-f--force参数。

    npm install <packageName> --force

    2、如果想更新已安装模块,就要用到npm update命令。

    npm update <packageName>

      它会先到远程仓库查询最新版本,然后查询本地版本。如果本地版本不存在,或者远程版本较新,就会安装。

    3、那么npm update命令怎么知道每个模块的最新版本呢?

      答案是 npm 模块仓库提供了一个查询服务,叫做 registry 。以 npmjs.org 为例,它的查询服务网址是 https://registry.npmjs.org/

      这个网址后面跟上模块名,就会得到一个 JSON 对象,里面是该模块所有版本的信息。比如,访问 https://registry.npmjs.org/react,就会看到 react 模块所有版本的信息。

      它跟下面命令的效果是一样的。

    npm view react
    
    // npm view 的别名
    npm info react
    npm show react
    npm v react

      registry 网址的模块名后面,还可以跟上版本号或者标签,用来查询某个具体版本的信息。比如, 访问 https://registry.npmjs.org/react/v0.14.6 ,就可以看到 React 的 0.14.6 版。

      返回的 JSON 对象里面,有一个dist.tarball属性,是该版本压缩包的网址。

    dist: {
      shasum: '2a57c2cf8747b483759ad8de0fa47fb0c5cf5c6a',
      tarball: 'http://registry.npmjs.org/react/-/react-0.14.6.tgz' 
    },

      到这个网址下载压缩包,在本地解压,就得到了模块的源码。npm installnpm update命令,都是通过这种方式安装模块的。

    4、缓存目录

      npm installnpm update命令,从 registry 下载压缩包之后,都存放在本地的缓存目录。

      这个缓存目录,在 Linux 或 Mac 默认是用户主目录下的.npm目录,在 Windows 默认是%AppData%/npm-cache。通过配置命令,可以查看这个目录的具体位置。

    PS D:modb-frontmodb-front> npm config get cache
    D:Program
    odejs
    ode_cache

      浏览一下这个目录,会看到里面存放着大量的模块,储存结构是{cache}/{name}/{version}

    npm cache ls react
    
    ~/.npm/react/react/0.14.6/
    ~/.npm/react/react/0.14.6/package.tgz
    ~/.npm/react/react/0.14.6/package/
    ~/.npm/react/react/0.14.6/package/package.json

      每个模块的每个版本都有一个自己的子目录,里面是代码的压缩包package.tgz文件,以及一个描述文件package/package.json

      除此之外,还会生成一个{cache}/{hostname}/{path}/.cache.json文件。比如,从 npm 官方仓库下载 react 模块的时候,就会生成registry.npmjs.org/react/.cache.json文件。

      这个文件保存的是,所有版本的信息,以及该模块最近修改的时间和最新一次请求时服务器返回的 ETag 。

    {
      "time":{
        "modified":"2016-01-06T23:52:45.571Z",
        // ...
      },
      "_etag":""7S37I0775YLURCFIO8N85FO0F""
    }

      对于一些不是很关键的操作(比如npm searchnpm view),npm会先查看.cache.json里面的模块最近更新时间跟当前时间的差距,是不是在可接受的范围之内。如果是的,就不再向远程仓库发出请求,而是直接返回.cache.json的数据。

    5、模块的安装过程

      Node模块的安装过程是这样的:

    1、发出npm install命令

    2、npm 向 registry 查询模块压缩包的网址

    3、下载压缩包,存放在~/.npm目录

    4、解压压缩包到当前项目的node_modules目录

      注意,一个模块安装以后,本地其实保存了两份。一份是~/.npm目录下的压缩包,另一份是node_modules目录下解压后的代码。

      但是,运行npm install的时候,只会检查node_modules目录,而不会检查~/.npm目录。也就是说,如果一个模块在~/.npm下有压缩包,但是没有安装在node_modules目录中,npm 依然会从远程仓库下载一次新的压缩包。

      这种行为固然可以保证总是取得最新的代码,但有时并不是我们想要的。最大的问题是,它会极大地影响安装速度。即使某个模块的压缩包就在缓存目录中,也要去远程仓库下载,这怎么可能不慢呢?

      另外,有些场合没有网络(比如飞机上),但是你想安装的模块,明明就在缓存目录之中,这时也无法安装。

    6、--cache-min 参数

      为了解决这些问题,npm 提供了一个--cache-min参数,用于从缓存目录安装模块。

      --cache-min参数指定一个时间(单位为分钟),只有超过这个时间的模块,才会从 registry 下载。

    npm install --cache-min 9999999 <package-name>

      上面命令指定,只有超过999999分钟的模块,才从 registry 下载。实际上就是指定,所有模块都从缓存安装,这样就大大加快了下载速度。

    参考文章:http://www.ruanyifeng.com/blog/2016/01/npm-install.html

  • 相关阅读:
    C# 学习历程——接口
    C# 学习历程——类的封装,继承与多态
    C# 学习历程——C#基础
    C# 学习历程——Hello World
    python(14)---发邮件、写日志、操作redis数据库
    python(13)——内置函数
    python(12)---导入模块
    HTML操作之DOM操作
    HTML基础之CSS
    HTML基础之HTML标签
  • 原文地址:https://www.cnblogs.com/goloving/p/14593761.html
Copyright © 2011-2022 走看看