创建项目及包管理yarn create vite源码学习

目录
  • 1.引言
  • 2.走进“yarn create vite”的源码
    • 2.1 Vite 创建项目的方式:
      • 2.1.1 终端交互方式创建项目:
      • 2.1.2 终端指定模版创建项目:
    • 2.2 源码分析:
      • 2.2.1 终端参数解析:
      • 2.2.2 交互收集数据:
      • 2.2.3 目录初始化:
      • 2.2.4 拷贝模板文件夹:
      • 2.2.5 重写 gitignore 名称:
      • 2.2.6 重写 package 字段:
      • 2.2.7 后续操作提示:
  • 3. 总结

1.引言

我们在编程学习的过程中也会写一些项目的模板,这样的模板在后期其实并没有进行很好的管理,以至于下次再来回顾或使用的时候还需要从“零”开始,在使用过 Vite 来创建项目后顺便拿看了一下仓库中create-vite包中的源码,得到了很好的启发~

2.走进“yarn create vite”的源码

2.1 Vite 创建项目的方式:

  • 终端交互方式创建项目;
  • 终端指定模版创建项目;

2.1.1 终端交互方式创建项目:

相比于以往的 CLI 工具提供的创建项目都需要优先手动安装 CLI 工具后再执行对应的创建命令,另一种就是 Vite 目前采用的直接通过包管理器内置命令使用统一的规范来实现项目的快速创建;

如果你使用 YARN:

# yarn
yarn create vite

接下来就可以按终端提示进行项目名称的录入和项目模板的选择了~

2.1.2 终端指定模版创建项目:

如果我们很明确内置的模板选项的话我们可以在终端执行时同时录入项目名称和模板名称更快速的创建项目;

# yarn
yarn create vite my-vue-app --template vue

备注:使用“.”来在当前目录创建项目;

2.2 源码分析:

  • 终端参数解析;
  • 交互收集数据;
  • 目录初始化;
  • 拷贝模板文件夹;
  • 重写 gitignore 名称;
  • 重写 package 字段;
  • 后续操作提示;

2.2.1 终端参数解析:

通过 minimist 模块将终端参数解析为对象形式:

const argv = minimist<{
  t?: string
  template?: string
}>(process.argv.slice(2), { string: ['_'] })

通过读取对象属性来得到 argTargetDir 和 argTemplate 两个参数:

const argTargetDir = formatTargetDir(argv._[0])
const argTemplate = argv.template || argv.t

2.2.2 交互收集数据:

通过交互收集的数据包括:projectName、overwrite、packageName、framework、variant:

projectName:默认值是 defaultTargetDir ,对应的值是vite-project,当通过终端解析到 argTargetDir 后将跳过此步骤;

{
  type: argTargetDir ? null : 'text',
  name: 'projectName',
  message: reset('Project name:'),
  initial: defaultTargetDir,
  onState: (state) => {
    targetDir = formatTargetDir(state.value) || defaultTargetDir
  }
}

overwrite:在确认好 targetDir 参数后,我们要看 targetDir 对应的文件夹是否存在或是文件夹中是否有文件,要提示用户是否需要情况或终端操作;

{
  type: () =>
    !fs.existsSync(targetDir) || isEmpty(targetDir) ? null : 'confirm',
  name: 'overwrite',
  message: () =>
    (targetDir === '.'
      ? 'Current directory'
      : `Target directory "${targetDir}"`) +
    ` is not empty. Remove existing files and continue?`
},
{
  type: (_, { overwrite }: { overwrite?: boolean }) => {
    if (overwrite === false) {
      throw new Error(red('') + ' Operation cancelled')
    }
    return null
  },
  name: 'overwriteChecker'
}

packageName:packageName 的值通过 路径targetDir 来确定,在终端交互收集数据的时候需要对值做格式的校验来确定合法性;

// 确定项目名称
const getProjectName = () =>
    targetDir === '.' ? path.basename(path.resolve()) : targetDir
// 校验项目名称合法性
{
  type: () => (isValidPackageName(getProjectName()) ? null : 'text'),
  name: 'packageName',
  message: reset('Package name:'),
  initial: () => toValidPackageName(getProjectName()),
  validate: (dir) =>
    isValidPackageName(dir) || 'Invalid package.json name'
}

framework:如果终端已获取到 argTemplate 参数,且已内置该模板将跳过这步,否则将进行预置模板配置的解析并选择;

{
  type:
    argTemplate && TEMPLATES.includes(argTemplate) ? null : 'select',
  name: 'framework',
  message:
    typeof argTemplate === 'string' && !TEMPLATES.includes(argTemplate)
      ? reset(
          `"${argTemplate}" isn't a valid template. Please choose from below: `
        )
      : reset('Select a framework:'),
  initial: 0,
  choices: FRAMEWORKS.map((framework) => {
    const frameworkColor = framework.color
    return {
      title: frameworkColor(framework.display || framework.name),
      value: framework
    }
  })
}

variant:通过上一步得到的 framework 参数将确定这个步的配置,因为同样的 framework 看一配置多种 variant ;

{
  type: (framework: Framework) =>
    framework && framework.variants ? 'select' : null,
  name: 'variant',
  message: reset('Select a variant:'),
  choices: (framework: Framework) =>
    framework.variants.map((variant) => {
      const variantColor = variant.color
      return {
        title: variantColor(variant.display || variant.name),
        value: variant.name
      }
    })
}

2.2.3 目录初始化:

目录如果不存在的话我们需要创建对应的目录,因为在前期收集参数可能是个目录,这儿创建的时候需要递归创建,但是当目录存在且有内容的时候我们就需要清空掉里面的文件了,但是在清空的时候我们要考虑当时目录可能已经被版本管理过了,所以需要对.git目录过滤掉,这样才更完整;

const root = path.join(cwd, targetDir)
if (overwrite) {
  emptyDir(root)
} else if (!fs.existsSync(root)) {
  fs.mkdirSync(root, { recursive: true })
}

2.2.4 拷贝模板文件夹:

模板拷贝的时候需要过滤掉package.json,我们会在后面单独进行处理;

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
  write(file)
}

2.2.5 重写 gitignore 名称:

在上一步的模板文件夹拷贝的时候已经用到了这个函数,我们这里关系第二行中的关键对象 renameFiles ,实际上就是要将 _gitignore 重命名为 .gitignore ,因为在模板中直接使用 .gitignore 可能就导致关节的文件被丢失掉了;

const write = (file: string, content?: string) => {
  const targetPath = path.join(root, renameFiles[file] ?? file)
  if (content) {
    fs.writeFileSync(targetPath, content)
  } else {
    copy(path.join(templateDir, file), targetPath)
  }
}

2.2.6 重写 package 字段:

最后来输出 package.json ,需要改变里面的内容,尤其是重要的项目名称,命名规范也是为了符合 package 中 name 的规则;

const pkg = JSON.parse(
  fs.readFileSync(path.join(templateDir, `package.json`), 'utf-8')
)
pkg.name = packageName || getProjectName()
write('package.json', JSON.stringify(pkg, null, 2))

2.2.7 后续操作提示:

在模板拷贝完毕后项目的创建阶段也就结束了,接着就是判断在终端执行的包管理器来提示用户下一步的操作了~

const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)
const pkgManager = pkgInfo ? pkgInfo.name : 'npm'
switch (pkgManager) {
  case 'yarn':
    console.log('  yarn')
    console.log('  yarn dev')
    break
  default:
    console.log(`  ${pkgManager} install`)
    console.log(`  ${pkgManager} run dev`)
    break
}

3. 总结

在源码中还支持了第三方模板通过自定义命令来创建项目,关键词可以搜索 customCommand ,整体源码是很简单的,你准备好为自己创建一套模板管理工具了吗~

以上就是创建项目及包管理yarn create vite源码学习的详细内容,更多关于创建项目包管理yarn create vit的资料请关注我们其它相关文章!

(0)

相关推荐

  • Create vite理解Vite项目创建流程及代码实现

    目录 前言 monorepo 主流程 入口文件 主要结构 扩展插件 模板配置 getProjectName formatTargetDir npm包名验证和转化 取得模板目录 得到npm包管理器相关信息 文件操作相关的函数 write函数 写入文件 copy函数 复制文件 copyDir 复制目录 emptyDir 清空目录 isEmpty 判断目录为空 核心代码 总结 前言 继上次阅读create-vue后 ,本次接着来解析 create-vite, 得益于之前的阅读经验, 本篇笔记将会着重讲

  • create vite 实例源码解析

    目录 代码结构 init() projectName:项目名称 overwrite:是否覆盖已存在的目录 overwriteChecker:检测覆盖的目录是否为空 framework:框架 variant:语言 获取用户输入 清空目录 生成项目 确定项目模板 确定包管理器 正式生成项目 创建package.json 完成 总结 代码结构 create-vite的源码很简单,只有一个文件,代码总行数400左右,但是实际需要阅读的代码大约只有200行左右,废话不多说,直接开始吧. create-vi

  • Vite的createServer启动源码解析

    目录 启动Vite的createServer 通过vite3安装一个vue的工程 添加断点并开启调试 边调试边理解代码 启动Vite的createServer 为了能够了解vite里面运行了什么,通过执行单步调试能够更加直观的知道Vite具体内容.所以这次我们来试着启动Vite的createServer,并进行调试. 通过vite3安装一个vue的工程 进入工作目录,运行下面的代码,项目名称随意,语言用Vue. npm create vite 进入工程目录安装依赖 添加断点并开启调试 通过vsc

  • 创建项目及包管理yarn create vite源码学习

    目录 1.引言 2.走进“yarn create vite”的源码 2.1 Vite 创建项目的方式: 2.1.1 终端交互方式创建项目: 2.1.2 终端指定模版创建项目: 2.2 源码分析: 2.2.1 终端参数解析: 2.2.2 交互收集数据: 2.2.3 目录初始化: 2.2.4 拷贝模板文件夹: 2.2.5 重写 gitignore 名称: 2.2.6 重写 package 字段: 2.2.7 后续操作提示: 3. 总结 1.引言 我们在编程学习的过程中也会写一些项目的模板,这样的模板

  • Python3使用requests包抓取并保存网页源码的方法

    本文实例讲述了Python3使用requests包抓取并保存网页源码的方法.分享给大家供大家参考,具体如下: 使用Python 3的requests模块抓取网页源码并保存到文件示例: import requests html = requests.get("http://www.baidu.com") with open('test.txt','w',encoding='utf-8') as f: f.write(html.text) 这是一个基本的文件保存操作,但这里有几个值得注意的

  • Vite创建项目的实现步骤

    目录 前言 yarn create 做了什么 源码解析 项目依赖 模版配置 工具函数 copy copyDir emptyDir 核心函数 命令行交互并创建文件夹 写入文件 小结 前言 随着 Vite2 的发布并日趋稳定,现在越来越多的项目开始尝试使用它.我们使用 Vite 是一般会用下面这些命令去创建一个项目: // 使用 npm npm init @vitejs/app // 使用 yarn yarn create @vitejs/app // 想指定项目名称和使用某个特定框架的模版时,可以

  • vue-cli创建项目及项目结构解析

    目录 1.进入一个目录,创建项目 2.选择你需要的配置项 2.1 选择vue版本 2.2 选择选择是否使用history router 2.3 选择css 预处理器 2.4 选择Eslint代码验证规则 2.5 选择什么时候进行代码规则检测 2.6 选择如何存放配置 2.7 是否保存当前配置 3.项目的配置图 4.项目创建完成 5.输入npm run serve启动项目 6.项目结构解析 上一篇vue-cli 介绍与安装我们安装了vue-cli,接下来我们就使用该脚手架进行创建项目 1.进入一个

  • AERGO SHIP:用于开发智能合约的包管理器

    AERGO SHIP:用于开发智能合约的包管理器 用于构建.测试和部署分布式应用程序的客户端框架和开发环境 构建大型分布式应用程序是很困难的,因为对其进行测试,使其实现端到端工作,并进行部署是一个非常耗时的过程.通过AERGO,我们计划让一切变得与众不同. AERGO是一个为在实现基于区块链的系统和应用程序时面临众多独特挑战的企业提供解决方案的平台.为了提高开发.测试和部署智能合约的效率和易用性,我们创建了SHIP.SHIP是Lua智能合约包管理器.它将本地开发环境与Git和分布式分类账连接起来

  • 详解IDEA 中使用Maven创建项目常见错误和使用技巧(推荐)

    使用idea的运行程序时,出现jar包不存在的错误(pom.xml文件中有依赖,而且代码没有红色的). 解决方法:Maven安装目录下的conf文件下的setting.xml文件中不要加入本地仓库路径设置,直接在idea中设置. tomcat启动maven项目出现jar包不存在的错误.解决方法:在pom.xml文件中加上war maven依赖下载速度太慢.解决方法:在maven安装目录下的conf文件下的setting.xml中,设置阿里云的镜像仓库地址. <mirror> <id>

  • linux下源码包安装的服务管理

    目录 1.源码包服务的启动管理 2.源码包服务的自启动管理 3.让源码包服务被服务管理命令识别 (1)让通过源码包安装的服务能被service命令管理启动 (2)让通过源码包安装的服务能被chkconfig命令管理自启动 (3)让ntsysv命令可以管理通过源码包安装的服务 (4)总结 1.源码包服务的启动管理 # 通过源码包的安装路径,找到该服务的启动脚本, # 也就是获得该服务的启动脚本的绝对路径, # 最后加上启动选项. [root@localhost ~]# /usr/local/apa

  • 使用pnpm包管理器替代npm及yarn的命令示例

    目录 前言 为什么会有 pnpm 不止于此 什么是扁平化的 node_modules pnpm 的 node_modules 如何使用 pnpm 安装 直接安装 通过 npm 安装 通过 HomeBrew 安装( 一种 MacOS 包管理器) 升级 使用 配置 命令 和其他包管理器比较 Monorepo 及 工作空间(Workspace) 什么是 Monorepo Workspace workspace: 协议 结语 前言 今天给大家介绍一种新的包管理器:pnpm,pnpm 由 zkochan

随机推荐