如果你在Windows上刚刚接触Node.js,大概率会遇到这样一个场景:装好Node之后,打开PowerShell想跑个npm -v看看版本,结果屏幕直接给你一行红色错误:"npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。" 我当年第一次装Node.js,被这行字卡了一下午,重装了三遍都没用,甚至一度以为是安装包有毒。后来才明白,真正的问题出在Windows PowerShell的"执行策略"上,和Node.js本身一点关系都没有。
这篇笔记,就是把我从零开始装配Node.js环境的整个过程记录成文。内容包括版本怎么选、安装包怎么挑、全局目录怎么规划、npm执行脚本报错怎么解决、第一个项目怎么跑起来、多版本怎么管理。只要你准备在Windows上学习或使用Node.js,这篇内容应该能帮你少走不少弯路。我会尽量少说概念术语,多用实际操作说话。
1. 初装Node.js前,先理清这几个基础概念
1.1 Node.js到底是什么,为什么前后端都用它
很多人第一次接触Node.js,是从"前端要学Node"这句话开始的。它本质上是一个运行环境,让JavaScript可以脱离浏览器,在电脑上直接执行。以前JavaScript只能在浏览器里操作网页,有了Node.js之后,你就能用它读写文件、启动服务、操作数据库,甚至写命令行工具。所以无论你现在是想学前端工程化,还是想用JS写后端接口,Node.js都是绕不开的一环。
我遇到不少初学者喜欢先啃概念,动手装环境反而随便,结果一上来就被报错劝退。这里我的建议是:先把"Node.js是JS的运行时、npm是它的包下载器"这两点记住就够了,剩下的都是在实际使用中慢慢理解的。不用先去研究事件循环、非阻塞I/O那些底层机制,那都是后话。等你的项目跑起来,遇到性能问题再回头看,比一开始钻牛角尖有效得多。
1.2 npm和Node.js的关系,以及那个特别的npm.ps1
npm全称是Node Package Manager,它会随着Node.js安装包一起装好。它的作用是帮你下载和管理别人写好的JavaScript模块,你把依赖写在package.json里,npm负责把对应的包拉下来放进node_modules文件夹。类比一下:Node.js是操作系统,npm就是应用商店。没有npm,你就得手动去一个个下载源码、手动处理依赖关系,那基本等于回到原始时代。
问题来了:在Windows上安装完Node.js后,你会在安装目录里看到好几个跟npm有关的文件,最简单的有npm、npm.cmd、npm.ps1。这三个名字看起来差不多,但各有用途:npm是Shell脚本,主要给Unix类系统用;npm.cmd是给CMD调用的批处理;npm.ps1是给Windows PowerShell用的脚本。PowerShell为了安全,默认会限制.ps1脚本的执行,一旦你的系统策略是"禁止运行脚本",那么当你敲npm时,PowerShell尝试加载npm.ps1就被拒绝了。所以你会看到那种很吓人的红字报错,但CMD里却一切正常。理解这个原理,后面排查问题就有方向了。
2. 安装与验证:从下载到node -v的全部细节
2.1 LTS还是Current:不同场景下的选择策略
打开Node.js官网,首页会给你两个下载按钮,一个标着LTS,一个标着Current。LTS是Long Term Support的意思,这类版本会得到长期维护,API稳定,大部分生产环境都会用LTS。Current则是最新功能版本,能提前用上新特性,但可能不够稳定,升级大版本时也可能出现兼容性问题。
我给新手的建议很直接:默认选LTS。尤其是你要用来练习、学习、做毕业设计或者公司项目,LTS是最稳妥的。只有在你明确需要某个新语法或新API,并且愿意承担小概率踩坑的时候,才去碰Current。我自己就干过傻事,装了最新Current版本跑老项目,结果某个依赖怎么都装不上,最后查了半天是Node版本太新。从那以后,我本机默认装LTS,需要测新特性再切版本。
2.2 下载渠道和安装包类型,我推荐哪一类
Node.js的下载渠道有官方站和国内镜像。官方站下载地址是nodejs.org,如果你的网络下载速度一般,也可以用npmmirror提供的二进制镜像,也就是很多人熟知的淘宝镜像,里面会同步Node.js的各个发行版本。但要注意,镜像站只提供文件,文档和更新日志还是以官方为准。
安装包形式通常有两种:.msi和.zip。.msi是Windows安装程序,双击之后一路Next,会自动帮你把Node.js和npm装好,还会写入系统环境变量PATH,适合绝大多数人。.zip是绿色解压版,解压后需要手动把node.exe所在目录加进PATH,适合想完全掌控文件结构的高级用户。如果你是第一次装,直接选.msi,不用犹豫。
2.3 安装完成后,先别急着跑npm,按这个顺序验证
安装过程没什么特殊的,基本就是同意协议、选择安装路径、点下一步。有一点需要提醒:安装路径尽量不要选带中文的目录,虽然很多情况下中文路径也能跑,但后续一旦出问题,排查起来会非常痛苦。默认的C:\Program Files\nodejs虽然有空格,但这是Node官方支持过的路径,npm自己也在这个目录下,一般没问题。
装完后先打开CMD,不是PowerShell,是CMD。输入node -v,如果输出类似v20.18.1的版本号,说明Node.js本体装好了。接着输入npm -v,如果也输出版本号,说明npm正常。为什么要先用CMD验证?因为CMD不会加载.ps1脚本,即使你PowerShell执行策略有问题,CMD里的npm大概率也是正常的。这样能帮你快速把问题范围缩小:如果CMD里两个命令都正常,那Node.js环境就没坏,出错的地方多半是PowerShell配置。
3. 把全局包和缓存目录迁出C盘,环境变量一次配好
3.1 为什么要迁移:全局包塞满C盘的惨痛教训
默认情况下,npm的全局包会安装到Node.js安装目录下的node_modules里,或者用户目录下的AppData文件夹里。一开始你可能没感觉,等到你开始大量安装全局工具包,比如http-server、nodemon、vue-cli、create-react-app,C盘空间会一点一点被吃掉。更麻烦的是,有些工具在系统盘目录下需要管理员权限才能写入,运行命令时经常会有各种权限问题。
我自己的电脑C盘是SSD,容量本来就不大,有段时间频繁装全局工具,装了一圈下来发现C盘少了几个G。后来一气之下把所有npm全局包和缓存都迁到了D盘,从此清净了。建议大家从一开始就规划好目录,别等到C盘爆红再折腾。迁移这件事本身不难,难的是下定决心,因为改完之后旧工具可能需要重装。
3.2 新建目录并读取当前配置
先确定两个目录,一个是全局包存放目录,一个是npm缓存目录。比如我想把这两个目录放在D:\Nodejs\global和D:\Nodejs\cache,就先在D盘把这两个文件夹建好。建完之后可以在命令行里用两条命令确认当前npm的配置指向哪里:
npm config get prefix npm config get cache通常你会看到npm默认的prefix是Node.js安装目录,cache是用户目录下的npm缓存目录。接下来就要把这两个路径改掉。改之前记住旧路径也有用,因为万一你想回退,还能找到原来的位置。
3.3 修改npm全局前缀和缓存位置并配置系统变量
执行下面两条命令,把prefix和cache指到新建的目录:
npm config set prefix "D:\Nodejs\global" npm config set cache "D:\Nodejs\cache"执行完可以用npm config get prefix和npm config get cache确认是否生效。但这只是改了npm内部的配置,系统还不认识D:\Nodejs\global里的命令。接下来打开系统属性里的环境变量设置,在用户变量或系统变量的Path中新增一行D:\Nodejs\global。同时,再新建一个环境变量名为NODE_PATH,值设为D:\Nodejs\global\node_modules。
NODE_PATH的作用是让Node.js在解析模块时能感知到全局包的位置。以后如果你用npm install -g装了某些全局工具,它们生成的可执行文件会放进D:\Nodejs\global,依赖模块则待在D:\Nodejs\global\node_modules里。配置完之后,需要重新打开一个终端窗口,环境变量才会刷新。然后可以随便全局装个小工具测一下,比如npm install -g http-server,再执行http-server --version,只要能输出版本号,说明系统已经能识别新路径了。
4. 遇到npm.ps1权限报错,完整排查与三种解法
4.1 报错复现:什么情况下最容易触发
在新装的Windows系统里,PowerShell默认的执行策略是Restricted,也就是禁止运行所有.ps1脚本。所以只要你在PowerShell里敲npm、npm install、npm run dev这类命令,一旦内部要走npm.ps1,就会被策略拦下来,显示类似这样的一段话:
npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。 有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。 + CategoryInfo : SecurityError + FullyQualifiedErrorId : UnauthorizedAccess很多人看到SecurityError就以为是杀毒软件或者权限问题,其实不是。它仅仅是PowerShell认为运行这个脚本不合规,和Node.js本身没有任何关系。
4.2 排查链路:先分清是npm问题还是PowerShell问题
遇到这个报错,我们可以按这样一个顺序排查:
- 先跑
node -v,如果正常,说明Node.js的核心文件没问题。 - 再跑
npm.cmd -v,注意是带.cmd后缀的npm。如果这个能输出版本号,说明npm也没有问题,只是PowerShell不走.cmd,只认.ps1。 - 在PowerShell里运行
Get-ExecutionPolicy,如果返回Restricted,就基本可以确定是执行策略的锅。 - 运行
Get-ExecutionPolicy -List,可以查看当前用户、本地机器等不同作用域下的策略,有时候某个策略里已经对外开放了,但另一个作用域还在限制。
这样排查完,你就能很清楚地知道:问题不是出在Node.js,而是出在PowerShell的安全策略。知道根因之后,选一种解法就行。常见的情况可以简单对个表:
| 症状 | 可能原因 | 下一步操作 |
|---|---|---|
| node -v 正常,npm -v 报错 | PowerShell执行策略限制 | 检查Get-ExecutionPolicy |
| CMD里npm正常,PowerShell报错 | 只影响PowerShell | 修改CurrentUser执行策略 |
| CMD里npm也不认识 | 环境变量PATH没配好 | 检查Node.js安装目录是否在PATH |
| npm install超时或连接拒绝 | 网络到官方源不稳定 | 切换镜像源 |
4.3 解法一:调整当前用户的执行策略(最推荐)
最常用的做法是只调整当前用户的执行策略,不改系统级别的配置。操作也很简单,在PowerShell窗口里运行:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser系统会询问是否要更改执行策略,输入Y回车确认。之后再运行npm -v就能正常输出了。
这里解释一下RemoteSigned的含义:它允许运行本地创建的脚本,也可以运行从网络下载的脚本,但网络下载的脚本必须带有可信数字签名。npm.ps1是Node.js安装时写在你本地的文件,所以属于"本地脚本",可以被正常执行。相比Unrestricted,RemoteSigned已经安全很多。这也是微软官方比较推荐的一个策略组合。
有一点要注意:如果你用的Scope是LocalMachine,那通常需要管理员权限;但CurrentUser作用域只需要当前用户权限即可,不用专门右键"以管理员身份运行"。
4.4 解法二:直接用CMD或Git Bash绕过PowerShell
如果你并不想修改PowerShell的任何策略,另一个简单粗暴的办法就是:以后不要用PowerShell跑npm,直接用CMD、Git Bash或Windows Terminal里新建的CMD窗口。CMD执行的是npm.cmd,根本不经过PowerShell的脚本策略检查,所以不会报这个错。
很多前端工具链命令在CMD里都能正常运行,比如npm install、npm run build。但如果你在项目里配了某些需要PowerShell特性的脚本,比如自定义的ps1脚本,那还是得彻底解决执行策略问题。我的个人习惯是:日常命令行工具窗口用Windows Terminal,默认启动PowerShell,所以最终还是把策略调成了RemoteSigned,一劳永逸。
4.5 解法三:修改npm的脚本shell,或者直接调用npm.cmd
还有一类情况是,PowerShell执行策略本身没问题,但你看到某个脚本文件带.ps1后缀被阻止,可能是在运行npm run xxx时,npm内部用了PowerShell去执行package.json里的脚本。这时可以在npm配置里指定shell:
npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"这样npm在执行脚本时会走Git Bash,而不是PowerShell。前提是你本机装了Git Bash。
临时应急时,也可以在PowerShell里直接敲npm.cmd -v,或者在Node安装目录下找到npm.cmd,用完整路径调用。不过这些方案都绕不开一个事实:你的PowerShell策略始终在限制脚本执行。所以我的建议还是优先改执行策略,这不是什么危险操作,只要选对作用域和策略级别,安全性是可控的。
5. 跑通第一个项目:npm init到依赖安装的完整链路
5.1 用npm init生成package.json,字段含义与默认值
环境配好之后,我们来跑一个最小的项目。先在某个工作目录下新建一个文件夹,然后进入这个文件夹,运行:
npm init -y-y表示跳过交互式提问,直接生成一份默认的package.json。打开它,你会看到类似这样的内容:
{ "name": "my-project", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }这些字段里,name是项目名,version是版本号,main是入口文件,scripts可以定义常用命令。很多初学者不关心package.json是怎么来的,直接复制别人的配置,这样也可以,但自己动手过一遍,理解每个字段干嘛用的,后面遇到问题时能少走很多弯路。
5.2 安装依赖的完整链路:dependencies与devDependencies
在项目里安装一个运行时依赖,最经典的例子是Express:
npm install express执行完你会发现文件夹里多了一个node_modules目录,package.json里也多了一条依赖。node_modules里放着Express以及它的所有依赖包,这就是npm帮你下载好的代码。如果你装的是只在开发阶段用到的工具,比如代码热重载工具nodemon,推荐安装到devDependencies:
npm install -D nodemondependencies里的包是生产环境运行时要用的,devDependencies里的包只在开发构建时需要。区分它们很重要,比如部署到服务器时,通过npm install --production可以只装生产依赖,避免把一堆开发工具也拖到线上。
5.3 锁定版本与package-lock.json的意义
装完依赖后,项目里还会多一个package-lock.json文件。它记录了每个实际安装的依赖的精确版本号,包括依赖的依赖。这个文件建议提交到Git仓库里,这样别人拉下代码后执行npm install,可以装出跟你本地完全一样的版本,避免出现"我这边跑得好好的,你那边就是起不来"的版本不一致问题。
如果以后想把依赖清理重装到锁定版本,可以用:
npm cinpm ci会严格按照package-lock.json里的版本安装,并且会先删除node_modules再重新安装,速度通常比npm install更稳定。我第一次遇到npm ci,是接手一个老项目时同事告诉我的,当时npm install总报依赖冲突,换成npm ci后一口气就好了,所以印象很深。
5.4 换镜像源提速,以及常见报错
国内下载npm包经常很慢,官方源是https://registry.npmjs.org/,网络不好时会出现各种超时错误。办法是把registry切换到国内镜像,我目前比较常用的是npmmirror的源:
npm config set registry https://registry.npmmirror.com设置完之后,可以用npm config get registry确认。这样一来,npm install的下载速度会有明显提升。如果你只想在某个命令里临时换源,不用全局改,可以直接在install时加参数:
npm install express --registry=https://registry.npmmirror.com常见的安装报错我遇到过这几种:ECONNREFUSED一般是网络或代理问题;ETIMEDOUT是超时;ERESOLVE通常是依赖版本冲突,可以试试npm install --legacy-peer-deps,或者用npm update后再装。如果怀疑是缓存坏了,可以执行npm cache clean --force再重新安装。这些都是老生常谈,但在紧急情况下真的能救命。
6. 安装进阶:nvm多版本切换与镜像源提速
6.1 为什么用nvm-windows,而不是Linux/Mac上的nvm
很多教程提到"用nvm管理Node版本",但Linux和macOS上的nvm是一个Shell脚本,而Windows上的nvm-windows是另一套独立的工具,两者并不是同一个实现。如果你在Windows上去搜nvm install的教程,一定要确认对方用的是不是nvm-windows,否则可能看了半天还是装不上。
nvm-windows的安装包可以到它的GitHub仓库下载,装完之后,先用管理员权限打开CMD或PowerShell,然后就可以执行:
nvm install 20.18.1 nvm install 22.11.0 nvm use 20.18.1nvm ls能列出当前已装的版本,nvm current能查看当前正在用的版本。日常开发中,有时候老项目需要低版本Node,有时候新项目要求高版本,靠nvm-windows来回切换是非常高效的。
6.2 安装nvm-windows前,必须先卸载已有Node.js
这一点特别关键。如果你已经用安装包装过Node.js,在装nvm-windows之前,最好先把原来的Node.js卸载干净,包括删掉系统环境变量里的Node路径,否则nvm通过符号链接切换版本时会跟旧安装冲突。我自己就踩过一次:当时舍不得卸载旧版Node,装完nvm后一执行nvm use,跑node -v还是旧版本,排查了很久才意识到是旧安装残留的PATH排在前面,把nvm的链接路径盖住了。
卸载干净之后,再安装nvm-windows,然后安装你需要的Node版本。注意,nvm-windows本身安装的目录最好也不要有中文,否则后续装版本时可能出现权限或路径识别问题。
6.3 日常切换版本与全局包处理
切换版本后,有一个容易被忽略的问题:全局包不会自动跟着新版本走。比如你在Node 20里全局安装了nodemon,切到Node 22后,再想运行nodemon可能就提示"不是内部或外部命令"了。这是因为每个Node版本安装后,全局包目录是独立的。
解决方案有两个:一是切换版本后手动重新安装所需的全局包;二是尽量少用全局包,把项目依赖放在项目内的node_modules里,用npx来调用临时工具。npx是npm自带的命令,它会在当前项目里找命令,找不到时会临时下载并执行,用完即走,特别适合不想污染全局环境的人。
6.4 镜像源配置的完整命令与注意事项
nvm-windows本身下载Node.js发行版时,走的也是官方源,国内经常很慢。可以通过设置环境变量来加速:
NVM_NPMJS_MIRROR=https://registry.npmmirror.com NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node/设置前者的作用范围是npm包镜像,设置后者的作用范围是Node.js二进制发行版镜像。具体变量名视nvm-windows版本略有差异,建议安装后先看下它的README。设置完环境变量,需要重新打开终端再执行nvm install,不然有可能不生效。
这里要特别提醒:不要把"npm源"和"nvm的Node二进制源"混为一谈。npm config set registry只能加速npm安装JavaScript依赖包的速度;而nvm下载的是Node.js本身的压缩包,换的是另一个镜像地址。两个都配置好,整个流程才会顺畅。
说到最后,我还想补充一个个人经验:每次配置完环境变量或者nvm切换版本后,别急着开干,先执行node -v、npm -v确认当前环境,再跑项目。这个习惯帮我省了很多"为什么明明装了还提示找不到"的排查时间。Node.js环境这件事,看着简单,但每个小细节都可能成为坑点。把基础打扎实,后面不管是学框架还是写脚本,都会顺畅很多。