前端架构: 从vue-cli探究脚手架原理

从使用角度理解什么是脚手架

  • 脚手架本质是一个操作系统的客户端
    • 在终端中去执行一个命令,这个命令本身它就是一个客户端
    • 我们其实可以把脚手架理解为操作系统的一个客户端
    • 通过命令去执行它的时候,这个命令往往是这样的一个构造,如下
  • 比如:要创建一个vue的项目的时候, $ vue create vue-test-app
    • 上面这条命令由3个部分组成
      • 主命令: vue
      • command: create
        • 这个 command 是子命令,实际上它向脚手架(主命令)发送一个请求
        • 这个请求,让我们的脚手架帮我们完成一个动作,完成这个动作,就是create创建项目
      • command的param: vue-test-app
        • 建什么项目呢?看这第三个参数,在command后面,又加了一个空格,输入了一个参数
    • 这个命令输入完以后,脚手架会给我们一定的反馈, 比如说会让我们做一些选择,或者会帮我们执行一些操作等等
    • 它表示创建一个vue项目,项目名称为 vue-test-app
  • 以上是一个较为简单的脚手架命令,但实际场景往往更复杂,比如:
    • 当前目录已经有文件了,我们需要覆盖当前目录下的文件,强制进行安装 vue 项目,此时我们就可以输入
    • $ vue create vue-test-app --force
      • --force 叫做 option, 用来辅助脚手架确认在特定场景下用户的选择(可以理解为配置)
      • 如果加入了 --force,就等于告诉脚手架创建项目的时候,可以强制进行覆盖
      • 如果没加 --force, 那么脚手架的执行就会中断。因为你没有强制覆盖,而我当前又有文件,所以我就会中断
      • 其实 --force 可以理解为 --force true, 简写为:--force-f
  • 还有一种场景, 通过 vue create 创建项目时,会自动执行 npm install 帮用户安装依赖
    • 如果我们使用淘宝源来安装,就可以输入命令 vue create vue-test-app --force -r https://registry.npm.taobao.org
    • 这里的 -r 也是 option, 它与 --force 不同的是它使用 -,并且使用简写
    • 这里 -r 也可替换成 --registry,同时,我们可以通过 vue create --help 来查看其他可用命令
    • -r https://registry.npm.taobao.org 后面的 https://registry.npm.taobao.org 成为 option的param

脚手架原理

  • 我们需要理解输入了 $ vue create vue-test-app 之后,为什么会发生一系列的事情

  • 我们先要理解整个 vue 脚手架的体系,如下图

  • 通过 $ which vue 可看到 /usr/local/bin/vue, 这里的vue其实是一个软连接
    • 参考:vue -> …/…/…/Users/xxx/.config/yarn/global/node_modules/.bin/vue
    • 前面的 vue 其实执行的就是后面路径里的vue命令
  • 程序员在终端中输入 $ vue create vue-test-app
  • 终端解析出 vue 命令
  • 终端在环境变量中找到 vue 命令
  • 终端根据 vue 命令链接到实际文件 vue.js
  • 终端利用 node 执行 vue.js
  • vue.js 解析 commond / options
  • vue.js 执行 commond
  • 执行完毕,退出

从应用角度开发

  • 以 vue-cli 为例开发一个脚手架

    • 比如:/Users/johnny/.config/yarn/global/node_modules/@vue/cli
  • 其目录结构

    LICENSE
    README.md
    bin
    lib
    node_modules
    package.json
    
  • 需要开发一个 npm 项目,该项目中应包含一个 bin/vue.js 文件,并将这个项目发布到 npm

  • 将 npm 项目安装到 node 的 lib/node_modules,或者如: /…/yarn/global/node_modules

  • 在 node 的 bin 目录下配置 vue 软链接指向 lib/node_modules

  • 在执行vue命令的时候,就可以找到 vue.js 进行执行,这样一个板顶关系,在package.json中

    {"bin": {"vue": "bin/vue.js"}
    }
    
  • 这个就是 vue 和 vue.js 之间的绑定关系

  • 这就是为什么全局安装 @vue/cli 后会添加的命令为 vue

  • $ npm i -g @vue/cli 全局安装 @vue/cli 时发生了什么?

    • 在安装时,会把当前npm包下载到 lib/node_modules
      • 或者如: /…/yarn/global/node_modules 下
    • 之后解析 package.json 中的 bin 属性
    • 创建一个软连接 /usr/local/bin/vue 指向 /../yarn/global/node_modules/@vue/cli/bin/vue.js
  • 执行vue命令时,发生了什么?为何 vue 指向了 js 文件,却可以通过 vue 命令执行它

    • 操作系统,会根据 $ which vue 中的 vue 路径找到 vue执行文件,如果 vue 命令不存在,会报出 command not found 的提示
    • 这个vue执行路径其实是一个软链接,通过这个软连接找到真实的 vue地址,对应的就是 上述 /…/bin/vue.js
    • 这个 vue.js 是一个 js文件,即使有执行权限,也不可直接执行,需要一个 node 的解释器,就是类似 node /…/bin/vue.js
    • 但是很明显,在执行vue命令时,并没有冠以 node 的前缀,直接进入 /…/yarn/global/node_modules/@vue/cli/bin/vue.js
    • 可看到,最顶部有一个声明 #!/usr/bin/env node 这个声明可以直接让 xx.js 文件直接在操作系统执行
    • 意思是,告诉操作系统,在直接调用这个文件的时候,到环境变量中去找 node 命令,类似的,如果是个python文件,将node修改成 python
    • /usr/bin/env 会列出所有环境变量,在这个环境变量列表中找到 node 命令
    • 通过 node 命令来执行这个 js 文件
    • 因此,任何js文件,只要在文件顶部加上这个声明,即可 直接执行 (这里限制在 unix 系统)
    • 此时, ./xx.js 等价于 node xx.js
    • 注意,#!/usr/bin/env node 这样写的好处是
      • 无需关注每一个电脑环境下的node路径
      • 这个也可替换成具体的node路径也是一样的,但是会非常的麻烦,而且换个环境可能就不能用了
      • 所以,还是采用这种方式来处理
  • 现在我们想要用 mycommand (这个是我们自定义脚手架随意举例) 指向 xx.js,就可以通过创建软链接的方式来处理

    • 进入到 /usr/local/bin 目录
    • 创建软链接 $ ln -s /../xx.js mycommand
      • 注意,这里的 /…/xx.js 是当前脚本的路径,替换成自己的即可
    • 可看到当前目录下有一个 imooc 的文件
    • 此时,在系统内任意位置,只需要执行 mycommand 即可运行 xx.js
  • 这个就是我们自定义的脚手架 mycommand 的基本设定

最后,描述一下脚手架命令执行的一个整个过程

脚手架的本质是操作系统上的一个客户端

  • 可以发现脚手架执行起来的过程和前端开发的应用是非常不一样的
  • 其实它和web应用从本质上来讲,没有关系
  • 它们的联系仅仅是脚手架和开发的web应用都是通过 js 这个语言来进行编写的
  • 但其实脚手架它其实是操作系统当中的一种机制
  • 执行脚手架的时候,它其实是被作为一个操作系统上的可执行文件来进行执行的
  • 所以可以说我们开发的脚手架就是操作系统上的一个客户端
  • 我们的脚手架它本质执行起来时候,是依靠 node 这个命令
  • node 是一个操作系统客户端,而我们的 xx.js 仅仅是node的一个参数
  • 换句话说,仅仅是把一个参数注到 node 当中,类似的可以这样 node -e console.log(1) 这样也可以执行
  • 也就是说脚手架是操作系统的客户端,其本质并不是说 xx.js 是一个客户端,而是node本身它是一个客户端
  • 在windows中,node 是 node.exe
  • 在mac中,node 是 node* (*代表可执行文件)
  • 当去执行 node xx.js 的时候,其实是把 xx.js 中的代码变成一个字符串传入到node中
  • 然后 node 对这些字符串进行解析,把它当成一个可执行程序进行执行
  • 这些逻辑全部是预设好的,预设好的逻辑就存放在这个node的可执行文件当中
  • 所以脚手架是客户端,其本质是因为node本身就是客户端

脚手架和在PC上面安装的其他应用或者软件的区别

  • 本质来说没有区别,在操作系统上安装了软件,windows上都是 exe 后缀?
  • 在 macos 上面都是可执行文件,所以本质没有区别
  • 它们的区别仅仅是安装的一些软件会提供一个GUI,像当前终端一样,它会提供一个GUI
  • 而我们的 node 并没有提供 GUI
  • 我们的node是直接通过命令行的方式传入参数来进行执行,仅仅是这样的一个差别
  • 如果想在 nodejs 当中去展示GUI有可能吗?
    • 完全可能我们只需要去调用操作系统的GUI绘制API就可以绘制出窗口来
    • 所以脚手架本质它其实就是个客户端。但注意, 不是我们编写的代码是客户端,而是node本身是客户端

为 node 脚手架创建别名

  • 方式 1,就是通过编写一个软链接,其本身会链接到我们自己编写的一个代码文件上
  • 方式 2,现在继续想给 mycommand 添加一个别名或者对其进行修改
    • 进入到 /usr/local/bin 目录
    • 执行 ln -s ./mycommand mycommand1 这样就可以通过 mycommand1 来执行
  • 可见,软链接是可以嵌套的,基于此可以给当前脚手架起别名

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

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

相关文章

PoW算法,请出示你的证明

口信消息型拜占庭问题的解可以防止 (n - 1) / 3 个坏人 (其中 n 为节点数)作恶,这样一来也是可以通过不断增加节点数来突破 (n - 1) / 3 的限制。为了防止这一行为可以使用区块链技术中的工作量证明(Proof of Work)算法。 原理 PoW算法&…

devc++跑酷小游戏1.2.5

更新了在关卡中的复位和地图的刷新z或Z,存档还是没写出来,文件操作好难!!!!!!!!!!!!!!…

【leetcode热题100】解码方法

难度: 中等通过率: 21.5%题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 题目描述 一条包含字母 A-Z 的消息通过以下方式进行了编码: A -> 1 B -> 2 ... Z -> 26给定一个只包含数字…

continue、break、return的区别

continue、break、return的区别 continuebreakreturn continue 作用&#xff1a;跳过本次循环&#xff0c;继续接下来的循环 for(int i 1;i < 10;i){if(i4){continue;}System.out.print(i " "); } //输出结果为&#xff1a;1 2 3 5 6 7 8 9 10 //4的输出被跳过…

C#中 Combine 静态方法

在C#中&#xff0c;Combine是System.IO.Path类的一个静态方法&#xff0c;用于将多个路径片段组合成一个完整的路径。 Combine方法的详细解释如下&#xff1a; public static string Combine(string path1, string path2);参数&#xff1a; path1&#xff1a;要组合的第一个…

【手写数据库toadb】数据字典的内容结构,它的生成,避免鸡生蛋蛋生鸡的问题,高频访下的性能应对

411 数据字典的作用 ​专栏内容: 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方…

【好玩AI】【Prompt】情人节了,用GPT写个【骂醒恋爱脑】的机器人跟自己对话吧

情人节了&#xff0c;让我们用GPT写个【骂醒恋爱脑】的机器人跟自己对话吧。 通过本文&#xff0c;你能学到&#xff1a; 1. 如何零代码搭建一个自己的机器人Bot 2. 骂醒恋爱脑的高级Prompt 通过本文&#xff0c;你还能得到&#xff1a; 恋爱脑可能被骂醒 为了白嫖&#xff0c;…

Linux下的多线程

前面学习了进程、文件等概念&#xff0c;接下里为大家引入线程的概念 多线程 线程是什么&#xff1f;为什么要有线程&#xff1f;线程的优缺点Linux线程操作线程创建线程等待线程终止线程分离 线程间的私有和共享数据理解线程库和线程id深刻理解Linux多线程&#xff08;重点&a…

【selenium】

selenium是一个Web的自动化测试工具&#xff0c;最初是为网站自动化测试而开发的。Selenium可以直接调用浏览器&#xff0c;它支持所有主流的浏览器。其本质是通过驱动浏览器&#xff0c;完成模拟浏览器操作&#xff0c;比如挑战&#xff0c;输入&#xff0c;点击等。 下载与打…

算法刷题:快乐数

快乐数 .习题链接题目题目解析初始值算法原理我的答案 . 习题链接 快乐数 题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1…

【C语言】解析刘谦春晚魔术《守岁共此时》

今年的春晚上刘谦表演了魔术《守岁共此时》&#xff0c;台上台下积极互动&#xff08;尤其是小尼&#xff09;&#xff0c;十分的有趣。刘谦老师的魔术不仅仅是他的高超手法&#xff0c;还有这背后的严谨逻辑&#xff0c;下面我们来用C语言来解析魔术吧。 源代码 #define _CRT…

已解决ModuleNotFoundError: No module named ‘PIL‘异常的正确解决方法,亲测有效!!!

已解决ModuleNotFoundError: No module named PIL异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 文章目录 问题分析 报错原因 解决思路 解决方法 总结 Python是一个强大的编程语言&#xff0c;拥有丰富的第三方库来扩展它的功能。但有时&…

【笔记】Helm-5 Chart模板指南-13 调是模版

调试模板 调试模板可能很棘手&#xff0c;因为渲染后的模板发送了kubernetes API server&#xff0c;可能会以格式化以外的原因拒绝YAML文件。 以下命令有助于调试&#xff1a; 1、helm lint 是验证chart是否遵循最佳实践的首选工具。 2、helm template --debug在本地测试渲…

Python Flask Web 框架学习笔记+完整项目

Flask是一个轻量级的基于Python的web框架。 我们建议使用最新版本的 Python。Flask 支持 Python 3.8 及更高版本。 官网&#xff1a;欢迎使用 Flask — Flask 文档 &#xff08;3.0.x&#xff09; (palletsprojects.com) 完整项目&#xff1a; 1.简介 Flask 是一个轻量级的…

【实验2】在Hadoop平台上部署WordCount程序

文章目录 实验内容一、实验环境:二、实验内容与步骤(过程及数据记录):5. 分布式文件系统HDFS上的操作5.1 利用Shell命令与HDFS进行交互5.2 利用Web界面管理HDFS6. 分布式文件系统HDFS上的编程实践6.1 安装Eclipse6.2 创建Eclipse工程6.3 编写一个Java应用程序检测HDFS中是否…

敏捷开发和传统开发的区别及工具分享

敏捷开发和传统开发的区别主要体现在以下几个方面&#xff1a; 团队建设不同&#xff1a;敏捷开发以团队为单位&#xff0c;强调团队建设&#xff0c;赋予高度的责任&#xff0c;支持开发、透明的交流环境&#xff1b;传统开发以个人为单位&#xff0c;团队成员之间交付很少。…

201709CSPT5除法

题意&#xff1a;有一个长度为 n n n的序列,对其有 m m m个操作&#xff1a; 1 : 对 [ L , R ] 1:对[L,R] 1:对[L,R]之间所有 v v v的倍数除以 v v v 2 : 对 [ L , R ] 2:对[L,R] 2:对[L,R]之间所有求和 #include<bits/stdc.h> using namespace std; struct node {lon…

笔记本选购配置参数详解

笔记本电脑的选购是一个技术活&#xff0c;涉及到众多的配置参数。本文将为您详细解析笔记本电脑的主要配置参数&#xff0c;帮助您在选购时做出明智的决策。 1. 处理器&#xff08;CPU&#xff09; 处理器是笔记本电脑的核心组件&#xff0c;负责执行计算任务…

单页404源码

<!doctype html> <html> <head> <meta charset"utf-8"> <title>简约 404错误页</title><link rel"shortcut icon" href"./favicon.png"><style> import url("https://fonts.googleapis.co…