语义化版本

  • major: 重大变化,不兼容老版本

  • minor: 新增功能,兼容老版本

  • patch: 修复bug,兼容老版本

依赖版本号

  • * 匹配最新版本的依赖

  • ^ 匹配最近的大版本依赖,比如^1.2.3,会匹配所有1.x.x的包,不包括2.0.0

  • ~ 会匹配最近的小版本依赖,比如~1.2.3,会匹配所有1.2.x版本,不包括1.3.0

package入口

如果使用import对库进行导入,会优先寻找module字段引入,然后才是main字段。

  1. {
  2. name: 'midash',
  3. main: './dist/index.js', // es module入口
  4. module: './dist/index.mjs' // commonjs入口
  5. }

package-lock

锁定规则

  • 当package-lock.json中的依赖锁定版本符合package.json中的版本号范围时,将以package-lock.json锁死版本号为主。

  • 当package-lock.json中的依赖锁定版本不符合package.json中的版本号范围时,将会安装符合package.json版本号范围的最新版本号依赖,并重写 package-lock.json文件

要不要提交package-lock

  • 对于项目开发而言,有必要。当有了lock文件时,每一个依赖的版本号都被锁死在了lock文件,每次依赖安装的版本号都从lock文件中进行获取,避免了不可测的依赖风险。

  • 对于库开发而言,也有必要。虽然项目中所有依赖都会根据项目lockfile锁死而并不会依照库依赖的lockfile,但是为了贡献者能很容易地将项目跑起来,devDependencies必须在库的lockfile中锁定。

npm脚本原理

  • 每当执行npm run xx,就会自动新建一个Shell,在这个Shell里面执行指定的脚本命令。因此,只要是Shell可以运行的命令,一般是Bash,就可以写在npm脚本里面。
  • npm run新建的这个Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样,这也就是为什么npm run指向的命令能够被执行的原因。

npm脚本执行

  1. {
  2. "scripts": {
  3. "bx": "npm run script1.js & npm run script2.js", // 并行执行(同时执行)
  4. "abc": "npm run script1.js && npm run script2.js", // 继发执行(即只有前一个任务成功,才执行下一个任务)
  5. }
  6. }

Windows下不支持这2种方式,可以通过安装npm-run-all、Concurrently模块解决。

npm常用别名

  1. npm add -> npm install
  2. npm create -> npm init

npm发布

  1. 第一步,在npm官网进行注册一个账号。
  2. 第二步,执行 npm login,输入注册的账号密码完成登录。
  3. 第三步,npm i -y 初始化 package 文件,填入最基本的3个字段:name,version 和 main 字段,其中main字段应该是打包后的代码。
  4. 第四步,在包目录执行npm publish

npm变量

通过npm_package_前缀,js脚本可以通过process.env对象拿到package.json里面的字段。比如,下面这个package.json:

  1. {
  2. "name": "foo",
  3. "version": "1.2.5",
  4. "scripts": {
  5. "view": "node view.js"
  6. }
  7. }
  1. // view.js
  2. console.log(process.env.npm_package_name); // foo
  3. console.log(process.env.npm_package_version); // 1.2.5

npm_package_前缀也支持嵌套的package.json字段

  1. // view.js
  2. console.log(process.env.npm_package_scripts_view); // node view.js

npm依赖

  • dependencies 生产依赖

  • devDependencies 开发依赖

安装命令

  1. npm i --save xxx // 生产依赖
  2. npm i --save-dev // 开发依赖
  3. npm i -S xxx // 生产依赖(简写)
  4. npm i -D xxx // 开发依赖(简写)

是否要严格区分生产和开发?

  • 当进行项目开发时,并无必要。因为打包时,依靠的是Webpack/Rollup对代码进行模块依赖分析,与该模块是否在dep/devDep并无关系,只要在 node_modules上能够找到该依赖即可。

  • 当进行库开发时,有必要。因为当在项目中安装一个依赖库时,只有该依赖的dependencies会被安装到node_modules中,devDependencies不会,因此这里如果不区分,会导致开发项目报错受影响。

npm钩子

npm钩子,也称npm生命周期。npm默认提供pre和post两个钩子,当我们执行任意npm run脚本时,都将自动触发pre/post的钩子但是这2个钩子的内容需要由你自定义。

  1. {
  2. "scripts": {
  3. "preabc": "xxx",
  4. "abc": "xxx",
  5. "postabc": "xxx"
  6. }
  7. }

当你执行npm run abc时,会自动按照下面的顺序执行

  1. npm run preabc -> npm run abc -> npm run postabc

一些常用npm脚本,如:publish、install、uninstall、version、test、stop、start和restart,同样支持自定义这2个钩子。

npm restart

npm restart是一个复合命令,实际上会执行三个脚本命令:stop、restart、start。具体的执行顺序如下:

  1. prerestart
  2. prestop
  3. stop
  4. poststop
  5. restart
  6. prestart
  7. start
  8. poststart
  9. postrestart

npm publish

npm publish发包的生命周期比较复杂,当执行npm publish命令,将自动执行以下脚本:

  1. prepublishOnly: 最重要的一个生命周期,如果你需要在发包之前自动做一些事情,如测试、构建等,可以在这里完成。
  2. prepack
  3. prepare
  4. postpack
  5. publish
  6. postpublish

prepare钩子

一个最常用的生命周期钩子,它的执行时机:

  • npm install 之后自动执行

  • npm publish 之前自动执行

常用的git hook工具husky通常就被放置在这个钩子里执行

  1. {
  2. prepare: "husky install";
  3. }

npm_lifecycle_event变量

npm提供一个npm_lifecycle_event变量,返回当前正在运行的脚本名称,比如pretest、test、posttest等等。所以,可以利用这个变量,在同一个脚本文件里面,为不同的npm scripts命令编写代码。

  1. const TARGET = process.env.npm_lifecycle_event;
  2. if (TARGET === 'test') {
  3. console.log(`Running the test task!`);
  4. }
  5. if (TARGET === 'pretest') {
  6. console.log(`Running the pretest task!`);
  7. }
  8. if (TARGET === 'posttest') {
  9. console.log(`Running the posttest task!`);
  10. }

npx

npm 从5.2版开始,增加了npx命令,可以提升开发者使用包内提供的命令行工具的体验,它有很多用处。

方便调用项目安装的模块

通常我们安装完npm依赖或脚手架后,需要将其写入package.json的scripts字段里面,运行npm run xxx才能执行,npx就是想解决这个问题,利用npx,我们可以直接调用运行。

  1. "scripts": {
  2. "serve": "vue-cli-service serve",
  3. "build": "vue-cli-service build",
  4. "build-bundle": "vue-cli-service build --target lib --name t3-ui ./src/components/index.js",
  5. "lint": "vue-cli-service lint"
  6. }

我们用npx命令的话, 就不需要在写scripts里面的内容, 直接在控制台执行npx vue-cli-service serve,就会直接寻找本地依赖并执行。

避免全局安装模块

运行npx命令后,npx会将依赖下载到一个临时目录,使用以后再删除

  1. npx uglify-js@3.1.0 main.js -o ./dist/main.js // 临时下载压缩包,执行压缩
  1. npx http-server // 临时在当前目录,安装并运行起本地服务器

使用不同版本的node

  1. npx -p node@6 npm run serve

执行逻辑如下:

  • npx下载node@6版本
  • 将执行的node版本切换为node@6版本
  • 使用node@6执行npm run serve
  • 命令执行完毕后,删除下载包,最终不会改变本地的使用版本

npx命令执行逻辑

先自动查找当前依赖包中的可执行文件,如果找不到,就会去PATH里找,如果依然找不到,就会帮你临时安装,执行完后再删除包。

npm init

命令用法:

  1. npm init [--force|-f|--yes|-y|--scope]
  2. npm init <@scope> (same as `npx <@scope>/create`)
  3. npm init [<@scope>/]<name> (same as `npx [<@scope>/]create-<name>`)

npm init xxx时,会自动转换成如下npx命令:

  1. npm init foo -> npx create-foo
  2. npm init @usr/foo -> npx @usr/create-foo
  3. npm init @usr -> npx @usr/create

以vue3官方安装为例,命令实际效果如下:

  1. // 实际安装的是create-vue@latest包
  2. npm init vue@latest -> npx create-vue@latest

npm exec命令和npx作用相同,区别仅在于后者会将其后面的标志和选项都会优先设置为位置参数,具体可对照npm文档。

npm link

简而言之,就是可以将你本地的npm开发包当作是已经npm install好后的包使用了,用来在本地项目和本地npm模块之间建立连接,方便关联到项目中进行修改/调试。

局部link

项目和本地npm模块在同一个目录下,可以使用相对路径进行link

  1. npm link ../module // 然后,你本地项目的node_modules就出现了该module的软链接

全局link

1.注入全局link

  1. cd modulePath
  2. npm link // 然后,全局node_modules目录下就出现该module的软链接

2.引入全局link

  1. cd projectPath
  2. npm link module

解除link

解除局部link

  1. cd projectPath
  2. npm unlink module

解除全局link

  1. cd modulePath
  2. npm unlink

以vite为例

如果你迫不及待想要体验最新的功能,可以自行克隆vite仓库,然后到本地机器上然后自行将其链接

  1. // 第1步,克隆并进入目录
  2. git clone https://github.com/vitejs/vite.git
  3. cd vite
  4. // 第2步,安装vite作为npm开发包的依赖,然后打包出开发者需要的vite
  5. pnpm install
  6. cd packages/vite
  7. npm run build
  8. // 第3步,全局注入link
  9. npm link
  10. // 第4步,进入本地项目,引入link,这个时候就相当于全局安装了vite,类似于执行了vite官方安装命令:npm create vite@latest
  11. pnpm link --global vite
  12. // 第5步,package文件的script内dev写入vite命令
  13. dev: 'vite'
  14. // 第6步,执行npm命令
  15. npm run dev

实际测试发现,使用link后,第5和第6步是多余的,本地可以直接在控制台使用vite命令,不管你是全局link的,还是局部link的,都可以运行。

npm相关知识整理的更多相关文章

  1. Redis相关知识整理

    Redis相关知识整理 1. Redis和MySQL的区别?a).mysql是关系型数据库,而redis是NOSQL,非关系型数据库.mysql将数据持久化到硬盘,读取数据慢,而redis数据先存储在 ...

  2. podSpec文件相关知识整理

    上一篇文章整理了我用SVN创建私有库的过程,本文将整理一下有关podSpec文件的相关知识. podSpec中spec的全称是“Specification”,说明书的意思.顾名思义,这是用来描述你这个 ...

  3. OpenCV&Qt学习之四——OpenCV 实现人脸检测与相关知识整理

    开发配置 OpenCV的例程中已经带有了人脸检测的例程,位置在:OpenCV\samples\facedetect.cpp文件,OpenCV的安装与这个例子的测试可以参考我之前的博文Linux 下编译 ...

  4. [Cxf] cxf 相关知识整理

    ① 请求方式为GET @GET @Path(value = "/userAddressManage") @Produces( { MediaType.APPLICATION_JSO ...

  5. JVM的相关知识整理和学习--(转载)

    JVM是虚拟机,也是一种规范,他遵循着冯·诺依曼体系结构的设计原理.冯·诺依曼体系结构中,指出计算机处理的数据和指令都是二进制数,采用存储程序方式不加区分的存储在同一个存储器里,并且顺序执行,指令由操 ...

  6. Web缓存相关知识整理

    一.前言  工作上遇到一个这样的需求,一个H5页面在APP端,如果勾选已读状态,则下次打开该链接,会跳过此页面.用到了HTML5 的本地存储 API 中的 localStorage作为解决方案,回顾了 ...

  7. java中的字符串相关知识整理

    字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...

  8. Android 基本控件相关知识整理

    Android应用开发的一项重要内容就是界面开发.对于用户来说,不管APP包含的逻辑多么复杂,功能多么强大,如果没有提供友好的图形交互界面,将很难吸引最终用户.作为一个程序员如何才能开发出友好的图形界 ...

  9. 【杂谈】FilterChain相关知识整理

    前言 做后台的,Filter肯定没少配置,但是知晓其原理的可能不多.在这之前我也不懂,但这并不影响业务开发,同时也有其他的知识要学,所以一直就没看.这阵子有点闲,刚好在看<How Tomcat ...

随机推荐

  1. Java基础语法Day_02-03(数据类型、运算符、方法、循环结构)

    第5节 数据类型转换 day02_01_数据类型转换_自动转换 day02_02_数据类型转换_强制转换 day02_03_数据类型转换_注意事项 day02_04_ASCII编码表 第6节 运算符 ...

  2. 利用QEMU+GDB搭建Linux内核调试环境

    前言 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试. 其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qe ...

  3. [操作系统]LINUX进程状态说明

    R(task_running) : 可执行状态 只有在该状态的进程才可能在CPU上运行.而同一时刻可能有多个进程 处于可执行状态,这些进程的task_struct结构(进程控制块)被放入对应CPU的 ...

  4. [总结] 零散的 tricks

    对于类似构造方案的题目,先确定其中一些关键位置的方案,然后看是否能较为简单地推出其他位置的方案. 一个长度为 \(n\) 的序列,满足 \[a_1\le-a_4\le a_7\le-a_{10}\le ...

  5. 一文看懂二层接口、三层接口、PVID及VLANIF

    关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 文章来源:朱仕耿个人博客 一位同事问了个关于二层和三层端口的概念及区分,以及关于VLANIF. ...

  6. victoriaMetrics无法获取抓取target的问题

    victoriaMetrics无法获取抓取target的问题 问题描述 最近在新环境中部署了一个服务,其暴露的指标路径为:10299/metrics,配置文件如下(名称字段有修改): apiVersi ...

  7. Java学习笔记-基础语法Ⅹ-进程线程

    学习快一个月了,现在学到了黑马Java教程的300集 打印流的特点: 只负责输出数据,不负责读取数据 有自己的特有方法 字节打印流:PrintStream,使用指定的文件名创建新的打印流 import ...

  8. JS 异步与 Promise

    JS 异步与 Promise 本文写于 2020 年 6 月 8 日 1. 同步与异步与回调函数 Promise 现在是前端面试必考题呀,但是先不急着看 Promise,我们首先来看看什么是异步. - ...

  9. linux篇-linux下ffmpeg安装

    1最近自己搭建的公司服务端转化视频不可以,我想应该是ffmpeg的问题,头痛 准备这两个源码包 2安装,先解压 ffmpeg-4.1.4.tar.bz2 yasm-1.3.0.tar.gz 3先安装y ...

  10. linux篇-Centos7构建NFS服务器和连接

    准备两台centos7虚拟机 192.168.30.133 192.168.30.129 2.192.168.30.1(服务端), 3查看rpc服务是否启动 4测试安装是否成功 5修改配置文件vi/e ...