关于npm和package.json的一些经验之谈(如何同时使用多个版本的echarts)

news2024/11/8 21:30:27

前言

人们往往会忽视他们最常用的东西的一些构造原理,感觉就是天生自带没有为什么。但是真的被问到这些问题的时候,却又答不上来。对于前端开发工程师来说,npm和package.json就是这样的东西。很熟悉却又很陌生。熟悉,是因为,我们几乎每个web项目都会有他们的身影。陌生是因为几乎都没有深究过他们的用法原理。下面,我就来说说我做过的项目中的一些关于npm和package.json的填坑之旅。
cover

一、what is npm ?

首先,我们得知道npm的本质是一种包管理器,官网地址:https://www.npmjs.com。那什么又是包管理器呢?通俗一点,这个东西的全称应该叫做软件包管理器。其实就是类似咱们手机上的应用商店。我们能下载、上传发布、更新应用包。对于web开发来说,这里的包指的就是咱们项目的node_module里面的一个个的文件夹,每个文件夹就是一个依赖包。而npm就是管理这些依赖包的应用商店。
当然,web开发的依赖包不仅仅只有npm。目前市面常见的还有yarncnpm和新出来的pnpm等。

  • yarn是对npm的一个优化版,npm是串行安装依赖,也就是一个一个安装包,比较耗时。yarn是并行安装,能大大提升安装速度。
  • cnpm是咱么国产的魔改npm。针对国内“特殊网络”访问外网困难进行的特殊升级。不过,本人不建议使用。因为有些包没有正式的新
  • pnpm是近几年才出来的,对比npm,最明显的提升就是体现在依赖包的引入方式上。举个例子,现在我们要引入echarts。假设我们有10个项目,那么每个项目都会单独下载引入一份,也就是占了磁盘10份的空间。而使用pnpm的话,会将echarts先下载到磁盘的一个公共区域,然后每个项目是指向这个区域,共用一份空间。好处就不用多说了。

二、what is package.json

package.json本质上就是存在于咱么web项目中根目录下的一个json文件。一般来说的话,常见的结构如下:
package.json结构
我们在使用npm进行依赖安装的前提,就是你的项目得先存在这么个文件。生成该文件的方式,要么你手动创建输入;要么通过npm指令:

npm init

接着会让你输入一系列的配置参数:

PS E:\workspace\H5\GeoMap> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (geomap)
version: (1.0.0)                                                                                                                                                                                                                                        
description:                                                                                                                                                                                                                                            
entry point: (index.js)                                                                                                                                                                                                                                 
test command:                                                                                                                                                                                                                                           
git repository:                                                                                                                                                                                                                                         
keywords:                                                                                                                                                                                                                                               
author:                                                                                                                                                                                                                                                 
license: (ISC)                                                                                                                                                                                                                                          
About to write to E:\workspace\H5\GeoMap\package.json:

{
  "name": "geomap",
  "version": "1.0.0",
  "main": "index.js",
  "directories": {
    "lib": "lib"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "description": ""
}


Is this OK? (yes)

全部回车的话,就都走默认值。然后你的根目录就会生成这个json文件。当然后期,你可以随意修改这个文件里面的值。

简单的理解这个文件的话,就等同于windows里面的注册表

关于package.json的详细介绍,可以看这位老哥的说明:https://blog.csdn.net/qq_34703156/article/details/121401990

三、npm的一些常用命令

1、安装、更新npm

npm一般是和node.js绑在一起的。也就是你安装node.js的时候,就会附带安装好npm。但是呢,有个问题。npm的更新速度远远大于node.js。因此,在很多时候,你的npm版本都是小于官方正式版本的。查看npm版本的指令如下:

npm -v

某些ide如webstorm,在你打开项目的时候,会在console里面提示你npm版本过低,这时可以点击里面的快捷方式进行升级。当然,手动升级也行,指令如下:

npm install npm@latest -g

@的后面跟的是你要升级的npm的版本号。最新的版本号,可以在https://www.npmjs.com中搜索npm关键字,选择第一项即可查看:
npm最新版本号

当然也可以写成上面的latest,表明直接更新到npm包管理器里面的最新版本。-g表明是全局安装,一般都是全局。

2、通过npm安装项目依赖

2.1 基本指令

npm install xxx

这里的xxx代表安装的依赖包的名称(不准确,后面会细说)。

PS:该指令中的install可以简写为i

具体的可以在https://www.npmjs.com中搜索。例如我们要安装echarts,那么写法就应该是:

npm install echarts

这样的话,就会在线帮我们安装好npm远程仓库中最新的echarts。
但是这样不会在package.json中存根,间接地就会导致别人在使用我们的项目安装依赖后,运行项目报错的可能。所以,我们一般要这样写:

npm install echarts --save

加上--save后缀后,就会在package.json的dependencies子节点里面生成我们的依赖项,例如我们安装完echarts后,就会生成诸如下面的语句:

"dependencies": {
    "echarts": "^5.4.2"
 }

PS:--save可以简写为-s

安装指令还可以跟-dev的后缀。-dev表明我们要安装的依赖只在dev开发环境中生效,如果打包到线上的话,就不需要这些包了。一般像eslintcss loaderbebel等,都属于上线后不需要的依赖,指令写法如下:

npm install xxx -dev --save

PS:-dev可以简写为-d

2.2 安装指定版本依赖

通过在要安装的依赖的名字的后面跟上 @version 就能安装指定版本的依赖包。这里的version是要符合Semver的版本号。

PS:Semer的全程叫做Semantic versioning,中文译为语义化版本。官网其实有比较详细的解释:

semantic versions in published packages Using semantic versioning to
specify update types your package can accept Example Resources To keep
the JavaScript ecosystem healthy, reliable, and secure, every time you
make significant updates to an npm package you own, we recommend
publishing a new version of the package with an updated version number
in the package.json file that follows the semantic versioning spec.
Following the semantic versioning spec helps other developers who
depend on your code understand the extent of changes in a given
version, and adjust their own code if necessary.

Note: If you introduce a change that breaks a package dependency, we
strongly recommend incrementing the version major number; see below
for details. Incrementing semantic versions in published packages To
help developers who rely on your code, we recommend starting your
package version at 1.0.0 and incrementing as follows:

Code status	Stage	Rule	Example version First release	New product	Start
with 1.0.0	1.0.0 Backward compatible bug fixes	Patch release	Increment
the third digit	1.0.1 Backward compatible new features	Minor
release	Increment the middle digit and reset last digit to zero	1.1.0
Changes that break backward compatibility	Major release	Increment the
first digit and reset middle and last digits to zero	2.0.0 Using
semantic versioning to specify update types your package can accept
You can specify which update types your package can accept from
dependencies in your package's package.json file.

For example, to specify acceptable version ranges up to 1.0.4, use the
following syntax:

Patch releases: 1.0 or 1.0.x or ~1.0.4 Minor releases: 1 or 1.x or
^1.0.4 Major releases: * or x For more information on semantic
versioning syntax, see the npm semver calculator.

Example   "dependencies": {   "my_dep": "^1.0.0",   "another_dep":
"~2.2.0" }, ```

从官方描述来看,我们可以将版本号拆分为a.b.c的格式。例如1.0.2。1,0,2分别对应了大版本号小更新版本号补丁版本号。一般来说:

  • 大版本号往往是内部做了很大的改动,兼容性不好。比如vue2和vue3这种。如果动大版本号,就要考虑你的项目是否能适配该依赖。
  • 小更新一般是对功能上做了一些扩展优化,兼容性是比较好的。
  • 补丁版本是对当前的版本里面的一些问题进行修复,兼容性比较好。

依赖包的开发者根据这些规则,指定相关的上传包。依赖包的使用者在使用npm install xxx@version指令的时候去下载相应的包:

version写法作用涉及版本级别
1.0更新前缀为1.0的最新版本,例如更新到1.0.3,不会到1.1.x的地步补丁级
1.0.x更新前缀为1.0的最新版本,不会到1.1.x的地步补丁级
~1.0.2更新前缀为1.0的最新版本,不会到1.1.x的地步补丁级
1更新前缀为1的最新版本,例如更新到1.5.2,不会到2.0.1的地步小更新级
1.x更新前缀为1的最新版本,例如更新到1.5.2,不会到2.0.1的地步小更新级
^1.0.2更新前缀为1的最新版本,例如更新到1.5.2,不会到2.0.1的地步小更新级
*更新npm远程库里面的最新版本,例如更新到3.0.1大更新
x更新npm远程库里面的最新版本,例如更新到3.0.1大更新

举个例子,我们已经安装了4.7.0的echarts,此时的package.json是这样的:

"dependencies": {
    "echarts": "^4.7.0"
  }

这时,如果我们再执行一次npm install,那么就会更新到4.9.0而不是5.4.2。

2.3 给依赖取别名

最近在做一个数据大盘项目,当中涉及到了用echartst绘制图表。其中还包含了飞机的航线图。其中,飞机航线图所用到的echarts只能是4.7.0的,否则不能绘制航线。但是4.x版本的echarts没有圆角功能,导致很多图表绘制出来不精致。因此就需要引入两个版本的echarts。但是普通的npm install echarts方式只能安装一种,最后终于找到了解决办法,就是给echarts取别名。
现在,我们先使用默认的安装方式,安装了5.4.2版本的echarts后,再执行下面的指令安装4.7.0的echarts:

npm install echarts4 npm:echarts@4.7.0 -s

当执行完后,package.json里面就会出现echarts4的项了:

"dependencies": {
    "echarts": "5.4.2",
    "echarts4": "npm:echarts@4.7.0"
  }

与此同时,node_modules里面也会生成echarts4的文件夹:
echarts4
使用方式也很简单,默认的echarts5的引入方式如下:

import * as echarts from 'echarts'

当然。as后面本身也是一个别名,你也可以写成echarts5。
echarts4的引入方式,则改为:

import * as echarts from 'echarts4'

from后面的路径要和你安装时取的别名一致。

2.4 使用本地相对依赖

这一块对于大多数开发者来说,并不常见。我在查阅vue-admin-better的源码时看到了这一块。我们一般都使用的是远程的依赖。但是其实,npm还支持本地的依赖。其基本语法为:

npm install xxx@file:path

xxx代表的是一个依赖包名,也就是相应的package.json里面的name字段的属性。path是你这个依赖包相对于根目录的路径。由于是包名,因此我们需要先构造一个依赖包的结构。在这里,我们先在项目根目录模拟构造一个最简单依赖包结构:
最简单的包
其中至少包含一个package.json和一个入口js文件。
入口js文件的内容如下:

const GAMES = [
  {
    'label': '射击类FPS',
    'value': 0
  },
  {
    'label': '角色扮演类RPG',
    'value': 1
  },
  {
    'label': '赛车类RACE',
    'value': 2
  }
]

export {
  GAMES
}

很简单,就是单纯地生成一个常量,然后导出。
package.json的内容如下:

{
  "name": "constant",
  "version": "0.0.1",
  "main": "test.js"
}

包含了一个包的name,版本号和入口js路劲(相对于当前的包的文件夹来说的)。
这个时候,我们执行安装指令:

npm install constant@file:constant -s

运行完后,package.json会生成:
ccc
并且在node_modules中会生成指向constant的软链:
软链
使用依赖包的方式也很简单,

import {GAMES} from 'constant'

这样就能调用到我们刚才设置的变量。
上面是个相对简单的例子,实际项目中的结构要比这个复杂一些,我再举一个相对规范的例子。
假设我们的本地依赖包都放在了一个lib的目录中,还是以这个constant为例:
constant
constant的结构如下,增加了二级菜单:
二级菜单
这个时候,我们要修改一下package.json如下:

{
  "name": "constant2",
  "version": "0.0.1",
  "main": "js/test.js"
}

修改了包名,main的入口函数项上套上相对路径。然后安装时,也加上相对路径:

npm install constant2@file:lib/constant -s

这时的package.json会生成:

"dependencies": {
    "constant": "file:constant",
    "constant2": "file:lib/constant"
  }

同样地,node_modules里面,也会生成软链:
constant2
通过两个例子,我们就很好地掌握了如何使用本地依赖地方式。

2.5 依赖远程私有库

这里引入这篇文章的解释:https://www.lmlphp.com/user/59042/article/item/2097221/
对于 npm 公用包来说是比较方便的,直接引用即可。而内网的代码应该怎么引入呢?大概有以下几种方式:

  • npm 公有包
  • npm 私有包
  • 搭建 npm 私有服务器
  • git 仓库
    公有包肯定是满足不了需求的,因为所有人都能下载包,也就意味着代码是被泄漏了,首先被排除。npm 私有包是收费的,

而搭建 npm 服务器也是需要一定成本的,所以最好的方案自然是采用 npm 安装 git 仓库的方式了。

下看 npm 对于安装 git 仓库的命令:

npm install <git remote url>

实际上就是直接 install 一个 URL 而已。对于一些公有仓库, npm 还是做了一些集成的,比如 github等(示例全部出自 npm 官方文档):

npm install github:mygithubuser/myproject

npm install bitbucket:mybitbucketuser/myproject

npm install gitlab:myusr/myproj#semver:^5.0

如果我们直接安装 github 上,使用网址的方式可以表示为:

npm install git+https://isaacs@github.com/npm/npm.git

看下 npm 安装 git 仓库的协议:

<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]

即 protocol 支持 git, git+ssh, git+http, git+https, git+file,私有仓库需要用户名和密码时需要填写用户名和密码,semver 表示需要使用的版本号, 不过貌似不生效。(npm 中有个包 semver 是专门用于比较包的版本号大小)

直接写 #branch 表示需要安装的分支号。

所以在开发过程中我们可以这么写包:

npm i git+https://username:password@git.example.com/path/reposity#master

或者使用打的 tag

npm i git+https://username:password@git.example.com/path/reposity#1.0.0

可能存在的问题是:
由于新版的 npm install 在安装时会使用 package-lock.json, 有时候同一分支不会从 github 上拉取最新的,
可能需要手动再安装一下(拿自己的仓库试了下,果然不会更新),所以安装时尽量以 tag 为标签进行安装,这样确保代码是正确的
此外,由于私有仓库都是需要密码的,这个时候需要提供一个公共账号和密码,某种程度上不利于管理吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/683646.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【消费战略方法论】食品品牌成功的本质

消费始于消费者 也终于消费者 当下的品牌是否都是以“消费者”为核心进行打造和运营的&#xff1f;面对着越来越多、五花八门的战略思路、品牌方法、营销理论&#xff0c;很多品牌越来越偏离了“消费”的本质。沉迷于精湛的营销打法之前是否需要先审视一下做品牌的初衷。 现…

Nginx服务性能和安全优化

目录 一、配置Nginx隐藏版本相关信息 1.隐藏版本号 2.修改版本号及相关信息 ​编辑​编辑 二、修改Nginx运行时的属主和属组 三、配置Nginx网页缓存时间 四、配置Nginx站点日志分割 五、设置Nginx长连接及超时时间 六、配置Nginx网页压缩 七、配置Nginx防盗链 1.模拟…

人工智能-A*启发式搜索算法解决八数码问题 Python实现

一.问题描述 八数码问题也称为九宫问题。在 33 的棋盘&#xff0c;摆有八个棋子&#xff0c;每个棋子上标有 1 至 8 的某一数字&#xff0c;不同棋子上标的数字不相同。棋盘上还有一个空格&#xff08;以数字 0 来表示&#xff09;&#xff0c;与空 格相邻的棋子可以移到空格中…

操作系统——Linux 进程间通信

一&#xff1a;实验题目 Linux 进程间通信 二&#xff1a;实验目的 Linux 系统的进程通信机构&#xff08;IPC&#xff09;允许在任意进程间大批量地交换数据&#xff0c;通过本实验&#xff0c;理解 熟悉 Linux 支持的消息通信机制。 三&#xff1a;实验内容&#xff08;…

企业级微服务架构实战项目--xx优选-小程序安装篇4

一 搭建微信小程序前端环境 1.1 申请小程序测试号 申请地址&#xff1a;微信公众平台 使用微信扫描二维码进行申请&#xff0c;申请成功之后&#xff0c;进入界面&#xff0c;获取小程序ID和秘钥 。 AppID(小程序ID) wx62bfe844fea3eba8 AppSecret(小程序密钥) …

JavaScript ES9新特性

文章目录 Object spread syntax&#xff08;对象扩展语法&#xff09;Promise.prototype.finally()Asynchronous Iteration&#xff08;异步迭代&#xff09;&#xff1a;Rest/Spread Properties&#xff08;剩余和扩展属性&#xff09;&#xff1a;RegExp named capture group…

Apikit 自学日记:导入、导出文档

一、导入API文档 功能入口&#xff1a;API管理应用 / 选中某个项目 / API文档菜单 / 点击“ API”按钮旁的下拉按钮 / 选中“导入API” Eolink提供一键导入已有API文档的功能&#xff0c;支持多种产品格式。常用于新项目创建后&#xff0c;需要对旧项目或旧软件内数据进行迁移…

认识设计组件帮助测试,以提高产品用户体验

一、控制元素 1、活动指示器——应与背景想协调&#xff0c;用于持续时间不明的进程&#xff0c;单一元素不显示&#xff0c;大于1个显示 2、加载控件——同一个专区页面&#xff0c;加载样式统一 3、页码控制器——原点最好控制在5点内&#xff0c;左右滑动&#xff0c;点击原…

OpenCL编程指南-5.5图像读、写函数

读图像 OpenCL GPU设备有专用硬件来读、写图像。OpenCL C图像读、写函数允许开发人员充分利用这个专用硬件。OpenCL 中的图像支持是可选的。要了解一个设备是否支持图像&#xff0c;可以使用clGetDeviceInfo API查询CL_DEVICE_IMAGE_SUPPORT属性。 需要说明的是&#xff0…

c4d+AI+PS设计广告展示架/销售柜台/展示盒子的建议

1、首先做出我标识出来的样子&#xff0c;这里称作A面。&#xff08;可用软件&#xff1a;PS、AI、cdr等&#xff09; 2、制作用于展示盒A面PNG图片&#xff08;PS来掏空空白处用于描边&#xff09;。 操作&#xff1a;按需求缩小图片&#xff0c;载入选区&#xff0c;新建图层…

three.js标准网格材质(MeshStandardMaterial)光照、粗糙度、金属度、法线属性介绍

如上图&#xff0c;在前面的章节中我们通过设置物体的纹理和材质实现了一个3d的立体门框的效果 完整代码如下&#xff1a; import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls&quo…

新媒体运营工作总结

新媒体运营工作总结篇1 一、大力提升新媒体平台的关注度。在当前掩盖全校60%的同学的基础上&#xff0c;进一步提高掩盖率&#xff0c;争取在未来一年中到达90%以上。为了增强平台与受众的互动与交流&#xff0c;吸引同学们的关注&#xff0c;可以展开更多同学们喜闻乐见的线上…

macOS FreeBSD 如何刷新 DNS 缓存

macOS FreeBSD 如何刷新 DNS 缓存 全文&#xff1a;如何刷新 DNS 缓存 (macOS, Linux, Windows) Unix Linux Windows 如何刷新 DNS 缓存 (macOS, FreeBSD, RHEL, CentOS, Debian, Ubuntu, Windows) 请访问原文链接&#xff1a;https://sysin.org/blog/how-to-flush-dns-cach…

(动态规划) 5. 最长回文子串 ——【Leetcode每日一题】

❓ 5. 最长回文子串 难度&#xff1a;中等 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s “babad” 输出&#xff1a;“bab” 解释&#xff1a…

Pytest+Webdriver+Alluer的UI自动化测试框架

作为web自动化的入门学习&#xff0c;搭建框架练习下 一、熟悉项目的测试框架的整体目录 二、 PIP安装完所需框架 1、编写main.py import pytestif __name__ __main__:#pytest.main() # 遍历相同目录下的所以test开头的用例#生成测试报告 #一次执行所有接口测试用例&…

【消费战略方法论】3W消费战略作业方法

3W消费战略 以消费者为核心导向的 品牌战略 品牌本质上属于消费者&#xff0c;消费者是品牌战略的核心。所有品牌工作都应把握一个标准&#xff0c;即是否围绕着消费者&#xff0c;是否对消费者有价值。一切的品牌战略、策略、创意、营销等工作都应该是为了“消费者”而设…

【Java|多线程与高并发】定时器(Timer)详解

文章目录 1. 前言2. 定时器的基本使用3. 实现定时器4. 优化上述的定时器代码5. 总结 1. 前言 在Java中&#xff0c;定时器Timer类是用于执行定时任务的工具类。它允许你安排一个任务在未来的某个时间点执行&#xff0c;或者以固定的时间间隔重复执行。 在服务器开发中,客户端向…

原型模式(Prototype)

定义 原型是一种创建型设计模式&#xff0c;使你能够复制已有对象&#xff0c;而又无需使代码依赖它们所属的类。 别名 克隆&#xff08;Clone&#xff09;。 前言 1. 问题 如果你有一个对象&#xff0c;并希望生成与其完全相同的一个复制品&#xff0c;你该如何实现呢&a…

基于工业智能网关的设备运维管理平台有何功能?

工业物联网平台作为监控工业设备和工业环境的智能应用&#xff0c;整合边缘和云端的数据优势&#xff0c;在制造业领域得到越来越丰富的应用。 在工业制造生产过程中&#xff0c;常常分为人、机、料、法、环等五大要素&#xff0c;其中机器设备的安全稳定运行时保证工厂生产效…

58同城AI Lab在WeNet中开源GPU热词增强功能

01 前言 端到端语音识别系统在足够多数据上训练后&#xff0c;往往能达到不错的识别效果&#xff0c;然而在实际应用场景中&#xff0c;对于不常见的专有名词&#xff0c;例如人名、产品名、小区名等&#xff0c;往往容易识别错误&#xff0c;此类问题需要快速修复&#xff0c…