关键词:
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
npm 是 node 捆绑的依赖管理器,常用程度可想而知。那么你每天都在 npm/yarn run 的命令到底是如何运行项目的呢?
前端项目中运行 npm run xxx 的时候发生了什么?
大家都知道目前的 node 是捆绑 npm 的。npm 是 node 的依赖管理器,虽然它不是唯一的选择,我们还有 pnpm/yarn/cnpm/ni 。
但是,的依赖管理器都是在解决 npm 的某个痛点。对于 npm 依赖声明文件
package.json
本身是基本没有变化的。
例如我们可以使用
npm run serve
运行某个命令, 也可以使用
yarn serve
运行某个命令。
可以看到在这个地方 yarn 可以省略 run 这个参数。
但是,他们都只是对
package.json
进行解析而已,例如下面的文件,当运行
npm run serve
时,其实就是运行该 json 文件中的
scripts
下的
serve
键对应的命令。
"name": "h5", "version": "1.0.7", "private": true, "scripts": "serve": "vue-cli-service serve" , "dependencies": "axios": "^0.19.2", "vuex": "^3.4.0" , "devDependencies": "node-sass": "^4.12.0"
上面说是 命令
只是用于方便理解,例如:
npm run server # 类似于在命令行运行以下命令 vue-cli-service serve
通过 npm run 与直接运行命令的区别
还是用上面的配置来描述:
"scripts": "serve": "vue-cli-service serve"
npm 在运行
vue-cli-service serve
这条命令的时候,会先在当前
node_modules/.bin
下面看有没有同名的可执行文件,如果有,则使用其运行。
这里我们可以打开这个目录看看:
如果直接在命令行中运行
vue-cli-service serve
这条命令,是不会从 node_modules 中查找可执行程序的。
运行可执行文件
那么什么叫可执行文件呢?上面的图中有很多个同名的 vue-cli-service ,到底是运行哪个?
我们先来分析这几个文件怎么来的?
例如
@vue/cli-service
有以下
package.json
文件,注意 bin 字段,当我们运行
npm i @vue/cli-service
这条命令时,npm 就会在
node_modules/.bin/
目录中创建好以
vue-cli-service
为名的几个可执行文件了。
"name": "@vue/cli-service", "version": "4.4.6", "description": "local service for vue-cli projects", "main": "lib/Service.js", "typings": "types/index.d.ts", "bin": "vue-cli-service": "bin/vue-cli-service.js"
对于可执行这个定义,每个系统不一样。在 windows 系统上,可执行文件是通过组策略和环境变量决定的。
使用
set pathext
可以查看
pathext
这个环境变量,他定义了可以作为可执行文件的后缀。
# 查看可执行文件后缀 set pathext
由上面的配置可以发现,我们常见的 exe 也在其中,这个可执行文件在 windows 上,在命令行中输入文件名或双击时即可以运行。
在 unix 系统上面,是通过设置文件的属性为可执行,再在文件中的第一行声明解释器来运行的。
如果我们在 cmd 里运行的时候,windows 一般是调用了
vue-cli-service.cmd
这个文件,这是 windows 下的批处理脚本:
@ECHO off SETLOCAL CALL :find_dp0 SET _maybeQuote=" IF EXIST "%dp0%\\node.exe" ( SET "_prog=%dp0%\\node.exe" ) ELSE ( SET _maybeQuote= SET "_prog=node" SET PATHEXT=%PATHEXT:;.JS;=;% ) %_maybeQuote%%_prog%%_maybeQuote% "%dp0%\\..\\_@vue_cli-service@4.4.6@@vue\\cli-service\\bin\\vue-cli-service.js" %* ENDLOCAL EXIT /b %errorlevel% :find_dp0 SET dp0=%~dp0 EXIT /b
所以当我们运行
vue-cli-service serve
这条命令的时候,就相当于运行
node_modules/.bin/vue-cli-service.cmd serve
然后这个脚本会使用 node 去运行
vue-cli-service.js
这个 js 文件,由于 node 中可以使用一系列系统相关的 api ,所以在这个 js 中可以做很多事情,例如读取并分析运行这条命令的目录下的文件,根据模板生成文件等。
# unix 系默认的可执行文件,必须输入完整文件名 vue-cli-service # windows cmd 中默认的可执行文件,当我们不添加后缀名时,自动根据 pathext 查找文件 vue-cli-service.cmd # Windows PowerShell 中可执行文件,可以跨平台 vue-cli-service.ps1
这里多提了下,在 windows 中 cmd 脚本使用得比较多,兼容性也较好。 powerShell 虽然比较强大,但他运行命令的方式由于和 cmd 命令有较大不同,这会导致你常常搞不清什么命令应该在什么解释器里运行。
示例:运行命令的方式不兼容
示例:windows 很多系统会默认禁止此脚本运行,导致 npm 命令运行错误
所以如果遇到 powerShell 相关错误时建议用 cmd 试试。
注入相关运行时信息
这一节我们通过调试 npm 的源码来进行说明。
首先我们在 mockm 这个前端接口联调工具的源码中先来个 debugger, 注意有从 process.env 中获取 NPM_CONFIG_REGISTRY 这个环境变量,这是 npm 安装时可配置的镜像地址。
然后我们再看一下这个环境变量,在当前系统中是没有定义的。
让我们开始调试 mockm package.json 中的 scripts
npm run s2
"scripts": "s2": "node run.js remote --config=D:/git2/mockm/server/example/full.mm.config.js",
为了节省篇幅,这里直接断点在关键地点:
这是 npm@v6.x 的源码,可以发现 npm 使用了 npm-lifecycle 这个依赖来运行的子进程调用我们的
run.js
文件。
在通过 spawn 运行 run.js 的时候,同时设置了进程相关的一些信息,这是由 node 原生支持的。
例如刚刚说到的 NPM_CONFIG_REGISTRY 环境变量。
下面把继续进入下一个断点, run.js 文件:
可以发现子进程成功获取了父进程给予的信息。
总结
运行 npm run xxx
的时候,npm 会先在当前目录的 node_modules/.bin 查找要执行的程序,如果找到则运行;
没有找到则从全局的 node_modules/.bin 中查找,npm i -g xxx
就是安装到到全局目录;
如果全局目录还是没找到,那么就从 path 环境变量中查找有没有其他同名的可执行程序。
本文转载于:
https://blog.51cto.com/u_15077533/4531157
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
前端启动项目的时候遇到的问题记录
1.问题描述:在执行bowerinstall的时候报错,插件不兼容angular版本解决方法:在.bowerrc文件中添加"ignoredDependencies":["angular"]注意事项:bowerinstall后不安装angular,所以需要手动安装bowerinstallangular#version 2.gruntserve的时候报错:Runnin... 查看详情
单例模式记录
...要作用是对于一个类,在整个项目中只实例化一次,本次记录四种实现方式,并说说优劣性。1.懒汉模式实现:classSingle1//懒汉模式顾名思义,就是比较懒,在类加载的时候不调用实例方法//当真正调用的时候去实例化方法privatest... 查看详情
npminit初始化项目
...用npminit会生成一个pakeage.json文件,这个文件主要是用来记录这个项目的详细信息的,它会将我们在项目开发中所要用到的包,以及项目的详细信息等记录在这个项目中。方便在以后的版本迭代和项目移植的时候会更加的方便。... 查看详情
npm项目install偶有报错导致不能启动应用一般解决办法记录
问题描述有时候前端项目从一个设备迁移到另一个设备上或者从网上克隆前端项目之后我们通常都会npminstall一下,将项目的依赖下载下来之后运行项目。但是,有些时候执行npminstall时会遇到这样或那样的报错,导致... 查看详情
异常处理——把异常记录下来,log4j的使用
...哪一行代码发生了什么异常,严重级别是多少之类的信息记录下来,那么我们就可以在维护时根据这个记录异常的文件针对性地去修复这些异常了。log4j 查看详情
前端博站项目中遇到的问题总结
...每一条留言下面都可以发布评论,因为发布一条评论需要记录很多信息(回复人,留言人,时间,内容,点赞...),想着信息多,为了方便管理,我把他们存放在一个对象中,并将这个对象,放在了data中,结果等我发布信息的时... 查看详情
#yyds干货盘点react工作记录二react中setstate得回调用法
目录前言需求解决方案案例(来源于项目)前言我是歌谣我有个兄弟巅峰的时候排名c站总榜19叫前端小歌谣曾经我花了三年的时间创作了他现在我要用五年的时间超越他今天又是接近兄弟的... 查看详情
将内部可运行类导出到 jar(剪辑)中
...】:2012-11-1807:11:10【问题描述】:我在导出我正在处理的项目时遇到问题,该项目通过实现可运行来调用线程事件的内部类。它在eclipse中可以正常工作,但是导出的时候会启动内部类失败。这只发生在实现可运行的类中。这仅... 查看详情
前端项目性能优化记录~(代码片段)
...之所长,试图把这些骚操作应用在自己的项目中,完事之后记录一下自己的心得感悟(好记性不如烂笔头)文章目录前端性能优化总结前言一、对于一个前端来说,性能优化是什么?二、可感知性能优化1.用户体验(所有用户)2.甜甜... 查看详情
如何获取发生错误的行号,而不是从 Django 中记录错误的行号
】如何获取发生错误的行号,而不是从Django中记录错误的行号【英文标题】:HowtogetthelinenumberwhereerroroccurredinsteadoflinenumberfromwhereerrorloggedinDjango【发布时间】:2017-10-0418:39:59【问题描述】:我在我的django项目中使用日志记录来记... 查看详情
tzxblog博客系统-vue前端项目搭建和要点记录
vue-cli2和vue-cli3(vue-cli4)的一些区别据我目前的了解,创建vue项目,vue-cli不是必须的,但是在实际开发时,几乎就是必须的。vue-cli既可以看做是一种创建vue项目的快捷工具,也可能理解成是vue的一种规范。由于本机的vue-cli安装... 查看详情
记录 Android 应用程序中发生的事件
】记录Android应用程序中发生的事件【英文标题】:LoggingofeventsthatoccurinAndroidapplications【发布时间】:2016-11-1704:48:07【问题描述】:是否有任何Android日志显示当前运行的应用程序中发生了哪些事件并且无法访问应用程序的源代码... 查看详情
nodejs运行前端项目
...们会创建一些小项目,只有几个简单html,没有引入一些前端框架,也没有使用webpack,那我们要如何让代码在我们本地跑起来呢?当然是有很多种方法,IIS、wampserver等等好多都可以用,这里只是说道纯粹用node就把项目跑起来,... 查看详情
vscode怎么为一个前端项目配置ts的运行环境
vsCode为一个前端项目配置ts的运行环境,ts文件保存的时候自动编译成js文件:假设此前端项目名称为Web:文件结构如图1.在根目录中新建一个“.vscode”文件夹,里面建一个“tasks.json”文件,内容为:{//Seehttps://go.microsoft.com/fwlink/... 查看详情
前端模块依赖检查插件项目启动不了时使用(代码片段)
在运行前端项目时,有啥时候在安装完node包之后会出现无法启动的情况,这种一般情况是因为node包安装不完整导致此时可以使用一个插件来检查一下,是否完全安装完毕,插件名字depcheck首先此插件需要全局安装运行以下命令npmi-gdepc... 查看详情
二手前端入门-创建react项目
...准前端工程,过程中遇到了不少麻烦,今天作为笔记一般记录一下遇到的问题和解决方案。基础环境 手头一台Mac使用OSX系统,IDE使用WebStorm,装好了npm安装过程 因为没有很深厚的前端基础,所以学习时候采用crea... 查看详情
如何在构建时在 Blazor 项目中运行 T4 模板
...行良好,但我必须修改并保存模板才能使其再次运行(如记录和预期的那样)。我也想在构建项目的时候运行模板,所以不用VS运行模板,必须是 查看详情
quartz重复执行问题记录
...义的相关的时间表达式的时候)qrtz_triggers表对应的这条记录的状态发生改变,同时下次触发时间根据时间表达式做出改变,同时根据sched_name找到qrtz_job_details表中的具体job去执行网上的解决办法:整个过程就是:当job开始的时候... 查看详情