Vite创建项目的实现步骤

目录
  • 前言
  • yarn create 做了什么
  • 源码解析
    • 项目依赖
    • 模版配置
    • 工具函数
      • copy
      • copyDir
      • emptyDir
    • 核心函数
      • 命令行交互并创建文件夹
      • 写入文件
  • 小结

前言

随着 Vite2 的发布并日趋稳定,现在越来越多的项目开始尝试使用它。我们使用 Vite 是一般会用下面这些命令去创建一个项目:

// 使用 npm
npm init @vitejs/app
// 使用 yarn
yarn create @vitejs/app

// 想指定项目名称和使用某个特定框架的模版时,可以像下面这样
// npm
npm init @vitejs/app my-vue-app --template vue
// yarn
yarn create @vitejs/app my-vue-app --template vue

运行这些命令后就会生成一个项目文件夹,对于大多数人可能觉得只要能正常创建一个项目就够了,但我出于好奇,为什么运行这些命令就会生成一个项目文件夹。这里以 yarn 为例创建项目进行说明。

yarn create 做了什么

可能很多人会疑惑,为什么很多项目的创建方式都是使用yarn create这个命令进行创建。除了这里的 Vite,我们创建 React 项目也是这样:yarn create react-app my-app
那这个命令到底做了什么,它其实做了两件事:

yarn global add create-react-app
create-react-app my-app

关于yarn create的更多内容可以看这里

源码解析

yarn create @vitejs/app命令运行后就会执行@vitejs/create-app里的代码。我们先看看这文件的项目结构

template 开头的文件夹都是各个框架和对应的typescript版本的项目模板,我们不用太关心,创建项目的逻辑都在 index.js 文件里。下面就来看看这里面都做了什么

项目依赖

首先是依赖的引入

const fs = require('fs')
const path = require('path')
const argv = require('minimist')(process.argv.slice(2))
const prompts = require('prompts')
const {
  yellow,
  green,
  cyan,
  blue,
  magenta,
  lightRed,
  red
} = require('kolorist')

fs、path是Nodejs内置模块,minimist、prompts、kolorist则分别是第三方依赖库。

  • minimist:是一个用于解析命令行参数的工具。文档
  • prompts:是一个命令行交互的工具。文档
  • kolorist:是一个使命令行输出带有色彩的工具。文档

模版配置

接下来不同框架模版的配置文件,最后生成一个模版名称的数组。

// 这里只写了vue和react框架的配置,其他的都是差的不多,感兴趣可以去看源码。
const FRAMEWORKS = [
  ......

  {
    name: 'vue',
    color: green,
    variants: [
      {
        name: 'vue',
        display: 'JavaScript',
        color: yellow
      },
      {
        name: 'vue-ts',
        display: 'TypeScript',
        color: blue
      }
    ]
  },
  {
    name: 'react',
    color: cyan,
    variants: [
      {
        name: 'react',
        display: 'JavaScript',
        color: yellow
      },
      {
        name: 'react-ts',
        display: 'TypeScript',
        color: blue
      }
    ]
  },

  ......
]

// 输出模版名称列表
const TEMPLATES = FRAMEWORKS.map(
  (f) => (f.variants && f.variants.map((v) => v.name)) || [f.name]
).reduce((a, b) => a.concat(b), [])

其次,由于 .gitignore 文件的特殊性,每种框架项目模版下都是先创建的 _gitignore 文件,在后续创建项目的时候再替换为 .gitignore。所以,代码里会预先定义一个对象来存放需要重命名的文件:

const renameFiles = {
  _gitignore: '.gitignore'
}

工具函数

在开始讲的核心函数之前,先来看看代码中定义的工具函数。最重要的是与文件操作相关的三个函数。

copy

function copy(src, dest) {
  const stat = fs.statSync(src)
  if (stat.isDirectory()) {
    copyDir(src, dest)
  } else {
    fs.copyFileSync(src, dest)
  }
}

copy函数则用于复制文件或文件夹 src 到指定文件夹 dest。它会先获取 src 的状态 stat,如果 src 是文件夹的话,即stat.isDirectory()为 true 时,则会调用下面将介绍的copyDir函数来复制 src 文件夹下的文件到 dest 文件夹下。反之,src 是文件的话,则直接调用 fs.copyFileSync 函数复制 src 文件到 dest 文件夹下。

copyDir

function copyDir(srcDir, destDir) {
  fs.mkdirSync(destDir, { recursive: true })
  for (const file of fs.readdirSync(srcDir)) {
    const srcFile = path.resolve(srcDir, file)
    const destFile = path.resolve(destDir, file)
    copy(srcFile, destFile)
  }
}

copyDir函数用于将某个文件夹 srcDir 中的文件复制到指定文件夹 destDir 中。它会先调用 fs.mkdirSync函数来创建制定的文件夹,然后调用fs.readdirSync从 srcDir 文件夹下获取的文件并遍历逐个复制;最后在调用copy函数进行复制,这里用到了递归,因为可能存在文件夹里的文件还是文件夹。

emptyDir

function emptyDir(dir) {
  if (!fs.existsSync(dir)) {
    return
  }
  for (const file of fs.readdirSync(dir)) {
    const abs = path.resolve(dir, file)
    if (fs.lstatSync(abs).isDirectory()) {
      emptyDir(abs)
      fs.rmdirSync(abs)
    } else {
      fs.unlinkSync(abs)
    }
  }
}

emptyDir函数用于清空 dir 文件夹下的代码。它会先判断 dir 文件夹是否存在,存在则遍历该问文件夹下的文件,构造该文件的路径 abs,当 abs 为文件夹时,会递归调用 emptyDir 函数删除该文件夹下的文件,然后再调用fs.rmdirSync删除该文件夹;当 abs 是文件时,则调用fs.unlinkSync函数来删除该文件。

核心函数

接下来就是核心功能实现的init函数。

命令行交互并创建文件夹

首先是获取命令行参数

let targetDir = argv._[0]
let template = argv.template || argv.t

const defaultProjectName = !targetDir ? 'vite-project' : targetDir

argv._[0] 代表 @vitejs/app 后的第一个参数
template则是要使用的模版名称
defaultProjectName则是我们创建的项目名称。
接下来就是使用prompts包来在命令行中输出询问,像下面这样:

具体代码如下:

// 关于命令行交互的部分代码没有全部放在这里,感兴趣的可以去看源码
let result = {}

result = await prompts(
  [
    {
      type: targetDir ? null : 'text',
      name: 'projectName',
      message: 'Project name:',
      initial: defaultProjectName,
      onState: (state) =>
        (targetDir = state.value.trim() || defaultProjectName)
    },
    ......

  ]
)

const { framework, overwrite, packageName, variant } = result

const root = path.join(cwd, targetDir)

if (overwrite) {
  emptyDir(root)
} else if (!fs.existsSync(root)) {
  fs.mkdirSync(root)
}

template = variant || framework || template

// 输出项目文件夹路径
console.log(`\nScaffolding project in ${root}...`)

const templateDir = path.join(__dirname, `template-${template}`)

选择完成后会返回我们选择的结果result
root是通过path.join函数构建的完整文件路径
overwrite是针对已存在我们要创建的同名文件时,是否要重写,如果重写,则调用前面的emptyDir函数清空该文件夹,如果不存在该文件夹,则调用fs.mkdirSync创建文件夹
templateDir选择的模版文件夹名称

写入文件

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

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

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName

write('package.json', JSON.stringify(pkg, null, 2))

const pkgManager = /yarn/.test(process.env.npm_execpath) ? 'yarn' : 'npm'

// 输出一些提示告诉你项目已经创建结束,以及告诉你接下来启动项目需要运行的命令
console.log(`\nDone. Now run:\n`)
if (root !== cwd) {
console.log(`  cd ${path.relative(cwd, root)}`)
}
console.log(`  ${pkgManager === 'yarn' ? `yarn` : `npm install`}`)
console.log(`  ${pkgManager === 'yarn' ? `yarn dev` : `npm run dev`}`)
console.log()

write函数则接受两个参数 file 和 content,它有两个功能:

  • 对指定的文件 file 写入指定的内容 content,调用fs.writeFileSync函数来实现将内容写入文件。
  • 复制模版文件夹下的文件到指定文件夹下,调用前面介绍的copy函数来实现文件的复制。

然后调用fs.readdirSync读取模版文件夹里的文件,遍历逐一复制到项目文件夹(其中要过滤的 package.json 文件,因为其中的 name 字段要修改);最后再写入 package.json 文件。

小结

Vite 的create-app包的实现只有320行左右的代码,但它考虑到各种场景的兼容处理;在学习完之后,自己去实现一个这样的CLI工具也不是什么难事。

到此这篇关于Vite创建项目的实现步骤的文章就介绍到这了,更多相关Vite创建项目内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue3.0+vite2实现动态异步组件懒加载

    创建一个vite项目 性能决定成败;vite确实快: cmd 命令行(默认你已经安装了node & npm),执行npm init @vitejs/app vue-study – --template vue: cd至vue-study,npm install(安装依赖); npm run dev(启动项目): 创建组件 新建一个目录为pages,pages下面再新建一个目录contents,contens下面可以新建具体的组件目录页面,此时目录结构为 App.vue <template&g

  • vite+vue3.0+ts+element-plus快速搭建项目的实现

    vite 出了 2.x 版本,抱着学一学的心态决定出个简单的项目,结合 element-plus,以及将会成为每位前端必会的 typescript,实现了如下内容. vite是一个由原生 ESM 驱动的 Web 开发构建工具.在开发环境下基于浏览器原生 ES imports 开发,在生产环境下基于 Rollup 打包. vite 作用 快速的冷启动:不需要等待打包操作: 即时的热模块更新:替换性能和模块数量的解耦让更新飞起: 真正的按需编译:不再等待整个应用编译完成,这是一个巨大的改变. 使用的

  • 详解Vue3.0 + TypeScript + Vite初体验

    项目创建 npm: $ npm init vite-app <project-name> $ cd <project-name> $ npm install $ npm run dev or yarn: $ yarn create vite-app <project-name> $ cd <project-name> $ yarn $ yarn dev 项目结构 main.js 在个人想法上,我觉得createApp()是vue应用的实例,createApp

  • Vite搭建React项目的方法步骤

    前言 日常放鸽,火钳刘明 这是一个基于 vite 搭建的 React 的项目,开发体验非常棒. 创建一个 Vite 项目 yarn create @vitejs/app 如上图,选择了 react-ts 预设模板,如果出现下图一样的工程 yarn // 安装依赖 yarn dev // 启动开发环境 打开浏览器输入http://localhost:3000/#/,如上图所示的话.那么恭喜你,你可以正常开发 React 项目了.完结撒花 如果不行的话,直接看 vite 官网,它比我写的详细 改造工

  • vite2.x实现按需加载ant-design-vue@next组件的方法

    1.使用版本 vite:2.0 ant-design-vue: 2.0.0-rc.8 vue:3.0.5 2.安装vite插件 yarn add vite-plugin-style-import -D or npm i vite-plugin-style-import -D 插件仓库地址:github 3.vite.config.js配置 import vue from '@vitejs/plugin-vue' import styleImport from 'vite-plugin-style

  • 详解vite2.0配置学习(typescript版本)

    介绍 尤于溪的原话. vite与 Vue CLI 类似,vite 也是一个提供基本项目脚手架和开发服务器的构建工具. vite基于浏览器原生ES imports的开发服务器.跳过打包这个概念,服务端按需编译返回. vite速度比webpack快10+倍,支持热跟新, 但是出于处于测试阶段. 配置文件也支持热跟新!!! 创建 执行npm init @vitejs/app ,我这里选择的是vue-ts 版本 "vite": "^2.0.0-beta.48" alias别

  • 详解vite+ts快速搭建vue3项目以及介绍相关特性

    vite 尤大在 Vue 3.0 beta 直播中推荐了 vite 的工具,强调:针对Vue单页面组件的无打包开发服务器,可以直接在浏览器运行请求的 vue 文件 很新颖,这篇博客用它来搭建一个 vue3 的项目试试 Vite 是面向现代浏览器,基于原生模块系统 ESModule 实现了按需编译的 Web 开发构建工具.在生产环境下基于 Rollup 打包 快速冷启动服务器 即时热模块更换(HMR) 真正的按需编译 node >= 10.16.0 搭建 使用 vite 搭建项目 npm init

  • vite2.0+vue3移动端项目实战详解

    一.涉及技术点 vite版本 vue3 ts 集成路由 集成vuex 集成axios 配置Vant3 移动端适配 请求代理 二.步骤 vite+ts+vue3只需要一行命令 npm init @vitejs/app my-vue-app --template vue-ts 配置路由 npm install vue-router@4 --save 在src下新建router目录,新建index.ts文件 import { createRouter, createWebHashHistory, Ro

  • vite+vue3+element-plus项目搭建的方法步骤

    使用vite搭建vue3项目 通过在终端中运行以下命令,可以使用 Vite 快速构建 Vue 项目. $ npm init vite-app <project-name> $ cd <project-name> $ npm install $ npm run dev 引入Element Plus 安装Element Plus: npm install element-plus --save main.js中完整引入 Element Plus: import { createApp

  • Vite创建项目的实现步骤

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

  • vue-cli3.X快速创建项目的方法步骤

    1.安装 Vue CLI 的包名称由 vue-cli 改成了 @vue/cli. 如果你已经全局安装了旧版本的 vue-cli (1.x 或 2.x),你需要先通过以下方式先卸载它: npm uninstall vue-cli -g # 或 yarn global remove vue-cli vue-cli 3.x安装: npm install -g @vue/cli # OR yarn global add @vue/cli 说明:-g / global 表示全局安装. 安装完成后可通过以下

  • Vue Cli3 创建项目的方法步骤

    最近的开发项目中使用了vue-cli 3.0,使用体验可以说非常棒了,模板更加制定化,配置更加简洁.以下总结下应用过程中的一些经验. 1. 安装 npm install -g @vue/cli 2. 创建一个项目 vue create iview-admin # OR vue ui default (babel, eslint) 默认套餐,提供 babel 和 eslint 支持. Manually select features 自己去选择需要的功能,提供更多的特性选择.比如如果想要支持 Ty

  • 创建项目及包管理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搭建vue3+TS项目的实现步骤

    目录 vite简介 初始化项目 修改vite.config.ts 安装ts依赖和ESLint 安装Axios 配置跨域 安装Less vite简介 vite 是一个基于 Vue3 单文件组件的非打包开发服务器,它具有快速的冷启动,不需要等待打包操作:并且官网说是下一代的前端构建工具. 初始化项目 npm init vite@latest 1.输入项目名称 2.选择Vue 3.选择TS 4.启动项目 5.项目启动成功 注意 用vscode进行开发的时候,推荐使用volar,禁用以前vue2常使用的

  • idea创建Spring项目的方法步骤(图文)

    Spring介绍 Spring概述 Spring是一个开源框架,Spring是2003年兴起的轻量级java开发框架,由Rod Johnson 在其著作 Expert One-On-One J2EE Development and Design 中阐述的部分理念和原形衍生而来.它是为了解决企业级开发的复杂性而创建的.Spring使用基本的javaBaen来完成以前只可能由EJB完成的事情,然而Spring的用途不仅限于服务器端的开发,从简单性.可测试性.低耦合的角度而言任何java应用都可以在s

  • IntelliJ IDEA创建maven web项目的图文步骤(IDEA新手适用)

    PS:从eclipse刚转到IDEA,对于这个陌生的工具我表示无言,但听说很好用,也就试试,结果我几乎花了一晚上的时间才搭起来maven web项目,觉得在此给各位一个搭建maven web项目的教程,指出我踩过的各种坑! 步骤一:首先先创建一个project,在这里就是创建一个maven的工作空间 步骤二:按照下面的步骤操作就可以了,最后next 首先,选择左边的maven 然后在右边Creater from archetype选项前面打个勾, 最后选择maven-archetype-weba

  • vue-cli4.x创建企业级项目的方法步骤

    安装脚手架(vue-cli) $ npm install @vue/cli -g //全局安装最新的脚手架 创建项目 $ vue create vue-demo 在创建项目的时候可以使用 $ vue ui 来进行创建,两种方式在创建的时候,直接选择上router和vuex,来进行项目创建 移动端Vant # 通过 npm 安装 $ npm i vant -S # 通过 yarn 安装 $ yarn add vant 我这里都是使用的按需引入,用了 babel-plugin-import 是一款

  • idea2020.1.3 手把手教你创建web项目的方法步骤

    首先: IDEA中的项目(project)与eclipse中的项目(project)是不同的概念,IDEA的project 相当于之前eclipse的workspace,IDEA的Module是相当于eclipse的项目(project). 第一步:配置tomcat (1)点击run下面的edit configuration (2)点击template左边的三角 (3)找到Tomcat Server,有两个选项,第一个表示本地的,第二个表示远程的.这里我们因为在自己电脑,选择本地的 (4)点击c

随机推荐