脚手架实现原理
当我们在终端输入vue create xx的时候 终端会去全局环境变量中,找到vue指令的方法 查看create-react-app的位置,所有通过npm -g安装的包都会放入该目录下。
描述脚手架命令执行全过程
在终端输入create-react-app之后、
终端解析命令
终端在上述的环境变量中找到creat-react-app命令脚本
window在C:\Users\Administrator\AppData\Roaming\npm可以找到create-react-app.cmd,如上图,这是一个软链接,直接指向C:\Users\Administrator\AppData\Roaming\npm\node_modules\create-react-app中的createReactApp.js。
终端利用node执行index.js
index.js解析comman/options,执行command
执行完毕,退出。
为什么全局安装create-react-app后会添加命令create-react-app?
在C:\Users\Administrator\AppData\Roaming\npm\node_modules\create-react-app中的package.json可以看到,
在package.json中,这个bin指令的意思就在在我们安装完create-react-app之后的软连接名称,以及指向的文件。
全局安装create-react-app发生了什么?
首先node会将这个包安装到node_modules下面,
然后解析这个包的package.json,发现有bin指令,发现了create-react-app:index.js
就会在配置文件配置一个软连接,create-reactp-app指向这个包的index.js文件
为什么可以直接通过create-react-app直接执行index.js文件。
在终端输入create-react-app的时候,操作系统会找到配置文件夹下的create-react-app,他是一个软连接。
然后通过软连接找到index.js文件,但是js文件必须要通过解释器来执行,如node执行js文件。但是我们通过create-react-app是直接执行了index.js。可以看看index.js的结构。 第一行至关重要,他就是为什么在命令行可以直接执行该文件的原因。 这句话的意思就是,在当前的操作系统中环境变量,直接找node来执行该文件。 可以通过/usr/bin/env node直接启动node 所以在终端直接执行 index.js,相当于执行/usr/bin/env node index.js
如何开发一个脚手架
以create-react-app为例子
开发npm项目,项目中应该包含一个index.js文件,并将这个项目发布到npm
将npm项目安装到node的node_modules文件夹下
在node的bin目录下配置create-react-app软连接指向node_mudules/create-react-app/index.js文件。
这样执行了create-react-app就会找到index.js文件执行。
如何调式本地脚手架
npm link将本地脚手架以软连接的形式存储在node的bin下。
包本地调试 如果是一个组件库,那么npm link之后,会在本地的node下面的node_modules上面添加一个依赖
这时候通过在脚手架 npm link linge-cli-lib,就可以从本地拉取组件库项目。
正常运行。 本地调式库和脚手架的方式完成。 等待调式完毕的时候,再npm plulish就行。然后在npm unlink 组件库,和npm uninstall -g 组件库。最后直接npm i 就可以下载npm上的版本了。
脚手架本地link流程
首先在脚手架:
npm link
然后在库项目:
npm link
再回到脚手架
npm link 库。
取消并且安装上线的:
在项目中,npm unlink
在脚手架中 npm unlink 库; rm - rf node_modules; 先unlink,再移除node_modules
在脚手架中 接着 npm i 就行了。
npm link:
npm link A,将当前项目中的node_modules下指定的A链接到node全局node_modules下的库文件。
npm link,将当前项目连接到node全局node_modules中作为一个库文件,或者一个脚手架。并解析bin配置创建可执行文件。
npm unlink
npm unlink: 将当前项目从node全局node_modules中移除。
npm unlink A: 将当前项目中的A移除依赖。
Lerna简介
原生脚手架痛点分析:
多package本地link
多package依赖安装
多package单元测试
多package代码提交
多package代码发布
版本一致性:
package越多,管理复杂度越高。
Lerna
https://www.lernajs.cn/
lerna开发脚手架流程
1 项目初始化
2 创建package
3 脚手架开发与测试
npm本地开发用法
以前在本地开发脚手架或者组件库的时候都是使用npm link。还可以使用: file:相对路径。然后再重新npm i 一下,那么本地开发的时候就两个库就可以正常连接。等到要发布的时候,要记得改过来。
yargs
Yargs 通过解析参数和生成优雅的用户界面,帮助您构建交互式命令行工具。 yargs文档
require源码解读
require源码解读
npmlog
node的友好输出模式
process
node的process模块。process官网
semver
比较版本号的库
使用commonader注册脚手架命令
commonader文档 基本用法
const { Command } = require ( "commander" ) ;
const program = new Command ( ) ;
program
. name ( "linge-cli" )
. usage ( " [options]" )
. option ( "-d, --debug" , "是否开启调式模式" , false )
. option ( "-e, --env " , "获取环境变量" )
. option ( "-p, --pizza-type " , "flavour of pizza" )
. parse ( process. argv) ;
const options = program. opts ( ) ;
console. log ( "-------" , options. debug) ;
console. log ( "-------" , options. env) ;
注册
command在当前脚手架注册命令
const clone = program. command ( "clone [destination]" ) ;
clone
. description ( "clone a repository" )
. option ( "-f --force" , "是否强制拷贝" , false )
. action ( ( source, destination, cmdObj ) => {
console. log ( "do cone==============" , source, destination, cmdObj) ;
} ) ;
addCommand注册子命令