别瞎删package-lock.json了

2023-05-16

作者:wuwhs

原文:https://segmentfault.com/a/1190000039684460

0. 前言

看完本文,你将从整体了解依赖版本锁定原理,package-lock.json 或 yarn.lock的重要性。首先要从最近接连出现两起有关 npm 安装 package.json 中依赖包,由于依赖包版本更新 bug 造成项目出错问题说起。

事件一:新版本依赖包本身 bug

项目本地打包正常,但是线上使用 Jenkins 完成 DevOps 交付流水线打包出错问题。报出如下错误:

**17:15:32**  ERROR in ./node_modules/clipboard/dist/clipboard.js
**17:15:32**  Module build failed (from ./node_modules/babel-loader/lib/index.js):
**17:15:32**  Error: Couldn't find preset "@babel/env" relative to directory "/app/workspace/SIT/node_modules/clipboard"

显示错误原因是 clipboard 插件没有安装 @babel/env 预设(preset)。明显这个是插件问题了,去官方库 `clipboard`[1] 查看源码发现该库依赖包很少,大部分是原生实现。再看 issue 别人有没有出现同样的问题,目前来看还没有人提出。以此推断可能是插件本身的 "问题" 了。

但是我本地项目打包正常,线上的出错,可能由于本地版本和线上版本不一致导致(某个小版本出现的 bug)的。通过查看package.json 配置的 clipboard: "^2.0.4",线上实际安装版本是 2.0.7,而我本地实际安装版本是 2.0.6因此定位到 2.0.7 出现的 “问题”。

由于是插件本身“问题”,我的临时解决办法是锁定到 2.0.4 版本,也就是 clipboard: "2.0.4",后面加上 package-lock.json

打破沙锅问到底既然“问题”已经定位到了 2.0.7 版本,进一步通过对比此次版本提交文件内容差异,发现 .babelrc 文件用到的 preset 是 env

2.0.7 版本用的是 @bable/env,将 babel 更新到了 7!

问题基本定位到了,这里就顺便给作者提了一个 `issues`[2]

事件二:依赖包的新版插件 bug

一直正常使用的 braft-editor 优秀的富文本编辑器插件,最近在其他小伙伴电脑或者在我本地电脑重新部署项目,启动后发现 toHtml() 方法获取富文本 html 内容总是空!

历史版本是正常的,猜测可能又是版本更新造成。同样的,去官方库 braft\-editor[3]看看 issues 别人有没有遇到同样的问题。果然这次有,原因是它的依赖包 `draft-js`[4]更新后的问题,具体的看这个 `issues`[5]

这个是由于插件的依赖包更新出现的问题,直接去锁定当前插件没有作用,不会对它的依赖包产生约束(依赖包还是会去下载最新版本的包)。我的临时解决办法是尝试将版本回退到后一个版本并锁定。这样做的原因是回退版本的依赖包版本肯定会低于现在的,之前的版本是正常的。

经验教训

其实这两起事件是同一个诱因导致的:没有锁定当前项目依赖树模块的版本。下面就来探究一下依赖包的版本管理。

1. 语义化版本(semver)

package.json 在前端工程化中主要用来记录依赖包名称、版本、运行指令等信息字段。其中,dependencies 字段指定了项目运行所依赖的模块,devDependencies指定项目开发所需要的模块。它们都指向一个对象。该对象的各个成员,分别由模块名和对应的版本要求组成,表示依赖的模块及其版本范围。对应的版本可以加上各种限定,主要有以下几种:

  • 指定版本:比如 1.2.2 ,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。

  • 波浪号(tilde)+指定版本:比如 ~1.2.2 ,表示安装 1.2.x 的最新版本(不低于1.2.2),但是不安装 1.3.x,也就是说安装时不改变大版本号和次要版本号。

  • 插入号(caret)+指定版本:比如 ˆ1.2.2,表示安装 1.x.x 的最新版本(不低于 1.2.2),但是不安装 2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为 0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。

  • latest:安装最新版本。

当我们使用比如 npm install package -save 安装一个依赖包时,版本是插入号形式。这样每次重新安装依赖包 npm install 时”次要版本“和“小版本”是会拉取最新的。一般的,主版本不变的情况下,不会带来核心功能变动,API 应该兼容旧版,但是这在开源的世界里很难控制,尤其在复杂项目的众多依赖包中难免会引入一些意想不到的 bug

2. npm-shrinkwrap && package-lock

npm-shrinkwrap

正是存在这每次重新安装,依赖树模块版本存在的不确定性,才有了相应的锁定版本机制。

npm5 之前可以通过 npmshrinkwrap 实现。通过运行 npm shrinkwrap,会在当前目录下生成一个 npm-shrinkwrap.json 文件,它是 package.json 中列出的每个依赖项的大型列表,应安装的特定版本,模块的位置(URI),验证模块完整性的哈希,它需要的包列表,以及依赖项列表。运行 npm install 的时候会优先使用 npm-shrinkwrap.json 进行安装,没有则使用 package.json 进行安装。

package-lock

在 npm5 版本后,当我们运行 npm intall 发现会生成一个新文件 package-lock.json,内容跟上面提到的 npm-shrinkwrap.json 基本一样。

"vue-loader": {
  "version": "14.2.4",
  "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-14.2.4.tgz",
  "integrity": "sha512-bub2/rcTMJ3etEbbeehdH2Em3G2F5vZIjMK7ZUePj5UtgmZSTtOX1xVVawDpDsy021s3vQpO6VpWJ3z3nO8dDw==",
  "dev": true,
  "requires": {
    "consolidate": "^0.14.0",
    "hash-sum": "^1.0.2",
    "loader-utils": "^1.1.0",
    "lru-cache": "^4.1.1",
    "postcss": "^6.0.8",
    "postcss-load-config": "^1.1.0",
    "postcss-selector-parser": "^2.0.0",
    "prettier": "^1.16.0",
    "resolve": "^1.4.0",
    "source-map": "^0.6.1",
    "vue-hot-reload-api": "^2.2.0",
    "vue-style-loader": "^4.0.1",
    "vue-template-es2015-compiler": "^1.6.0"
  },
  "dependencies": {
    "postcss-load-config": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
      "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=",
      "dev": true,
      "requires": {
        "cosmiconfig": "^2.1.0",
        "object-assign": "^4.1.0",
        "postcss-load-options": "^1.2.0",
        "postcss-load-plugins": "^2.3.0"
      }
    },
  }
},

当项目中已有 package-lock.json 文件,在安装项目依赖时,将以该文件为主进行解析安装指定版本依赖包,而不是使用 package.json 来解析和安装模块。因为 package-lock 为每个模块及其每个依赖项指定了版本,位置和完整性哈希,所以它每次创建的安装都是相同的。无论你使用什么设备,或者将来安装它都无关紧要,每次都应该给你相同的结果。

npm5 版本下 install 规则

npm 并不是一开始就是按照现有这种规则制定的。

5.0.x 版本

不管 package.json 中依赖是否有更新,npm install 都会根据 package-lock.json 下载。针对这种安装策略,有人提出了这个 issue[6] ,然后就演变成了 5.1.0 版本后的规则。

5.1.0 版本后

当 package.json 中的依赖项有新版本时,npm install 会无视 package-lock.json 去下载新版本的依赖项并且更新 package-lock.json。针对这种安装策略,又有人提出了一个 issue[7] 参考 npm 贡献者 iarna 的评论,得出 5.4.2 版本后的规则。

5.4.2 版本后

如果只有一个 package.json 文件,运行 npm install 会根据它生成一个 package-lock.json 文件,这个文件相当于本次 install 的一个快照,它不仅记录了 package.json 指明的直接依赖的版本,也记录了间接依赖的版本。

如果 package.json 的 semver-range version 和 package-lock.json 中版本兼容(package-lock.json 版本在 package.json 指定的版本范围内),即使此时 package.json 中有新的版本,执行 npm install 也还是会根据 package-lock.json 下载。

如果手动修改了 package.json 的 version ranges,且和 package-lock.json中版本不兼容,那么执行 npm install 时 package-lock.json 将会更新到兼容 package.json 的版本。

3. yarn

yarn 的出现主要目标是解决上面描述的由于语义版本控制而导致的 npm 安装的不确定性问题。虽然可以使用 npm shrinkwrap 来实现可预测的依赖关系树,但它并不是默认选项,而是取决于所有的开发人员知道并且启用这个选项。yarn 采取了不同的做法。每个 yarn 安装都会生成一个类似于npm-shrinkwrap.json 的 yarn.lock 文件,而且它是默认创建的。除了常规信息之外,yarn.lock 文件还包含要安装的内容的校验和,以确保使用的库的版本相同。

yarn 的主要优化

yarn 的出现主要做了如下优化:

  • 并行安装:无论 npm 还是 yarn 在执行包的安装时,都会执行一系列任务。npm 是按照队列执行每个 package,也就是说必须要等到当前 package 安装完成之后,才能继续后面的安装。而 yarn 是同步执行所有任务,提高了性能。

  • 离线模式:如果之前已经安装过一个软件包,用 yarn 再次安装时之间从缓存中获取,就不用像 npm 那样再从网络下载了。

  • 安装版本统一:为了防止拉取到不同的版本,yarn 有一个锁定文件 (lock file) 记录了被确切安装上的模块的版本号。每次只要新增了一个模块,yarn 就会创建(或更新)yarn.lock 这个文件。这么做就保证了,每一次拉取同一个项目依赖时,使用的都是一样的模块版本。

  • 更好的语义化yarn 改变了一些 npm 命令的名称,比如 yarn add/remove,比 npm 原本的 install/uninstall 要更清晰。

4. 安装依赖树流程

  1. 执行工程自身 preinstall。当前 npm 工程如果定义了 preinstall 钩子此时会被执行。

  2. 确定首层依赖。模块首先需要做的是确定工程中的首层依赖,也就是 dependencies 和 devDependencies 属性中直接指定的模块(假设此时没有添加 npm install 参数)。工程本身是整棵依赖树的根节点,每个首层依赖模块都是根节点下面的一棵子树,npm 会开启多进程从每个首层依赖模块开始逐步寻找更深层级的节点。

  3. 获取模块。获取模块是一个递归的过程,分为以下几步:

  • 获取模块信息。在下载一个模块之前,首先要确定其版本,这是因为 package.json中往往是 semantic versionsemver,语义化版本)。此时如果版本描述文件(npm-shrinkwrap.json 或 package-lock.json)中有该模块信息直接拿即可,如果没有则从仓库获取。如 package.json 中某个包的版本是 ^1.1.0npm就会去仓库中获取符合 1.x.x 形式的最新版本。

  • 获取模块实体。上一步会获取到模块的压缩包地址(resolved 字段),npm 会用此地址检查本地缓存,缓存中有就直接拿,如果没有则从仓库下载。

  • 查找该模块依赖,如果有依赖则回到第 1 步,如果没有则停止。

  • 模块扁平化(dedupe)。上一步获取到的是一棵完整的依赖树,其中可能包含大量重复模块。比如 A 模块依赖于 loadshB 模块同样依赖于 lodash。在 npm3 以前会严格按照依赖树的结构进行安装,因此会造成模块冗余。yarn 和从 npm5 开始默认加入了一个 dedupe 的过程。它会遍历所有节点,逐个将模块放在根节点下面,也就是 node-modules 的第一层。当发现有重复模块时,则将其丢弃。这里需要对重复模块进行一个定义,它指的是模块名相同且 semver 兼容。每个 semver 都对应一段版本允许范围,如果两个模块的版本允许范围存在交集,那么就可以得到一个兼容版本,而不必版本号完全一致,这可以使更多冗余模块在 dedupe过程中被去掉。

  • 安装模块。这一步将会更新工程中的 node_modules,并执行模块中的生命周期函数(按照 preinstallinstallpostinstall 的顺序)。

  • 执行工程自身生命周期。当前 npm 工程如果定义了钩子此时会被执行(按照 installpostinstallprepublishprepare 的顺序)。

  • 5. 举例说明

    插件 htmlparser2@^3.10.1 和 dom-serializer@^0.2.2 都有使用了 entities依赖包,不过使用的版本不同,同时我们自己安装一个版本的 entities 包。具体如下:

    --htmlparser2@^3.10.1
      |--entities@^1.1.1
    --dom-serializer@^0.2.2
      |--entities@^2.0.0
    --entities@^2.1.0
    

    通过 npm install 安装后,生成的 package-lock.json 文件内容和它的 node_modules 目录结构:

    可以发现:

    1. dom-serializer@^0.2.2 的依赖包 entities@^2.0.0 和我们自己安装的 entities@^2.1.0 被实际安装成 entities@^2.2.0,并放在 node_modules 的第一层。因为这两个版本的semver 范围相同,又先被遍历,所有会被合并安装在第一层;

    2. htmlparser2@^3.10.1 的依赖包 entities@^1.1.1 被实际安放在 dom-serializer 包的 node_modules 中,并且和 package-lock.json 描述结构保持一致。

    通过 yarn 安装后,生成的 yarn.lock 文件内容和它的 node_modules 目录结构:

    可以发现与 npm install 不同的是:

    1. yarn.lock 中所有依赖描述都是扁平化的,即没有依赖描述的嵌套关系;

    2. 在 yarn.lock 中, 相同名称版本号不同的依赖包,如果 semver 范围相同会被合并,否则,会存在多个版本描述。

    注意 cnpm 不支持 package-lock

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

    因此,尽量不要直接使用 cnpm install 安装项目依赖包。但是为了解决直接使用 npm install 速度慢的问题,可以设置 npm 代理解决。

    // 设置淘宝镜像代理
    npm config set registry https://registry.npm.taobao.org
    
    // 查看已设置代理
    npm config get registry
    

    当然,也可以通过 `nrm`[8] 工具,快捷操作设置代理。

    全局安装

    $ npm install -g nrm
    

    查看已安装代理列表

    $ nrm ls
    
    * npm -----  https://registry.npmjs.org/
      yarn ----- https://registry.yarnpkg.com
      cnpm ----  http://r.cnpmjs.org/
      taobao --  https://registry.npm.taobao.org/
      nj ------  https://registry.nodejitsu.com/
      skimdb -- https://skimdb.npmjs.com/registry
    

    切换代理

    $ nrm use cnpm  //switch registry to cnpm
    
    * Registry has been set to: http://r.cnpmjs.org/
    

    测速

    nrm test cnpm
    
    * cnpm --- 618ms
    

    然而,设置这些全局代理可能还是不能满足下载一些特定依赖包(在没有 VPN 情况下),比如:node-sasspuppeteerchromedriverelectron 等。可以通过 .npmrc 文件设置具体依赖包的国内镜像。该文件在项目 npm install 时会被加载读取,优先级高于 npm 全局设置。

    registry=https://registry.npm.taobao.org/
    sass_binary_site=http://npm.taobao.org/mirrors/node-sass
    chromedriver_cdnurl=http://npm.taobao.org/mirrors/chromedriver
    electron_mirror=http://npm.taobao.org/mirrors/electron/ npm install -g electron
    puppeteer_download_host=http://npm.taobao.org/mirrors/chromium-browser-snapshots/
    

    6. 总结

    项目在以后重新构建,由于依赖树中有版本更新,造成意外事故是不可避免的,究其原因是整个依赖树版本没有锁死。解决方案分为如下四种:

    • package.json 中固定版本。注意:仅能锁定当前依赖包版本,不能控制整棵依赖树版本。

    • npm+npm-shrinkwrap.json

    • npm+package-lock.json

    • yarn+yarn-lock.json

    根据自身情况选择~

    参考资料

    [1]

    clipboardhttps://github.com/zenorocha/clipboard.js

    [2]

    issueshttps://github.com/zenorocha/clipboard.js/issues/745

    [3]

    braft-editor: https://github.com/margox/braft-editor

    [4]

    draft-jshttps://github.com/facebook/draft-js

    [5]

    issueshttps://github.com/margox/braft-editor/issues/847

    [6]

    issue: https://github.com/npm/npm/issues/16866

    [7]

    issue: https://github.com/npm/npm/issues/17979

    [8]

    nrmhttps://www.npmjs.com/package/nrm

    创作不易,请各位给加个星标点赞、在看 支持哦!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

别瞎删package-lock.json了 的相关文章

  • 无法使用ssh的可能

    1 SSH服务未启动 xff1a 请确保SSH服务在远程计算机上已经启动 在Ubuntu上 xff0c 可以通过运行以下命令来启动SSH服务 xff1a sudo service ssh start 2 防火墙阻止了SSH连接 xff1a
  • CentOS7.0 关闭防火墙

    systemctl stop firewalld service 停止firewall systemctl disable firewalld service 禁止firewall开机启动
  • 如何查看张量tensor,并将其转换为numpy数据

    在tensorflow 中一般数据都是用tensor来表示 xff0c 而在python 中一般是用numpy包 xff0c 然而有时候需要打印变量的数据 xff0c 可用以下方法来打印 xff1a 一 import tensorflow
  • 浅谈联邦学习Federated Learning

    最近人工智能 大数据领域的公众号疯狂给我推送 联邦学习 相关的文章 xff0c 使得本来并不好奇的我 xff0c 有了一丝丝揭开它神秘面纱的冲动 公众号的每篇推文写得都很好 xff0c 但同时也十分学术 xff0c 作为刚上路的我 xff0
  • 云计算中的容器技术及其实践案例

    第一章 xff1a 什么是容器技术 随着云计算和DevOps的普及 xff0c 容器技术在IT行业中越来越受到关注 容器是一种轻量级 可移植 可扩展的应用程序封装技术 xff0c 可以将应用程序及其所有依赖项打包到一个独立的可执行文件中 相
  • 小坑整理

    for range坑 问题描述 range循环的时候 xff0c 取赋值的地址 xff0c 然后保存到map中 xff0c 结果是什么样子 xff1f 这里先回想下变量是什么时候才申请内存 xff1f 只有赋值给新的变量时 xff0c 内存
  • go操作es

    TOC 前言 xff1a elasticsearch 是一个基于Lucene构建的开源的 分布式 restful接口的全文搜索引擎 es还是一个分布式的文档数据库 xff0c 其中每个字段均可被索引 xff0c 而且每个字段的数据均可被搜索
  • 9-gin使用websocket

    toc gin使用websocket Gin 框架默认不支持 websocket xff0c 可以使用 github com gorilla websocket 实现 Talk is cheap Show me the code xff0c
  • 1. 准备环境

    硬件资源 mac 12 2 1 golang 1 15 3 minikube v1 25 1 prometheus operator 0 35 1 下载地址 xff1a https github com prometheus operato
  • pprof查docker内存占用

    https zhuanlan zhihu com p 363584053 https blog csdn net u010278923 article details 78774914
  • oklog run包使用

    oklog run 包介绍 oklog run 包非常简单 xff0c 只有一个类型 xff0c 两个方法 xff0c 共 60 行代码 其中 Group 是一组 actor xff0c 通过调用 Add 方法将 actor 添加到 Gro
  • windows上IIS实现https,配置ssl证书

    windows2003 系统IIS6安装ssl证书 http bbs qcloud com thread 4793 1 1 html windows2012实现IIS7的https 1 申请证书 xff0c 这里申请腾讯云的证书 1 xff
  • Ubuntu 14.04升级到Ubuntu 16.04(桌面版和字符版)

    下面记录了从Ubuntu 14 04 15 10升级到Ubuntu 16 04的步骤 桌面版 在升级系统之前 xff0c 我们先更新一下系统 打开终端执行如下命令 xff1a sudo apt span class hljs attribu
  • 编写使用systemctl启动服务脚本

    CentOS 7的服务systemctl脚本存放在 xff1a usr lib systemd xff0c 有系统 xff08 system xff09 和用户 xff08 user xff09 之分 xff0c 像需要开机不登陆就能运行的
  • python中print打印显示颜色

    显示颜色的格式 xff1a 033 显示方式 字体色 背景色m 033 0m 显示颜色的参数 xff1a 显示方式效果字体色背景色颜色描述0终端默认设置3040黑色1高亮显示3141红色4使用下划线3242绿色5闪烁3343黄色7反白显示3
  • ds1302时钟芯片工作原理引脚电路图及功能

    资源获取码 xff1a aaaa DS1302时钟实用仿真图 上面仿真图功能描述 xff1a 1 能读取DS1302数据 xff0c 并显示在数码管上面 2 带按键设置功能 xff0c 可以设置DS1302时分秒数据 3 带倒计时功能 xf
  • 吴恩达 DeepLearning 第一课第二周编程题目及作业(可免费下载资源)

    提示 作业里面会有需要用到的 Python 模块以及数据集 所以我下面再附上所需要的文件下载链接 xff0c 不把所有文件连同作业放一起打包好的目的是让第一次接触 Python 的人更多的了解 Python xff0c 万事开头难 xff0
  • linux centos7.6 关闭防火墙

    停止firewall root 64 lch software systemctl stop firewalld service 禁止firewall开机启动 root 64 lch software systemctl disable f
  • STM32之SHT30温湿度传感器驱动代码(程序稳定,清晰明了)

    第一部分 xff1a SHT30温湿度模块代码头文件 xff08 SHT30 h xff09 ifndef SHT30 H define SHT30 H include 34 delay h 34 include 34 sys h 34 i
  • 数据集(3):从0了解INRIA数据集

    该数据集分为两种格式 xff1a xff08 a xff09 具有对应注释文件的原始图像 xff08 b xff09 原始的负样本图像和标准化64 128像素的正样本图像 xff08 用于CVPR论文中的 xff09 根目录下虽然有六个文件

随机推荐

  • Ubuntu 登录界面,字体变大,输入密码出现循环登录问题

    出现这个问题 xff0c 很大可能就是显卡驱动掉了 xff0c 只需重新安装就好 参考 xff1a https blog csdn net qq 36427732 article details 80914653 一 下载显卡驱动 用一台电
  • virtualenv的使用

    安装 pip install virtualenv 使用 1 创建一个文件夹 xff0c 用来存放环境 xff0c 之后pip install 之类的东西都在里面 2 在该文件夹中建立该环境 virtualenv p usr bin pyt
  • LIF神经元介绍

    Integrate And Fire Models 基础知识 轴突 xff1a 动作电位 xff08 电位差形成电流 xff09 61 神经递质发放 61 脉冲产生 树突或细胞体 xff1a 神经递质的接受 61 产生内外膜电位差 xff0
  • 神经网络中Batch Size的理解

    直观的理解 xff1a Batch Size定义 xff1a 一次训练所选取的样本数 Batch Size的大小影响模型的优化程度和速度 同时其直接影响到GPU内存的使用情况 xff0c 假如你GPU内存不大 xff0c 该数值最好设置小一
  • Hessian矩阵

    转 xff1a 黑塞矩阵 xff08 Hessian Matrix xff09 转 xff1a Hessian矩阵以及在图像中的应用 黑塞矩阵 xff08 Hessian Matrix xff09 xff0c 是一个多元函数的二阶偏导数构成
  • 残差结构详解

    背景知识 xff1a 为什么要构建深层网络 xff1f 答 xff1a 认为神经网络的每一层分别对应于提取不同层次的特征信息 xff0c 有低层 xff0c 中层和高层 xff0c 而网络越深的时候 xff0c 提取到的不同层次的信息会越多
  • 第二章 Internet 地址结构

    第二章 Internet 地址结构 本文为 TCP IP 详解 学习笔记 文章目录 第二章 Internet 地址结构2 1 引言2 2 表示 IP 地址IPv4 地址IPv6 地址 2 3 基本的 IP 地址结构2 3 1 分类寻址2 3
  • 机器学习中数据不均衡问题(分类类别数据不均匀)

    在机器学习中 xff0c 我们经常会遇到类别数据分布不均衡问题 xff0c 即某类中含有很多数据 xff0c 而其他类别中的数据量很少 在这种情况下 使用传统机器学习算法开发的预测模型可能存在偏差和不准确 xff0c 造成上述的原因是 xf
  • EAST: An Efficient and Accurate Scene Text Detector翻译

    Abstract 用于场景文本检测的先前方法已经在各种基准测试中获得了良好的性能 然而 xff0c 在处理具有挑战性的场景时 xff0c 即使配备了深度神经网络模型 xff0c 它们通常也会达不到很好性能 xff0c 因为整体性能取决于管道
  • pytorch搭建网络结构

    记录pytorch怎么搭建网络 xff0c 看起来更舒服 首先定义一个block class myBlock nn module def init self in channel out channel xff1a super myBloc
  • ubuntu codename

    1 查看当前系统的codename lsb release a 2 历史版本codename Ubuntu 发布版本的官方名称是 Ubuntu X YY xff0c 其中 X 表示年份 xff08 减去2000 xff09 xff0c YY
  • xubuntu_18.04取消开机自动登录

    虽然开机自动登录听方便的 xff0c 但是总感觉不是那么的安全 xff0c 就把开机自动登录取消了 xff0c 下面是取消自动登录的方法 1 首先查一下自动登录的用户 grep R 34 autologin 34 etc lightdm 注
  • 双目相机与IMU联合标定

    前言 为了后面的视觉激光融合SLAM以及跑通VINS Fusion xff0c 需要标定双目相机和IMU得内参以及它们得外参 xff08 变换矩阵 xff09 准备工作 双目相机 xff1a ZED mIMU xff1a realsense
  • Python中画图时候的线类型

    在Python中用matplotlib画图的时候 xff0c 为了区分曲线的类型 xff0c 给曲线上面加一些标识或者颜色 以下是颜色和标识的汇总 颜色 xff08 color 简写为 c xff09 xff1a 蓝色 xff1a 39 b
  • Ubuntu20.04中,安装微信步骤总结

    先安装git xff08 如果已安装 xff0c 清忽略 xff09 sudo apt install git 检查git是否安装成功 xff08 如果已安装 xff0c 清忽略 xff09 git version 安装deepin win
  • touchgfx 浮点数显示

    最近在研究touchgfx xff0c 太懵了 xff0c 也就好久没有更新博文了 xff0c 很坑的一点 xff0c 我就想在屏幕上显示一个小数 xff0c 翻看了N多的博文 xff0c 没一个管用的 xff0c 这里分享一下我的方案 选
  • 浅谈专线(SD-WAN)

    存在就一定有存在的道理 xff0c 今天要说的网络知识点是专线 我们一步步来 xff0c 先说专线是什么 xff0c 然后说专线的特性 xff0c 最后说专线的未来 一 什么是专线 专线就是专门分的线路 xff0c 是运营商为企业客户分配的
  • Ubuntu18系统设置自定义分辨率1920*1080

    一般安装完unbuntu后会发现系统分辨率没有19201080 xff0c 需要手动自定义添加19201080分辨率 打开终端 xff0c 输入命令 xff1a xrandr xff0c 可以查看系统所有分辨率 输入命令生成显示 xff1a
  • 基于饿了么骨架屏方案,使用Chrome扩展程序生成网页骨架屏

    前言 之前写移动端项目的时候 xff0c 使用骨架屏来解决首屏渲染时出现短暂空白现象 xff0c 采用了就是饿了么page skeleton webpack plugin方法 但是page skeleton webpack plugin需要
  • 别瞎删package-lock.json了

    作者 xff1a wuwhs 原文 xff1a https segmentfault com a 1190000039684460 0 前言 看完本文 xff0c 你将从整体了解依赖版本锁定原理 xff0c package lock jso