脚手架原理和基本搭建

什么是脚手架

脚手架本质是一个操作系统的客户端,它通过命令执行,如:

vue create vue-test-app

上面命令由三部分组成

  • 主命令:Vue
  • command:create
  • command 的 parm:vue-test-app

执行此命令后,就会在对应目录下创建一个叫做 vue-test-app 的项目,并自动执行 npm install 按照对应的依赖,通常可以输入下面的命令就可以看到 vue create 支持的所有 options

vue create --help

为什么要研发脚手架?

开发脚手架的核心目标就是:提升前端研发效率

在大的开发团队中,提升研发效率是非常有必要的,减少重复操作劳动,统一代码风格和结构。我们通过脚手架讲研发过程:

  • 自动化:项目重复代码拷贝/git操作/发布上线操作
  • 标准化:项目创建/git flow/发布流程/回滚操作
  • 数据化:研发过程系统化、数据化、使得研发过程可量化

脚手架的执行原理

脚手架的执行原理如下:

  • 在终端输入 vue create vue-test-app
  • 终端解析出 vue 命令
  • 终端在环境变量中找到 vue 命令
  • 终端根据 vue 命令链接到实际文件 vue.js
  • 终端利用 node 执行 vue.js
  • vue.js 解析 command/options
  • vue.js 执行 command
  • 执行完毕退出执行

疑问🤔️

  • 为什么全局安装了 @vue/cli 后会添加的命令为 vue?
npm install -g @vue/cli
  • 全局安装 @vue/cli 时发生了什么?
  • 执行 vue 命令时发生了什么?为什么 vue 指向一个 js 文件,我们却可以通过 vue 命令去执行?

带着问题我们来一一刨析!

这里以我本地 create-react-app 脚手架为演示,在执行命令时,终端首先会执行如下命令进行查找:

which create-react-app

如图,可以看到在环境变量 /usr/local/bin 目录下创建一个了叫做 create-react-app 的软链接

OK,现在让我们进入到对应的目录,看看

在对应目录下我们看到了 create-react-app 项目的目录结构,查看 pack.jsonbin 属性,发现如下

  "bin": {
    "create-react-app": "./index.js"
  },

同样 @vue/cli 也是该原理,到此,我们就可以回到前面两个问题。

全局安装 @vue/clicreate-react-app 时,首先会创建一个软链接,然后指向它真是所在的项目目录,通过上面的图可以看到,通过全局安装会被放在 /yarn/global/node_modules/.bin/ 目录下

通过配置文件 pack.jsonbin 文件,设置命令的名字,如 vuecreate-react-app,cli 就会去执行对应的文件。我们打开 create-react-app 对应的 ./index.js 看看,在头部我们发现这么一行代码

#!/usr/bin/env node

这段代码的作用就是在环境变量中查找 node,然后用 node 去执行,到此基本回到了上面三个问题,下面来进阶一下脚手架原理

脚手架原理进阶

  • 为什么说脚手架的本质操作系统的客户端?它和我们在PC上安装的应用/软件有什么区别?
  • 如何为 Node 脚手架创建别名?

我们知道编写的脚手架JS 文件,必须在 Node 环境中运行,我们找到安装 Node 的目录发现,Node 本身就是一个可执行文件,只不过没有 GUI 可视化的操作页面,它和我们在PC上安装的应用本质没有任何区别

可以通过创建软链接的方式给脚手架创建别名

ln -s ./create-react-app create-react-app2

新起的名字叫做 create-react-app2 会指向 create-react-appcreate-react-app 会指向真实的地方

用一张图总结脚手架执行的全过程.

脚手架开发流程

在之前文章 从零创建自己的脚手架 中实现了一个脚手架的简单搭建和发布,那么有那些难点没有解决呢?

脚手架开发难点解析

  • 分包:将复杂的系统分开成若干个模块

  • 注册命令

    vue add
    vue create
    
  • 参数解析
    • optinos全称:--version、--help
    • options简写:-V、-h
    • 带params的optinos:--path /Users/xikun/Aotu

示例代码:

vue commadn [options] <params>
  • 帮助文档
    • globale help

create-react-app 示例:

sage: create-react-app <project-directory> [options]

Options:
  -V, --version                            output the version number
  --verbose                                print additional logs
  --info                                   print environment debug info
  --scripts-version <alternative-package>  use a non-standard version of react-scripts
  --template <path-to-template>            specify a template for the created project
  --use-npm
  --use-pnp
  -h, --help                               output usage information
    Only <project-directory> is required.

    A custom --scripts-version can be one of:
      - a specific npm version: 0.8.2
      - a specific npm tag: @next
      - a custom fork published on npm: my-react-scripts
      - a local path relative to the current working directory: file:../my-react-scripts
      - a .tgz archive: https://mysite.com/my-react-scripts-0.8.2.tgz
      - a .tar.gz archive: https://mysite.com/my-react-scripts-0.8.2.tar.gz
    It is not needed unless you specifically want to use a fork.

    A custom --template can be one of:
      - a custom template published on npm: cra-template-typescript
      - a local path relative to the current working directory: file:../my-custom-template
      - a .tgz archive: https://mysite.com/my-custom-template-0.8.2.tgz
      - a .tar.gz archive: https://mysite.com/my-custom-template-0.8.2.tar.gz

    If you have any problems, do not hesitate to file an issue:
      https://github.com/facebook/create-react-app/issues/new

还有很多,比如:

  • 命令行交互
  • 日志打印
  • 命令行文字颜色
  • 网络通信:HTTP/WebSocket
  • 文件处理

等等。。。

原生脚手架开发痛点分析

  • 痛点一:重复操作

    • 多Pageage本地link
    • 多Pageage依赖安装
    • 多Pageage单元测试
    • 多Pageage代码提测
    • 多Pageage代码发布
  • 痛点二:版本一致性
    • 发布时版本一致性
    • 发布后相互依赖版本升级

Pageage 越多,管理复杂度越高

脚手架本地link标准流程

链接本地脚手架

cd your-cli-dir
npm link

链接本地库文件

cd your-lib-dir
npm link
cd your-cli-dir
npm link your-lib

取消链接本地库文件

cd your-lib-dir
npm unlink
cd your-cli-dir
# link存在
npm unlink your-lib
# link不存在
rm -rf node_modules
npm install -S your-lib

理解 npm link

  • npm link your-lib:将当前项目中的 node_modules 下指定的库文件链接到 node 全局 node_modules 下的库文件
  • npm link:将项目当前链接到 node 全局 node_modules 中作为一个库文件,并解析 bin 配置创建可执行文件

理解 npm unlink

  • npm unlink:将当前项目从 node 全局 node_modules 移除
  • npm unlink your-lib:将当前项目的库文件依赖移除

Lerna 简介

Learn 是一个优化基于 git + npm 的多 pageage 项目管理的工具,像 bablevue-clicreate-react-app 都使用 Lerna 进行管理

Lerna 开发脚手架流程

基于Lerna创建脚手架

全局安装 Lerna

npm install -g lerna

在项目目录执行 lerna 初始化命令

lerna init

发现会生成一个 lerna.json 文件和 packages 目录,并且为我们初始化了 git 仓库

使用 Lerna 创建一个 package

lerna create core
lerna create utils

在输入 package 的 name,我们选择使用 npm 包组织管理默认,如 @aotu-cli/core、@aotu-cli/utils

如下图在 npm 上注册一个命令 aotu-cli 的组织,这样我们所有的包文件都在它下面

使用 Lerna 添加依赖

// 给所有package依赖依赖
lerna add loadash
// 给指定package依赖依赖
lerna add loadash packages/core

使用 Lerna 移除所有依赖

lerna add loadash

只会删除 node_modules,不会删除 package.json 中的依赖

使用 Lerna 执行所有命令

lerna run test

使用 Lerna 进行批量发布

lerna publish

初次执行会报错,提示告诉我们 执行 git commit

ok,首先在 github 上创建工程并链接到本地进行推送,再次执行 lerna publish

告诉我们需要先进行 npm 登陆,我们执行 npm login 进行登陆,输入账户密码,发现又出现新的报错

这个错误是 npm 要求在发布的时候要求设置环境为原地址,执行以下命令

npm config set registry http://registry.npmjs.org

再次执行 lerna publish,又发现报错

这个错误是因为 Lerna 的项目默认都是私有项目,在每个 packages 的 package.json 里面添加配置

  "publishConfig": {
    "access": "public"
  }

再次执行 lerna publish

如图发布成功,在 npm 进行搜索,找到了我们刚才发布的两个包

Copyright © imooc-lego (2020 - present) all right reserved,powered by GitbookFile Modify: 2021-06-27 08:04:57

results matching ""

    No results matching ""