你不知道的npm

npm

前端工程化离不开 npm(node package manager) 或者 Yarn 这些管理工具。npm 或 Yarn 在工程项目中,除了负责依赖的安装和维护以外,还能通过 npm scripts 串联起各个职能部分,让独立的环节自动运转起来。

npm诞生背景

npm由程序员isaacs(https://github.com/isaacs)发明,他的初步思路是集中管理所有的模块,所有的模块都上传到仓库中(registry)。在模块内创建package.json标注模块的基本信息,像模块名、版本、依赖库等等,然后通过npm publish发布模块上传倒npm仓库中(registry),最后通过npm install安装模块,模块安装到node_modules目录下。npm于2014年商业化,2020年被Github收购。

npm介绍

npm解决的核心问题是模块管理问题,npm包含cli脚手架、模块仓库、官网(https://www.npmjs.com/)三大部分。

关于npm的相关信息可以查阅:https://docs.npmjs.com/about-npm

在这里插入图片描述

产生一个模块首先通过npm init来创建一个模块,创建的模块中包含package.json,我们通过修改name、version、dependencies来确定模块的基本信息,如果模块想使用其他的模块则需要使用npm install来安装其他的模块,将模块下载到node_modules目录中,其中模块也包含package.json和node_modules这就是npm的规范。

当module1开发完成后,调用npm publish上传到npm registry中,registry包含两部分,一部分是public公开的,任何人都能使用,另一部分是private私有的,现在npm商业化后主要靠私有仓库收费。

public共有仓库又分为两种,一种是普通的仓库,一种是组织的仓库。

常见的npm命令如下:

  • npm init:创建模块
  • npm install:安装模块
  • npm publish:发布模块
  • npm link:关联本地模块进行本地开发
  • npm config:查看或调整本地配置
  • npm run:调用scripts

npm的局限

npm只能解决模块的高校管理和获取问题,无法解决性能加载性能问题。所以模块化发明后,制约其广泛应用的因素就是性能因素。

npm内部机制和核心原理

我们先来看看 npm 的核心目标:

Bring the best of open source to you, your team and your company.
给你和你的团队、你的公司带来最好的开源库和依赖。

通过这句话,我们可以知道 npm 最重要的一环是安装和维护依赖。在平时开发中,“删除 node_modules,重新 npm install”是一个百试不爽的解决 npm 安装类问题的方法。

npm 的安装机制和背后思想

它会优先安装依赖包到当前项目目录,使得不同应用项目的依赖各成体系,同时还减轻了包作者的 API 兼容性压力,但这样做的缺陷也很明显:如果我们的项目 A 和项目 B,都依赖了相同的公共库 C,那么公共库 C 一般都会在项目 A 和项目 B 中,各被安装一次。这就说明,同一个依赖包可能在我们的电脑上进行多次安装。

当然,对于一些工具模块比如 supervisor 和 gulp,你仍然可以使用全局安装模式,这样方便注册 path 环境变量,我们可以在任何地方直接使用 supervisor、 gulp 这些命令。(不过,一般还是建议不同项目维护自己局部的 gulp 开发工具以适配不同项目需求。)

npm的安装机制如下图所示:

在这里插入图片描述

npm install 执行之后,首先,检查并获取 npm 配置,这里的优先级为:项目级的 .npmrc 文件 > 用户级的 .npmrc 文件> 全局级的 .npmrc 文件 > npm 内置的 .npmrc 文件。

然后检查项目中是否有 package-lock.json 文件。

如果有,则检查 package-lock.json 和 package.json 中声明的依赖是否一致:

  • 一致,直接使用 package-lock.json 中的信息,从缓存或网络资源中加载依赖;
  • 不一致,按照 npm 版本进行处理(不同 npm 版本处理会有不同,具体处理方式如图所示)。

如果没有,则根据 package.json 递归构建依赖树。然后按照构建好的依赖树下载完整的依赖资源,在下载时就会检查是否存在相关资源缓存:

  • 存在,则将缓存内容解压到 node_modules 中;
  • 否则就先从 npm 远程仓库下载包,校验包的完整性,并添加到缓存,同时解压到 node_modules。

最后生成 package-lock.json。

构建依赖树时,当前依赖项目不管其是直接依赖还是子依赖的依赖,都应该按照扁平化原则,优先将其放置在 node_modules 根目录(最新版本 npm 规范)。在这个过程中,遇到相同模块就判断已放置在依赖树中的模块版本是否符合新模块的版本范围,如果符合则跳过;不符合则在当前模块的 node_modules 下放置该模块(最新版本 npm 规范)。

图中标明的 npm 不同版本的不同处理情况,并学会从这种“历史问题”中总结 npm 使用的团队最佳实践:同一个项目团队,应该保证 npm 版本的一致。

npm缓存机制

对于一个依赖包的同一版本进行本地化缓存,是当代依赖包管理工具的一个常见设计。使用时要先执行以下命令:

npm config get cache

通过这行命令可以得到配置缓存的根目录在C:\Users\用户名\AppData\Local\npm-cache(mac在/Users/用户名/.npm),我们 cd 进入C:\Users\用户名\AppData\Local\npm-cache中可以发现_cacache文件。在 npm v5 版本之后,缓存数据均放在根目录中的_cacache文件夹中。

在这里插入图片描述

可以使用以下命令清除C:\Users\用户名\AppData\Local\npm-cache_cacache 中的文件

npm cache clean --force

在_cacache目录下,有三个目录:

  1. content-v2
  2. index-v5
  3. tmp

其中 content-v2 里面基本都是一些二进制文件。为了使这些二进制文件可读,我们把二进制文件的扩展名改为 .tgz,然后进行解压,得到的结果其实就是我们的 npm 包资源。

而 index-v5 文件中,我们采用跟刚刚一样的操作就可以获得一些描述性的文件,事实上这些内容就是 content-v2 里文件的索引。

那么这些缓存是如何生成的呢?

当 npm install 执行时,通过pacote把相应的包解压在对应的 node_modules 下面。npm 在下载依赖时,先下载到缓存当中,再解压到项目 node_modules 下。pacote 依赖npm-registry-fetch来下载包,npm-registry-fetch 可以通过设置 cache 属性,在给定的路径下根据IETF RFC 7234生成缓存数据。

然后在每次安装资源时,根据 package-lock.json 中存储的 integrity、version、name 信息生成一个唯一的 key,这个 key 能够对应到 index-v5 目录下的缓存记录。如果发现有缓存资源,就会找到 tar 包的 hash,根据 hash 再去找缓存的 tar 包,并再次通过pacote把对应的二进制文件解压到相应的项目 node_modules 下面,省去了网络下载资源的开销。

注意

这里提到的缓存策略是从 npm v5 版本开始的。在 npm v5 版本之前,每个缓存的模块在 ~/.npm 文件夹> > 中以模块名的形式直接存储,储存结构是:{cache}/{name}/{version}。

npm的使用技巧

配置 npm init 默认字段来自定义 npm init 的内容

npm config set init.author.name "test"
npm config set init.author.email "test@gmail.com"
npm config set init.author.url "test.com"
npm config set init.license "MIT"

更多信息见:npm-config

利用 npm link,高效率在本地调试以验证包的可用性

使用 npm link可以将模块链接到对应的业务项目中运行,从工作原理上总结,npm link 的本质就是软链接,它主要做了两件事:

  • 为目标 npm 模块创建软链接,将其链接到全局 node 模块安装路径 C:\Users\用户名\AppData\Roaming\npm\node_modules(mac在/usr/local/lib/node_modules/)中
  • 为目标 npm 模块的可执行 bin 文件创建软链接,将其链接到全局 node 命令安装路径 /usr/local/bin/ 中。

npx 的作用

npx 由 npm v5.2 版本引入,解决了 npm 的一些使用快速开发、调试,以及项目内使用全局模块的痛点。

在传统 npm 模式下,如果我们需要使用代码检测工具 ESLint,就要先通过 npm install 安装

npm install eslint --save-dev

然后在项目根目录下执行:

./node_modules/.bin/eslint --init
./node_modules/.bin/eslint yourfile.js

而使用 npx 就简单多了,你只需要下面 2 个操作步骤:

npx eslint --init
npx eslint yourfile.js

这是因为它可以直接执行 node_modules/.bin 文件夹下的文件。在运行命令时,npx 可以自动去 node_modules/.bin 路径和环境变量 $PATH 里面检查命令是否存在,而不需要再在 package.json 中定义相关的 script。

npx 另一个更实用的好处是:npx 执行模块时会优先安装依赖,但是在安装执行后便删除此依赖,这就避免了全局安装模块带来的问题。
例如我们使用create-react-app创建工程。

npx create-react-app cra-project

npx 会将 create-react-app 下载到一个临时目录,使用以后再删除

相关文章

<think> 我们正在解决npm无法拉取webworkify-webpack的问题。首先需要分析可能的原因,常见的包括网络问题、包名错误、版本兼容、npm源问题等。 根据问题描述,用户在使用npm安装webworkify-webpack时失败。我们首先要确认包的正确名称和安装命令。 步骤1:确认包名称 在npm官网上查找webworkify-webpack包,确认其存在且名称正确。通过npm官网查询,我们知道正确的包名是`webworkify-webpack`(注意:实际中可能存在大小写或拼写错误,但npm包名通常是小写的)。 步骤2:尝试常规解决方法 a. 清除npm缓存:有时缓存可能导致安装问题。 命令:`npm cache clean --force` b. 更新npm到最新版本:旧版本npm可能存在bug。 命令:`npm install -g npm@latest` c. 切换npm源:如果使用的是官方源速度慢或可访问,可以切换到国内镜像源(如淘宝npm镜像)。 设置淘宝源:`npm config set registry https://registry.npm.taobao.org` 或者,如果使用官方源:`npm config set registry https://registry.npmjs.org` d. 尝试使用cnpm(淘宝的npm客户端):如果网络问题导致无法从官方源下载,可以使用cnpm。 安装cnpm:`npm install -g cnpm --registry=https://registry.npm.taobao.org` 然后使用cnpm安装:`cnpm install webworkify-webpack` e. 检查网络连接:确保网络可以访问npm仓库。 步骤3:如果上述方法无效,考虑包已被废弃或更名 在npm官网上搜索webworkify-webpack,我们发现这个包已经有一段时间没有更新了,而且有一个更流行的替代包`workerize-loader`(但这是必须的,我们还是要解决当前包的问题)。 步骤4:查看错误信息 用户提供的错误信息是关键。常见的错误包括: - 404 Not Found: 包名错误或包已被移除。 - 连接超时: 网络问题或源地址可达。 - 其他错误(如权限问题):可能需要使用sudo(推荐)或修改npm的默认目录权限。 步骤5:尝试安装特定版本 如果最新版本安装失败,可以尝试安装旧版本(先查看有哪些可用版本): 查看版本:`npm view webworkify-webpack versions` 安装特定版本:`npm install webworkify-webpack@<version>` 步骤6:如果包已被废弃,考虑替代方案 如果确认包已被废弃,可以寻找替代包。例如,`workerize-loader`或`webpack-worker`等。 根据以上步骤,我们给出一个综合的解决方案。 解决方案: 1. 首先,尝试清除缓存并更新npm: ``` npm cache clean --force npm install -g npm@latest ``` 2. 切换为淘宝源(国内用户推荐): ``` npm config set registry https://registry.npm.taobao.org ``` 3. 再次尝试安装: ``` npm install webworkify-webpack ``` 4. 如果仍然失败,使用cnpm: ``` npm install -g cnpm --registry=https://registry.npm.taobao.org cnpm install webworkify-webpack ``` 5. 如果以上方法都无效,检查错误信息。如果是404,那么包可能存在(可能是拼写错误)。注意,正确的包名是`webworkify-webpack`(全小写)。如果包确实存在,考虑使用替代包。 6. 替代方案:如果无法安装`webworkify-webpack`,可以考虑使用`worker-loader`(Webpack官方维护的worker loader)或`workerize-loader`。 例如,安装`worker-loader`: ``` npm install worker-loader --save-dev ``` 然后在webpack配置中配置它。 注意:在webpack配置中使用worker-loader的示例: ```javascript module.exports = { module: { rules: [ { test: /\.worker\.js$/, use: { loader: 'worker-loader' } } ] } } ``` 7. 如果遇到权限问题,可以尝试修复npm权限(避免使用sudo),参考:https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally 8. 如果使用的是Windows系统,可能是路径过长问题,可以尝试: ``` npm install --save webworkify-webpack --no-optional ``` 9. 如果包已经再维护且找到,可以考虑直接使用Web Worker的API,或者使用其他类似的库。 根据社区反馈,`webworkify-webpack`这个包可能已经再维护,所以使用替代方案可能是更好的选择。 相关问题: 1. 如何解决npm安装包时的网络问题? 2. 如何使用淘宝npm镜像源? 3. 有哪些替代webworkify-webpack的包? 4. 在Webpack中如何使用Web Worker? 如果用户提供具体的错误信息,可以进一步针对性解决。 </think> ### 解决 npm 安装 webworkify-webpack 失败的方案 #### 📌 核心问题分析 `webworkify-webpack` 是一个将模块转换为 Web Worker 的 Webpack 插件。安装失败通常由以下原因导致: 1. **网络问题**:npm 源访问稳定或包被墙 2. **依赖冲突**:与当前 Node.js 或 Webpack 版本兼容 3. **包已废弃**:该包最后一次更新是 5 年前(2018 年),可能已被社区弃用 [^1] --- #### 🔧 解决方案步骤 ##### 1️⃣ **检查 npm 源和网络** ```bash # 查看当前源 npm config get registry # 切换淘宝源(国内推荐) npm config set registry https://registry.npmmirror.com # 清除缓存后重试 npm cache clean --force npm install webworkify-webpack ``` ##### 2️⃣ **确认环境兼容性** ```bash # 检查 Node.js 和 npm 版本 node -v # 需 ≥ v14.x npm -v # 需 ≥ 6.x # 检查 webpack 版本(若已安装) npx webpack --version # 需兼容 webpack@4 ``` > 💡 **注意**:该包仅兼容 Webpack 4,若使用 Webpack 5 需改用替代方案 [^2] ##### 3️⃣ **尝试指定旧版本安装** ```bash # 安装较稳定的历史版本 npm install webworkify-webpack@2.1.1 --save-dev ``` ##### 4️⃣ **替代方案(推荐)** 由于该包已过时,建议使用现代替代品: ```bash # 方案1:官方 worker-loader(Webpack 5+) npm install worker-loader --save-dev # 方案2:vite风格的轻量方案 npm install @webworker/webpack --save-dev ``` ##### 5️⃣ **手动安装(终极方案)** 1. 访问 [npm 包页面](https://www.npmjs.com/package/webworkify-webpack) 2. 下载最新版 `.tgz` 文件 3. 本地安装: ```bash npm install /path/to/webworkify-webpack-2.1.1.tgz ``` --- #### ⚠️ 常见错误处理 | 错误类型 | 解决方案 | |--------------------------|----------------------------------| | `ERR! 404 Not Found` | 切换 npm 源或确认包名拼写 | | `ERR! Unsupported engine`| 降级 Node.js 或使用 `--force` 安装 | | `Module not found` | 检查 Webpack 配置是否包含 loader | --- #### 💡 最佳实践建议 对于新项目,**推荐迁移到 Webpack 5 的 Worker 系统**: ```javascript // webpack.config.js module.exports = { module: { rules: [{ test: /\.worker\.js$/, use: { loader: 'worker-loader' } }] } } ``` > ⚠️ 注意:Webpack 5 已内置 [Web Workers 支持](https://webpack.js.org/guides/web-workers/),无需额外插件 [^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值