我正在参加会员专属活动-源码共读第一期,点击参加
前言
上篇文章剖析了 vue-create 的原理,这篇将参阅 vue-create 构建自己的脚手架。
痛点
日常开发中敞开新项意图办法:复制粘贴,这种办法的缺陷:
- 重复性劳动,繁琐且浪费时间
- 简单忽略项目中的装备设置
-
copy
过来的模板会存有重复代码
How
假如咱们自己开发一套脚手架,自己定制自己的模板,复制粘贴的人工流程就会转换为cli
的自动化流程, 还能够经过保护不同的模板以适应不同业务需求。
首要为了达成以下意图:
- 快速建立新的项目
- 协助团队成员遵循共同的开发流程
脚手架将具备的功用:
- 交互式指令
- 模板选择
- 注入封装好的 request 模块
- 注入登录页面
规划脚手架架构
项目结构
参阅 vue-create 的项目,运用 pnpm 进行项目管理。运用 pnpm-workspace 建立 monorepo 环境。
新建项目并初始化:
pnpm init
装备文件
创立 .npmrc 文件并输入以下内容:
.npmrc 文件是 npm 包管理东西的装备文件,用来存储 npm 的装备信息。
hoist-pattern[]=*eslint*
hoist-pattern[]=*babel*
hoist-pattern[]=@emotion/*
hoist-pattern[]=postcss
hoist-pattern[]=pug
hoist-pattern[]=source-map-support
hoist-pattern[]=ts-node
strict-peer-dependencies=false
auto-install-peers=false
各项装备的意义:
-
hoist-pattern
表明将依靠包中满意某些条件的模块打包到一个文件中 -
strict-peer-dependencies
表明假如一个包被装置到项目中,它的同级依靠包也有必要被装置。 -
auto-install-peers
表明当装置某个包时,自动装置该包的同级依靠包。
装备 monorepo
pnpm-workspace.yaml 文件中能够存储多个作业空间的装备信息,而且能够设置不同作业空间之间的依靠关系。
根目录下新建一个 pnpm-workspace.yaml
文件,并输入如下内容:
packages:
- 'packages/**'
根目录创立 packages 文件夹,这是子项意图存在目录。
装备 eslint
pnpm add
eslint
eslint-define-config
eslint-plugin-import
eslint-plugin-node
eslint-plugin-regexp
--save-dev -w
-w
表明在根目录装置
装备 prettier
pnpm add prettier --save-dev -w
装备 typescript
pnpm add typescript --save-dev -w
在 create-niu 文件夹创立 tsconfig.json 文件,并输入:
{
"include": ["src", "__tests__"],
"compilerOptions": {
"outDir": "dist",
"target": "ES2020",
"module": "ES2020",
"moduleResolution": "Node",
"strict": true,
"declaration": false,
"sourceMap": true,
"noUnusedLocals": true,
"esModuleInterop": true
}
}
编写脚手架脚本
创立进口文件
在create-niu 目录下 新建文件 index.js
#!/usr/bin/env node
console.log('hello niu')
#!/usr/bin/env node
指定当时脚本的解释器为node
指定可履行脚本的方位
在 package.json 中增加下面代码:
{
"bin": {
"create-niu": "index.js",
"cnu": "index.js"
},
}
"bin"
字段用来指定包中可履行文件的路径, 也就是说当咱们的包上线后,履行指令 npm create niu
,就会开始履行这个index文件。
验证一下
在在终端进入到create-niu目录下,履行:
npm link
然后在终端中履行:
create-niu
// or
cnu
不出意外的话能够看到控制台输出的信息了
打包构建
脚本运用TS编写,那么就需求构建东西将TS代码转换成JS。
东西:
- rollup 打包构建东西。
- unbuild 是一致的JavaScript构建东西。
在项目根目录装置依靠:
pnpm add unbuild rollup --save-dev -w
进入到create-niu 文件夹下,创立build.config.ts,并输入以下装备:
import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
entries: ['src/index'],
clean: true,
rollup: {
inlineDependencies: true,
esbuild: {
minify: true
}
},
alias: {
// we can always use non-transpiled code since we support 14.18.0+
prompts: 'prompts/lib/index.js'
}
})
在 package.json 参加脚本:
"scripts": {
"dev": "unbuild --stub",
"build": "unbuild",
"prepublishOnly": "npm run build"
},
新建src目录,并增加 index.ts 文件,上述构建装备文件中指定的进口在此, entries: ['src/index']
:
履行pnpm run dev
查看 dist 文件夹下已构建好的文件。
将create-niu 目录下的index.js修正为:
#!/usr/bin/env node
import './dist/index.mjs'
此后在 src/index.ts
编写脚手架脚本
解析指令行参数
在指令行环境中,用户能够经过输入指令来履行程序。指令的格式一般是:<command> [options] [arguments]
,其间,指令表明要履行的操作,选项(options)用于指定指令的行为或许装备信息,参数(arguments)表明指令要操作的数据。
例如,grep -i "hello" file.txt
是一个常见的指令,其间,grep
是指令,-i
是选项,表明忽略大小写,”hello” 是参数,表明要查找的字符串,file.txt 是参数,表明要查找的文件。
怎么解析
解析指令行参数的进程:
- 程序从用户输入中读取指令行参数
- 剖析它们的内容
- 获取指令、选项和参数的值
command:
- create-niu
- cnu 别号
[options]:
- -v 显现版本号
- -h 显现协助信息
- –template 履行模板
[arguments]:
- projectName 项目名
- framework 结构
- language variety 言语变体
代码完结
装置 minimist, minimist
是一个常用的 Node.js 库,用于解析指令行参数。
pnpm -F create-niu add minimist
-F create-niu
是指在create-niu包中装置依靠
在ts中增加如下代码:
import minimist from 'minimist'
const argv = minimist<{
t?: string
template?: string
}>(process.argv.slice(2), { string: ['_'] })
console.log('hello niu', argv)
在测验包中履行,结果如图:
询问用户信息
prompts 供给了一个简单易用的指令行提示库,能够让你快速构建交互式的指令行应用。
装置
pnpm -F create-niu add prompts --save-dev
pnpm add @types/prompts --save-dev -w
修正index.ts:
try {
result = await prompts([
{
type: argTargetDir ? null : 'text',
name: 'projectName',
message: 'Project name:',
initial: defaultTargetDir,
onState: (state) => {
targetDir = formatTargetDir(state.value) || defaultTargetDir
}
}
])
} catch (cancelled: any) {
console.log(cancelled.message)
return
}
const { projectName } = result
console.log(projectName)
npm link 后能够在控制台看到你输入项目名称了
写入模板
运用 fs.copyFileSync
同步地将一个文件复制到另一个文件或目录。fs.copyFileSync
是 Node.js
中的一个文件系统办法它会读取源文件的内容,并将其写入方针文件,完结复制操作。
与 create-niu 目录下创立模板文件夹 template-demo ,如图:
修正脚本,复制模板的流程大致如下:
- 设置模板寄存路径
- 便利模板文件夹中文件
- 复制目录
- 复制文件
- 递归3,4过程,完结文件复制作业
复制进程中需求特别处理 package.json
文件,因为要往里边写入包名。
美化交互信息
完结必要的作业之后发现交互信息不是很好看,能够给交互式提示信息增加各式色彩。
pnpm -F create-niu add kolorist --save-dev
修正脚本:
import {
blue,
cyan,
green,
lightGreen,
lightRed,
magenta,
red,
reset,
yellow
} from 'kolorist'
{
type: 'select', //模板选择
name: 'template',
message: reset('select a framework'),
choices: [
{ title: blue('project1'), value: 1 },
{ title: cyan('project2'), value: 2 }
]
}
作用
发布脚手架
假如脚手架功用正常,能够将其发布到 npm 库房中,以便其他人运用。能够运行如下指令来发布脚手架:
npm publish
为了方便管理,这里运用上期学习的 release-it 进行项意图发布。
初始化:
npm init release-it
增加装备文件后履行:
npm run release
发布后,其他人就能够经过 npm 指令来装置和运用您的脚手架了.
@codeniu/create-niu
总结
这篇文章描绘了重零建立一个脚手架项意图全进程,包括怎么运用pnpm workspace 管理 monorepo 项目,脚本的编写,npm 包的发布。