首页 > 科普大全

create参数详解(create-vite原理揭秘)

科普大全 2023-09-09 11:50:01
有许多的朋友最近问小编create参数详解(create-vite原理揭秘)的问题,那么小编收集整合后,今天为大家分享关于的相关文章,一起来了解一下吧!

create参数详解(create-vite原理揭秘)

大家好,我是鄂茶哥。

你通常会很开心。npm create vite@lastest初始化一个vite项目。

那么你知道它的原理是什么吗?

今天这篇文章就带领大家一起学习它的原理,源代码不到400行。

2. npm init && npm create

Npm初始化文档[4]已写入。Create实际上是init的别名。

也就是说,npm create vite@lastest相当于= >;Npx create-vite@lastest,latest是版本号,可以通过以下命令查看最新版本。

NPM dist-tag ls create-vite # output #最新版本:3.0.0

然后我们克隆vite项目,调试包/create-vite,分析它的源代码实现。

3. 克隆项目 && 调试源码

正如我在上一篇文章中所写的,新手程序员必须学习的基本技能——调试JS代码,这里就不赘述了。

可以直接克隆我的项目调试。同时,请欢迎明星。看开源项目,一般先看README.md[5]和对应的CONTRIBUTING.md[6]。

git clone https://github.com/lxchuan12/vite-analysis.gitcd vite-analysis/vite 2 # NPM I-g pnpmpnpm install # At this index . js文件断点#调试节点vite 2/packages/create-vite/index . js在命令行终端。

贡献文档[7]还详细介绍了如何调试[8]。

调试截图:

调试截图

控制台输出:

控制台输出

最终生成的文件:

顺便问一下,我如何保存vite记录?其实我用的是git子树。

#创建git子树add-prefix = vite 2 https://github.com/vitejs/vite.git Main #更新git子树pull-prefix = vite 2 https://github.com/vitejs/vite.git Main

找到路径,packages/create-vite看看package.json。

{ "姓名& # 34;: "创建-邀请& # 34;, "版本& # 34;: "3.0.0", "类型& # 34;: "模块& # 34;, "斌& # 34;: { "创建-邀请& # 34;: "index.js & # 34, "cva & # 34: "index.js & # 34}, "main & # 34: "index.js & # 34, "引擎& # 34;: { "节点& # 34;: "^14.18.0 | | >;=16.0.0"},}

型号指定模块是指ES模块。bin可执行命令是create-vite或别名cva。我们可以知道主文件index.js代码限制了Nodejs的更高版本。

然后我们进行调试以查看这个index.js文件。

4. 主流程 init 函数拆分

//高级版本的节点支持,节点前缀从& # 39;节点:fs & # 39导入路径来自& # 39;节点:路径& # 39;从& # 39;导入{ fileURLToPath };节点:url & # 39//解析命令行的参数链接:https://npm.im/minimistimport minimit from & # 39;最小化& # 39;//求一个这样的链接:https://npm.im/promptsimport提示来自& # 39;提示& # 39;//终端色彩输出的库链接:https://npm.im/koloristimport {蓝色、青色、绿色、浅红色、品红色、红色、复位、黄色} from & # 39kolorist & # 39//通过定义与选项(_)关联的参数// non需要被解析为字符串,避免自动转换为项目名称的数字。请参阅# 4606 const argv = minimat(process . argv . slice(2),{ string:[& # 39;_']})//当前Nodejs执行目录const cwd = process.cwd()//省略主函数内容,异步函数init () {} init()。catch ((e) = > { console.error(e)})

4.1 输出的目标路径

//命令行的第一个参数,而不是反斜杠/是空字符串Lettargetdir = Format Targetdir(argv。_[0])//命令行参数-template or-tlettemplate = argv . template | | argv . t const默认Targetdir = & # 39vite-project & # 39;//获取项目名称const Get project name =()= & gt;targetDir = = = & # 39。'?path . basename(path . resolve()):targetDir

4.1.1 延伸函数 formatTargetDir

将反斜杠/替换为空字符串。

函数格式targetDir(targetDir){ return targetDir?。修剪()。替换(/\/ $/g,& # 39;')}

4.2 prompts 询问项目名、选择框架,选择框架变体等

提示[9]根据用户的输入和选择,代码已被删除。

let result = { } try { result = await prompts([{ type:targetDir?null:& # 39;正文& # 39;,姓名:& # 39;projectName & # 39,消息:重置(& # 39;项目名称:& # 39;),initial: defaultTargetDir,onState:(state)= & gt;{ Targetdir = Format Targetdir(state。value) || DefaultTargetdir}},//省略一些],{ on cancel:()= & gt;{抛出新错误(红色(& # 39;✖') '操作被取消& # 39;)} } } } Catch(cancelled){ console . log(cancelled . message)return }//与提示关联的用户选择//框架framework //覆盖现有目录。是否要重写// packageName输入的项目名// variant,如react = & gtreact-tsconst { framework,overwrite,packageName,variant } = result

4.3 重写已有目录/或者创建不存在的目录

//与提示关联的用户选择const {framework,overwrite,packagename,variant } = result//directory const root = path . join(CWD,targetdir)if(overwrite){//Delete folder empty dir(root)} else if(!fs . exist sync(root)){//新文件夹fs.mkdirsync (root,{recursive: true})}

4.3.1 延伸函数 emptyDir

递归删除文件夹,相当于rm -rf xxx。

函数emptyDir(dir) { if(!fs . exists sync(dir)){ return } for(fs . readdirsync(dir)的const文件){ fs.rmSync(path.resolve(dir,file),{ recursive: true,force: true }) }}

4.4 获取模板路径

有这些模板目录。

从模板可以看出,目前还是比较简单的。例如,没有配置eslint appellister。如果你想为多个vite项目工作,自动添加eslint更漂亮。这里推荐Vite-pretty-lint[10],我为这个库写的源码是在第35期看的[11],也有别人写的关于如何一键自动添加eslint和pretty的支持到前端项目的好文章[12]。

//determine template template = variant | | framework | | template console . log(` \ nscafolding project in $ { root }...`)const templateDir = path . resolve(fileURLToPath(import . meta . URL),& # 39;..',` template-${template} `)

4.5 写入文件函数

const write =(文件,内容)= & gt{//rename file const target path = rename files[file]?path.join(root,rename files[file]):path . join(root,file)if(content){ fs . writefilesync(target path,content)} else { copy(path . join(templateDir,file),targetPath) }}

重命名文件是因为。某些编辑器或计算机不支持gitignore。

const rename files = { _ git ignore:& # 39;。gitignore & # 39}

4.5.1 延伸函数 copy && copyDir

如果是文件夹,用copyDir复制

函数copy(src,dest){ const stat = fs . statsync(src)if(stat . is directory()){ copy dir(src,dest) } else { fs.copyFileSync(src,dest)} }/* * * * @ param { string } srcDir * @ param { string } destDir */函数copyDir(srcDir,destDir) { fs.mkdirSync(destDir,{ recursive:true })for(fs . readdirsync的const文件(srcDir

4.6 根据模板路径的文件写入目标路径

package.json文件是单独处理的。它的名称是输入的packageName或get。

const files = fs . readdirsync(templateDir)for(const file of files . filter((f)= & gt;f!== 'package.json & # 39)){ write(file)} const pkg = JSON . parse(fs . read file sync(path . join(templateDir,' package.json `),& # 39;utf-8 & # 39;))pkg . name = package name | | get project name()write(& # 39;package.json & # 39,JSON.stringify(pkg,null,2))

4.7 打印安装完成后的信息

const pkgInfo = pkgFromUserAgent(process . env . NPM _ config _ user _ agent)const pkg manager = pkgInfo?pkginfo . name:& # 39;npm & # 39console.log(`\nDone。现在运行:\n`)if (root!= = CWD){ console . log(` CD $ { path . relative(CWD,root)} `)} switch(pkg manager){ case & # 39;纱& # 39;:console . log(& # 39;纱& # 39;)console . log(& # 39;纱线开发& # 39;)break default:console . log(` ${ pkg manager } install `)console . log(` ${ pkg manager } run dev `)break } console . log()

4.7.1 延伸的 pkgFromUserAgent 函数

/* * * * @ param { string | undefined } user agent process . env . NPM _ config _ user _ agent * @ returns object | undefined */function pkgFromUserAgent(user agent){ if(!userAgent)返回未定义的const pkg spec = user agent . split(& # 39;')[0]const pkgSpecArr = pkgspec . split(& # 39;/')返回{ name: pkgSpecArr[0],version: pkgSpecArr[1] }}

第一个pkgFromUserAgent函数是从使用的包管理器创建一个项目,然后输出相应的命令npm/yarn/pnpm。

npm创建vite@lastestyarn创建vitepnpm创建vite

5. 总结

让我们回顾一下控制台输出:

控制台输出

至此,我们已经分析了整个过程。代码行总数不多,不到400行。

{ "姓名& # 34;: "创建-邀请& # 34;, "版本& # 34;: "3.0.0", "类型& # 34;: "模块& # 34;, "引擎& # 34;: { "节点& # 34;: "^14.18.0 | | >;=16.0.0"}}

从package.json可以看出,代码限制了Nodejs的更高版本,使用es模块,目前不涉及打包编译。

为了保证轻量和速度,源代码中很多函数都是自己写的。比如查项目名,有著名的validate-npm-package-name[13],在vue-cli和create-react-app中都用到。比如删除文件和文件夹也是自己实现的。

依赖包很少。只靠三包。分析命令行参数minimast [14],询问选择等提示[15],终端颜色输出的库kolorist[16]

本文不涉及测试用例,有兴趣的伙伴可以看看。路径:vite/packages/create-vite/_ _ tests _ _/CLI . spec . ts[17],采用vitest[18]。

看完这篇文章,你会发现每天都要用npm create vite来初始化vite项目,create-vite只有不到400行的源代码。

我们也可以根据公司相关业务开发自己的脚手架工具。

如果觉得vite项目模板不够用,也可以自己修改添加。例如,库vite-pretty-lint[19]一键自动为多个vite项目添加eslint和pretty。

有时候我们很容易被局限在公司的项目里,从来不看开源世界,开源项目的源代码就在那里。如果我们真的愿意学习,我们可以学到很多东西。

很多源码并没有我们想象的那么深奥。源代码不应该是我们的障碍,而是我们的导师。这也可以说是我继续组织源代码阅读活动的原因之一。

,

标签: 原理   参数

生活百科 饮食百科 健康养生 美容减肥 自然百科 科普大全 文化常识
Copyright 百科网 备案号:冀ICP备2022029337号-3本站图文信息均来自于网络收集,仅供大家参考,不作为医疗诊断依据。
统计代码