脚手架架构设计和框架搭建 - 框架搭建

目录

Lerna简介

原生脚手架开发痛点分析

Lerna简介

优势

官网

Lerna 开发脚手架流程(划重点)

基于 Lerna 搭建脚手架框架

Lerna 核心操作

Lerna 发布流程

Lerna 源码分析

学习目标

学习收获

源码仓库

准备源码

Node 源码调试过程中必会的小技巧

lerna 初始化过程源码详细分析

脚手架框架 yargs 快速入门

yargs 高级用法讲解

import-local 执行流程深度分析

pkg-dir 源码解析(一大波优秀的文件操作库)

resolve-from 源码分析(彻底搞懂 node_modules 模块加载逻辑)

赚回学费之基于Lerna重新设计简历

面试官问起细节之后如何回答?


Lerna简介

原生脚手架开发痛点分析

·痛点一:重复操作

        多 Package 本地 link

        多 Package 依赖安装

        多 Package 单元测试

        多 Package 代码提交

        多 Package 代码发布

·痛点二:版本一致性

        发布时版本一致性

        发布后相互依赖版本升级

package越多,管理复杂度越高

Lerna简介

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

优势

·大幅减少重复操作

·提升操作的标准化(减少排查错误的时间)

【上面两项 是 架构师核心思考点】

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

官网

https://lerna.js.org/

Lerna 开发脚手架流程(划重点)

步骤一:脚手架项目初始化

        初始化 npm 项目、安装 lerna、lerna init 初始化项目

步骤二:创建 package

        lerna create 创建 Package、lerna add 安装依赖、lerna link 链接依赖

步骤三:脚手架开发和测试

        lerna exec 执行 shell 脚本、lerna run 执行 npm 命令、lerna clean 清空依赖、lerna bootstrap 重装依赖

步骤四:脚手架发布上线

        lerna version  bump version、lerna changed 查看上版本以来的所有变更、lerna diff 查看diff、lerna publish 项目发布

基于 Lerna 搭建脚手架框架

// .gitignore 文件
.vscode
.idea
node_modules
packages/**/node_modules
lerna-debug.log
@imooc-cli-dev/core
@组织名/package名
现在npm网站上注册 组织名,再发包,不然发不上去。

Lerna 核心操作

......

Lerna 发布流程

发布之前,要对 版本号version 进行升级。

git checkout -- lerna-debug.log
//丢弃工作区的改动
//package.json中
"publishConfig": {
    "access": "public"
}

Lerna 源码分析

学习目标

·Lerna 源码结构和执行流程分析

·import-local 源码深度精读

学习收获

·如何将源码分析的收获写进简历

·学习明星项目的架构设计

·获得脚手架执行流程的一种思路

·脚手架调试本地源码的另外一种方法(npm link 之外)

·NodeJs加载node_modules模块的流程

·各种文件操作算法和最佳实践

源码仓库

https://github.com/lerna/lerna

准备源码

源码阅读前准备工作:下载源码、安装依赖、IDE打开

源码阅读准备完成的标准:找到入口文件、能够本地调试

Node 源码调试过程中必会的小技巧

取消 Do not step into library scripts

Coding assistant for NodeJs

lerna 初始化过程源码详细分析

require(.) 相当于 require(./index.js)

// npm 项目本地依赖引用方法
"dependencies": {
    "@lerna/global-options": "file:../global-options"
}

脚手架框架 yargs 快速入门

#!/usr/bin/env node

const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const arg = hideBin(process.argv)

const cli = yargs(arg)
cli
.usage('Usage: imooc-test [command] <options>')
.demandCommand(1, 'A command is required. Pass --help to see all available commands and options')
.strict()
.alias('h', 'help')
.wrap(cli.terminalWidth())
.epilogue(`结尾的话`)
.options({
    debug: {
        type: 'boolean',
        describe: 'Bootstrap debug mode',
        alias: 'd'
    }
})
.group(['debug'], '命令分组')
.group(['registry'], 'Extra Options:')
.argv

yargs 高级用法讲解

const argv = process.argv.slice(2)
const context = {
    imoocVersion: pkg.version
}

yargs(hideBin(process.args))
.command('serve [port]', 'start the server', (yargs) => {
    //builder
    yargs.positional('port', {describe: 'port to bind on',
                              default: 5000
    })
},(argv) => {
    //handler
    if (argv.verbose) console.info(`start server on :${argv.port}`)
    serve(argv.port)
})
.option('verbose', {
    alias: 'v',
    type: 'boolean',
    description: 'Run with verbose logging'
})
.recommendCommands()
.fail((err, msg) => {
    console.log(err)
})
.parse(argv, context)

import-local 执行流程深度分析

作用:当项目和全局都存在 某个命令时,优先执行项目中的命令。

node 代码执行过程中,会向当前上下文中注入5个变量。__dirname、 __filename、 module、 require、 exports。 

pkg-dir 源码解析(一大波优秀的文件操作库)

作用:逐级向上找,找到 package.json 所在位置。

path.resolve()
path.join()
path.parse()

好用的库:findUp、locatePath、pathExists

resolve-from 源码分析(彻底搞懂 node_modules 模块加载逻辑)

// 命令执行路径
process.cwd()

// 生成node_modules可能的路径
Module._nodeModulePaths()

// 解析模块的真实路径,node模块加载核心方法
Module._resolveFilename()

// 将paths和环境变量node_modules合并
Module._resolveLookupPaths()

// 在paths中解析模块的真实路径
Module._findPath()


fs.realpathSync()

赚回学费之基于Lerna重新设计简历

完全掌握本章内容的同学可以在简历中增加:

·熟悉 Yargs 脚手架开发框架

·熟悉多 Package 管理工具 lerna 的使用方法和实现原理

·深入了解 Nodejs  模块路径解析流程

面试官问起细节之后如何回答?

yargs

·脚手架构成

        bin:package.json中配置bin属性,npm link 本地安装

        command:命令

        options:参数(boolean / string / number)

        文件顶部增加 #!/usr/bin/env node

·脚手架初始化流程

        构造函数:Yargs()

        常用方法:Yargs.options  Yargs.option  Yargs.group  Yargs.demandCommand  Yargs.recommendCommands  Yargs.strict  Yargs.fail  Yargs.alias  Yargs.wrap  Yargs.epilogue

·脚手架参数解析方法

        hideBin(process.argv)

        Yargs.parse(argv, options)

·命令注册方法

        Yargs.command(command, describe, builder, handler)

        Yargs.command({ command, describe, builder, handler })

Lerna

·Lerna 是基于 git + npm 的多 package 项目管理工具

·实现原理

        通过 import-local 优先调用本地 lerna 命令

        通过 Yargs 生成脚手架,先注册全局属性,再注册命令,最后通过 parse 方法解析参数

        lerna 命令注册时需要传入 builder 和 handler 两个方法, builder 方法用于注册命令专属的options,handler 用来处理命令的业务逻辑

        lerna 通过配置 npm 本地依赖的方式来进行本地开发,具体写法是在 package.json 的依赖中写入:file:your-local-module-path,在 lerna publish 时会自动将该路径替换

Nodejs 模块路径解析流程

·Nodejs 项目模块路径解析是通过 require.resolve 方法来实现的

·require.resolve 就是通过 Module._resolveFileName 方法实现的

·require.resolve 实现原理

        Module._resolveFileName 方法核心流程有 3 点:

                判断是否为内置模块

                通过 Module._resolveLookupPaths 方法生成 node_modules 可能存在的路径

                通过 Module._findPath 查询模块的真实路径

        Module._findPath 核心流程有 4 点:

                查询缓存(将 request 和 paths 通过 \x00 合并成 cacheKey)

                遍历 paths,将 path 与 request 组成文件路径 basePath

                如果 basePath 存在则调用 fs.realPathSync 获取文件真实路径

                将文件真实路径缓存到 Module._pathCache (key 就是前面生成的 cacheKey)

        fs.realPathSync 核心流程有 3 点:

                查询缓存(缓存的 key 为 p,即 Module._findPath 中生成的文件路径)

                从左往右遍历路径字符串,查询到 / 时,拆分路径,判断该路径是否为软链接。如果是软链接则查询真实链接,并生成新路径 p,然后继续往后遍历,这里有 1 个细节需要特别注意:遍历过程中生成的子路径 base 会缓存在 knownHard 和 cache 中,避免重复查询。

                遍历完成得到模块对应的真实路径,此时会将原始路径 original 作为 key,真实路径作为 value,保存到缓存中

·require.resolve.paths 等价于 Module._resolveLookupPaths,该方法用于获取所有 node_modules 可能存在的路径

·require.resolve.paths 实现原理:

        如果路径为 / (根目录),直接返回 ['/node_modules']

        否则,将路径字符串从后往前遍历,查询到 / 时,拆分路径,在后面加上 node_modules,并传入一个 paths 数组,直至查询不到 / 后返回 paths 数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chengbo_eva

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值