欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Create?vite理解Vite項目創(chuàng)建流程及代碼實現(xiàn)

 更新時間:2022年10月27日 14:25:31   作者:Harexs  
這篇文章主要為大家介紹了Create?vite理解Vite項目創(chuàng)建流程及代碼實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

繼上次閱讀create-vue后 ,本次接著來解析 create-vite, 得益于之前的閱讀經(jīng)驗, 本篇筆記將會著重講解代碼執(zhí)行流程以及函數(shù)的擴展

最新的 create-vite 已經(jīng)升級為Ts編譯了,為方便學習理解使用川哥提供的源碼倉庫

git clone github.com/lxchuan12/v…

monorepo

ViteVue都使用monorepo的形式管理代碼,將原本多代碼倉庫變?yōu)閱未a倉庫,每一個包對應的就是一個項目,這些項目都具有相關性,但在邏輯上是獨立的。

主流程

入口文件

vite2/packages/create-vite/index.js

主要結構

import fs from 'node:fs'
import path from 'node:path'
//...
 async function init() {
//...
  try {
    result = await prompts(
      [
       //省略若干選項代碼
      ],
      {
        onCancel: () => {
          throw new Error(red('?') + ' Operation cancelled')
        }
      }
    )
  } catch (cancelled) {
    console.log(cancelled.message)
    return
  }
      //若干處理代碼
 }
 init().catch((e) => {
  console.error(e)
 })

index.js 核心就是執(zhí)行 init這個異步函數(shù), 通過選項式對話 取到配置變量后 執(zhí)行操作

擴展插件

import minimist from 'minimist'
import prompts from 'prompts'
import {
  blue,
  cyan,
  green,
  lightRed,
  magenta,
  red,
  reset,
  yellow
} from 'kolorist'

minimist 用于獲取命令行參數(shù),用于跳過后續(xù)一些選項式對話

prompts 提供了選項式對話的 命令行工具

kolorist 用來在命令行輸出不同顏色的字符

模板配置

const FRAMEWORKS = [
  {
    name: 'vanilla',
    color: yellow,
    variants: [
      {
        name: 'vanilla',
        display: 'JavaScript',
        color: yellow
      },
      {
        name: 'vanilla-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), [])

TEMPLATES 主要用來根據(jù)定義好的配置對象 生成對應后續(xù)template用到的數(shù)組

getProjectName

const getProjectName = () =>
  //path.resolve() 默認返回當前目錄
  //path.basename(path.resolve())  對應得到的就是 當前目錄名
    targetDir === '.' ? path.basename(path.resolve()) : targetDir

用于獲取項目名, 值得一提的是 path.resolve() 默認返回命令執(zhí)行的目錄,path.basename(path.resolve()) 就是獲取當前目錄名

formatTargetDir

function formatTargetDir(targetDir) {
  return targetDir?.trim().replace(/\/+$/g, '')
}

將文本去空,并將末尾的 /斜杠去掉

npm包名驗證和轉化

function toValidPackageName(projectName) {
  return projectName
    .trim()
    .toLowerCase()
    .replace(/\s+/g, '-')
    .replace(/^[._]/, '')
    .replace(/[^a-z0-9-~]+/g, '-')
}
function isValidPackageName(projectName) {
  return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(
    projectName
  )
}

用于驗證是否符合package.json name 的格式 以及轉換函數(shù)

取得模板目錄

 const templateDir = path.resolve(
    fileURLToPath(import.meta.url),
    '..',
    `template-${template}`
  )

通過resolve 拼接目錄名,根據(jù)用戶的選擇會生成對應的 比如 template-vue-ts

得到npm包管理器相關信息

const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)
  const pkgManager = pkgInfo ? pkgInfo.name : 'npm'
  function pkgFromUserAgent(userAgent) {
  if (!userAgent) return undefined
  const pkgSpec = userAgent.split(' ')[0]
  const pkgSpecArr = pkgSpec.split('/')
  return {
    name: pkgSpecArr[0],
    version: pkgSpecArr[1]
  }
}

process.env.npm_config_user_agent 會返回類似這樣的字符:

npm/6.7.5 xxxx/xxx xxx ,函數(shù)就是取出第一部分然后切割字符, 得到對應的 包管理器以及版本

文件操作相關的函數(shù)

write函數(shù) 寫入文件

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)
  }
}

targetPath先匹配.gitignore,否則直接使用參數(shù)的file值。 然后根據(jù)是否傳遞了 content參數(shù)執(zhí)行寫入 和 復制 template目錄下文件 兩個操作

copy函數(shù) 復制文件

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

判斷文件信息, 目錄則執(zhí)行 copyDir函數(shù), 否則調(diào)用 fs 下 的 copyFileSync

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)
  }
}

創(chuàng)建目標文件夾,然后遍歷源文件夾 依次將文件 copy過去

emptyDir 清空目錄

function emptyDir(dir) {
  if (!fs.existsSync(dir)) {
    return
  }
  for (const file of fs.readdirSync(dir)) {
    fs.rmSync(path.resolve(dir, file), { recursive: true, force: true })
  }
}

將目錄變?yōu)榭漳夸洝O扰袛嗄夸浭欠翊嬖冢?再遍歷執(zhí)行刪除操作

isEmpty 判斷目錄為空

function isEmpty(path) {
  const files = fs.readdirSync(path)
  return files.length === 0 || (files.length === 1 && files[0] === '.git')
}

通過fs.readdirSync 得到目錄返回的數(shù)組長度 進行判斷

核心代碼

const { framework, overwrite, packageName, variant } = result
  const root = path.join(cwd, targetDir)
//檢查是否可寫入
  if (overwrite) {
    emptyDir(root)
  } else if (!fs.existsSync(root)) {
    fs.mkdirSync(root, { recursive: true })
  }
  // determine template
  template = variant || framework || template
  console.log(`\nScaffolding project in ${root}...`)
//得到模板目錄
  const templateDir = path.resolve(
    fileURLToPath(import.meta.url),
    '..',
    `template-${template}`
  )
  const write = (file, content) => {
   //寫文件函數(shù)
  }
  const files = fs.readdirSync(templateDir) //得到模板目錄下文件信息
  //將默認目錄中非package.json 的文件 復制到 templateDir中
  for (const file of files.filter((f) => f !== 'package.json')) {
    write(file) //不傳 content 執(zhí)行 copy操作
  }
//得到模板目錄中的 package.json內(nèi)容
  const pkg = JSON.parse(
    fs.readFileSync(path.join(templateDir, `package.json`), 'utf-8')
  )
  pkg.name = packageName || getProjectName()
// 修改name 后 寫入 package.json 到 templateDir中中
  write('package.json', JSON.stringify(pkg, null, 2))
//得到對應包管理器的 信息 然后回顯
  const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)
  const pkgManager = pkgInfo ? pkgInfo.name : 'npm'
  console.log(`\nDone. Now run:\n`)
  if (root !== cwd) {
    console.log(`  cd ${path.relative(cwd, root)}`)
  }
  switch (pkgManager) {
    case 'yarn':
      console.log('  yarn')
      console.log('  yarn dev')
      break
    default:
      console.log(`  ${pkgManager} install`)
      console.log(`  ${pkgManager} run dev`)
      break
  }
  console.log()

這一步總體流程如下:

  • 檢查目錄是否可寫入
  • 得到對應的模板目錄
  • 寫入模板目錄的文件到 用戶的目錄中
  • 取得包管理器信息 回返顯示 提示信息

總結

path.resolve 是相對于當前工作目錄 返回路徑

path.join 是 根據(jù)path字符串片段拼接返回一個路徑 需要注意區(qū)別

至此 代碼和流程就分析完畢了,相對于create-vue, create-vite要簡單一點點

對于不懂或者不了解的地方, 復現(xiàn)或者嘗試重寫進行舉一反三 是加深 認知 和學習 更好的方式,光是看和閱讀領悟還是不夠的!

寫了個練習用的小工具,可以用來快捷的生成Vue模板頁面

create-harexs-tp

以上就是Create vite理解Vite項目創(chuàng)建流程及代碼實現(xiàn)的詳細內(nèi)容,更多關于Create vite 項目創(chuàng)建流程的資料請關注腳本之家其它相關文章!

相關文章

  • vue百度地圖實現(xiàn)自定義彈框樣式

    vue百度地圖實現(xiàn)自定義彈框樣式

    這篇文章主要介紹了vue百度地圖實現(xiàn)自定義彈框樣式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 使用vue+element?ui實現(xiàn)走馬燈切換預覽表格數(shù)據(jù)

    使用vue+element?ui實現(xiàn)走馬燈切換預覽表格數(shù)據(jù)

    這次做項目的時候遇到需要切換預覽表格數(shù)據(jù)的需求,所以下面這篇文章主要給大家介紹了關于使用vue+element?ui實現(xiàn)走馬燈切換預覽表格數(shù)據(jù)的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • Vue 3開發(fā)中VueUse強大Hooks庫

    Vue 3開發(fā)中VueUse強大Hooks庫

    VueUse提供了一個豐富且強大的Hooks庫,可以幫助開發(fā)者快速實現(xiàn)各種功能,提高開發(fā)效率,本文來詳細的介紹一下,需要的朋友們下面隨著小編來一起學習學習吧
    2024-08-08
  • Vue生命周期與setup深入詳解

    Vue生命周期與setup深入詳解

    Vue的生命周期就是vue實例從創(chuàng)建到銷毀的全過程,也就是new Vue() 開始就是vue生命周期的開始。Vue 實例有?個完整的?命周期,也就是從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模版、掛載Dom -> 渲染、更新 -> 渲染、卸載 等?系列過程,稱這是Vue的?命周期
    2022-09-09
  • vue項目初始化到登錄login頁面的示例

    vue項目初始化到登錄login頁面的示例

    今天小編就為大家分享一篇vue項目初始化到登錄login頁面的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • Vue-element-admin平臺側邊欄收縮控制問題

    Vue-element-admin平臺側邊欄收縮控制問題

    這篇文章主要介紹了Vue-element-admin平臺側邊欄收縮控制問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Vue3+Element Plus實現(xiàn)自定義彈窗組件的全屏功能

    Vue3+Element Plus實現(xiàn)自定義彈窗組件的全屏功能

    在現(xiàn)代化的前端開發(fā)中,彈窗組件是提升用戶體驗的重要元素,本文將介紹如何使用 Vue 3 和 Element Plus 庫來創(chuàng)建一個具有全屏功能的自定義彈窗組件,文中通過代碼示例講解的非常詳細,需要的朋友可以參考下
    2024-07-07
  • 詳解windows下vue-cli及webpack 構建網(wǎng)站(四) 路由vue-router的使用

    詳解windows下vue-cli及webpack 構建網(wǎng)站(四) 路由vue-router的使用

    本篇文章主要介紹了windows下vue-cli及webpack 構建網(wǎng)站(四) 路由vue-router的使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • vue監(jiān)聽用戶輸入和點擊功能

    vue監(jiān)聽用戶輸入和點擊功能

    這篇文章主要為大家詳細介紹了vue監(jiān)聽用戶輸入和點擊功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • vue Draggable實現(xiàn)拖動改變順序

    vue Draggable實現(xiàn)拖動改變順序

    這篇文章主要為大家詳細介紹了vue Draggable實現(xiàn)拖動改變順序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04

最新評論