前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >长文带你深入【前端脚手架开发从原理到实战开发】 | 技术创作特训营第五期

长文带你深入【前端脚手架开发从原理到实战开发】 | 技术创作特训营第五期

原创
作者头像
程序员库里
发布2024-01-19 13:46:51
4176
发布2024-01-19 13:46:51
举报
文章被收录于专栏:全栈学习全栈学习

开发脚手架的核心目标

提升前端研发效能

研发架构图

脚手架核心价值

将研发过程:

1.自动化:项目重复代码拷贝/git操作/发布上线操作

2.标准化:项目创建/git flow/发布流程/回滚流程

3.数据化:研发过程系统化,数据化,使得研发过程可量化

和自动化构建工具区别

问题:jenkins, travis等自动化构建工具已经比较成熟了,为什么还需要自研脚手架?

1.不满足需求:jenkins,travis通常在git hooks中触发,需要在服务端执行,无法覆盖研发人员本地的功能,如:创建项目自动化,本地git操作自动化等。

2.定制复杂:jenkins, travis 定制过程需要开发插件,其过程较为复杂,需要使用java语言,对前端同学不够友好

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

脚手架简介

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

代码语言:javascript
复制
vue create vue-test-app

上面这条命令由3个部分组成:

1.主命令:vue

2.command:create

3.command的param:vue-test-app

它表示创建一个vue项目,项目的名称为:vue-test-app,以上是一个较为简单的脚手架命令,但实际场景往往更加复杂,比如:

当前目录已经有文件了,我们需要覆盖当前目录下的文件,强制进行安装 vue 项目,此时我们就可以输入:

代码语言:javascript
复制
vue create vue-test-app --force

这里的 --force 叫做 option, 用来辅助脚手架确认在特定场景下用户的选择。

还有一种场景:

通过 vue create 创建项目时,会自动执行 npm install 帮用户安装依赖,如果我们希望使用淘宝源来安装,可以输入命令:

代码语言:javascript
复制
vue create vue-test-app --force -r https://registry.npm.taobao.org

这里的 -r 也叫做 option, 它与 --force 不同的是它使用 - , 并且使用简写。这里的 -r 也可以替换成 --registry。

可以通过下面命令查看所有 vue create 支持的所有 options

代码语言:javascript
复制
vue create --help

脚手架执行原理

脚手架的执行原理如下:

1.在终端解析 vue create vue-test-app

2.终端解析出 vue命令

3.终端在环境变量中找到 vue命令

4.终端根据 vue 命令链接到实际文件 vue.js

5.终端利用 node 执行 vue.js

6.vue.js 解析 command/options

7.vue.js 执行 command

8.执行完毕,退出执行

从应用的角度看如何开发一个脚手架

以 vue-cli 为例

1.开发 npm 项目,该项目中应包含一个 bin/vue.js 文件,并将这个项目发布到 npm

2.将 npm 项目 安装到 node 的 lib/node_modules

3.在 node 的 bin 目录下配置 vue 的软连接指向 lib/node_modules/@vue/cli/bin/vue.js

这样在执行 vue 命令的时候就可以找到 vue.js 进行执行。

脚手架的实现原理

1.为什么全局安装 @vue/cli 后添加的命令为vue?

2.全局安装 @vue/cli 时发生了什么?

3.执行 vue命令时发生了什么?为什么 vue指向了一个 js文件 ,我们却可以通过 vue 命令去执行它?

脚手架原理进阶

1.为什么说脚手架本质是操作系统的客户端?

本质是node是操作系统,通过 node -e 来解析js文件

2.如何为node 脚手架创建别名?

创建软连接:ln -s /a.js 别名

3.描述脚手架命令执行的全过程

1.用户在终端输入 vue create vue-test-app

2.终端会在 $PATH 查询 vue 命令。相当于执行 which vue

3.查询实际链接文件

4.通过 /usr/bin/env node 执行文件

脚手架开发流程

开发流程

1.创建 npm 项目

2.创建脚手架入口文件,最上方添加:

代码语言:javascript
复制
#!/usr/bin/env node

3.配置 package.json ,添加 bin 属性

4.编写脚手架代码

5.将脚手架发布到 npm

使用流程

1.安装脚手架

代码语言:javascript
复制
npm install -g your-cli

2.使用脚手架

代码语言:javascript
复制
your-cli

脚手架开发难点解析

  1. 分包:将复杂的系统拆分成若干个模块
  2. 命令注册:
代码语言:javascript
复制
vue create
vue add
...

3.参数解析

代码语言:javascript
复制
vue command [options] <params>

options全称:--version --help

options的缩写: -v -h

带params的options: --path

还有其他:

命令行交互

日志打印

命令行文字变色

网络通信

文件处理

。。。

动手写一个简单的脚手架

1.创建 文件夹 & 初始化 npm 项目

代码语言:javascript
复制
mkdir cli-test
cd cli-test
npm init -y

2.在 根目录 创建 bin/index.js,并在inde.js中 指明 node 环境

代码语言:javascript
复制
#!/usr/bin/env node

console.log('cli test')

3.在package.json中 指定 脚手架名称 和入口文件

代码语言:javascript
复制
"bin": {
    "cli-test": "bin/index.js"
},

4.登录 npm 并发布

5.在终端安装并使用 脚手架

本地调试方法

1.npm link。就是创建软连接

2.在脚手架 上级目录,全局安装后,进行调试。

多个包如何调试?

1.创建两个包,分别是 cli-test 和 cli-test-lib

2.在cli-test-lib,执行npm link

3.进入 cli-test,执行 npm link cli-test-lib 此时就可以在cli-test中使用cli-test-lib了。

4.在 cli-test-lib 中 lib/index.js写个方法

代码语言:javascript
复制
module.exports = {
    sum(a,b){
        return a+b;
    }
}

5.在cli-test中引入 cli-test-lib方法

代码语言:javascript
复制
#!/usr/bin/env node

const lib = require('cli-test-lib');

console.log(lib.sum(1,2))

console.log('cli test')

6.在终端直接执行 cli-test。可以看到执行效果。

脚手架本地link标准流程

链接本地脚手架

代码语言:javascript
复制
cd your-cli-dir
npm link

链接本地库文件

代码语言:javascript
复制
cd your-lib-dir
npm link
cd your-cli-dir
npm link your-lib

取消本地链接脚手架

代码语言:javascript
复制
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:

1.npm link your-lib :将当前项目中 node_modules 下指定的库文件链接到 node 全局 node_modules 下的库文件

2.npm link :将当前项目链接到 node 全局 node_modules 中作为一个库文件,并解析 bin 配置创建可执行文件

理解 npm unlink:

1.npm unlink:将当前项目从 node 全局 node_modules 移除

2.npm unlink your-lib :将当前项目中的库文件依赖移除

脚手架命令注册和参数解析

实现注册一个命令:curry-cli-test init

1.首先在 cli-test-lib 项目下 定义一个 init 方法

代码语言:javascript
复制
module.exports = {
    init(){
        console.log('执行init流程')
    }
}

2.在 cli-test 中 注册 init 命令

代码语言:javascript
复制
#!/usr/bin/env node

const lib = require('cli-test-lib');

// 注册一个命令 curry-cli-test init

const argv = require('process').argv;

const command = argv[2];

console.log(command)
if(command){
    if(lib[command]){
        lib[command](); 
    }else{
        console.log('无效的命令')
    }
}else{
    console.log('请输入命令')
}

现在在终端输入 curry-cli-test init

在终端输入 curry-cli-test publish

在终端输入 curry-cli-test

实现带参数的命令:curry-cli-test --name vue-test

1.在 cli-test 中 注册

代码语言:javascript
复制
#!/usr/bin/env node

const lib = require('cli-test-lib');

// console.log(lib.sum(1,2))
// 注册一个命令 curry-cli-test init

const argv = require('process').argv;

const command = argv[2];


// 获取 --name vue-test
const options = argv.slice(3);
let [option, param ] =options;

option = option.replace('--','')

console.log(command)
if(command){
    if(lib[command]){
    		// 给 init 方法传入 参数
        lib[command]({ option, param }); 
    }else{
        console.log('无效的命令')
    }
}else{
    console.log('请输入命令')
}

2.在cli-test-lib中 init 方法 引入参数

代码语言:javascript
复制
 init({ option, param }){
        console.log('执行init流程',  option, param)
    }

此时在终端执行 curry-cli-test init --name vue-test。就可以拿到传入的参数了。

实现 --version

代码语言:javascript
复制
// 实现参数解析 --version
if(command.startsWith('--') || command.startsWith('-')){
    const globalOption = command.replace(/--|-/g,'')
    if(globalOption === 'version' || globalOption === 'V'){
        console.log('1.0.0')
    }
}

效果如下:

原生脚手架开发痛点分析

痛点一:重复操作

1.多package本地link

2.多package依赖安装

3.多package单元测试

4.多package代码提交

5.多package代码发布

痛点二:版本一致性

1.发布时版本一致性

2.发布后相互依赖版本升级

结论:package越多,管理复杂度越高

lerna简介

lerna是一个优化基于git+npm的多package项目的管理工具

优势

1.大幅减少重复操作

2.提升操作的标准化

lerna是架构优化的产物,它揭示了一个架构真理:项目复杂度提升后,就需要对项目进行架构优化。架构优化的主要目标往往都是以效能为核心。

官网

https://www.lernajs.cn/

案例

使用lerna管理的大型项目:

1.babel

2.vue-cli

3.create-react-app

lerna开发脚手架流程

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开发脚手架的核心目标
  • 研发架构图
  • 脚手架核心价值
  • 和自动化构建工具区别
  • 从使用角度理解什么是脚手架
    • 脚手架简介
      • 脚手架执行原理
      • 从应用的角度看如何开发一个脚手架
        • 脚手架的实现原理
          • 脚手架原理进阶
            • 脚手架开发流程
              • 脚手架开发难点解析
              • 动手写一个简单的脚手架
              • 本地调试方法
                • 多个包如何调试?
                • 脚手架本地link标准流程
                • 原生脚手架开发痛点分析
                • lerna简介
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档