日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

vue 使用fs_模仿vue-cli,手写一个脚手架

發布時間:2025/3/19 vue 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue 使用fs_模仿vue-cli,手写一个脚手架 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

vue-cli

在vue的開發的過程中,經常會使用到vue-cli腳手架工具去生成一個項目。在終端運行命令vue create hello-world后,就會有許多自動的腳本運行。

  • 為什么會這樣運行呢?
  • 我們自己是否也能寫一個腳手架工具?
    帶著這樣的疑問,我們先來看看vue-cli。

解讀vue-cli

首先我們可以來到vue-cli的安裝目錄:
mac用戶來到路徑:/usr/local/lib/node_modules 可以看到(windows可以自行到全局安裝的目錄下查看)

此時用我們的編輯器 打開@vue文件:

lib內放的是具體各種配置和各種類,對于我們來說,這個目錄內的就是所謂的業務邏輯。
bin內放的就是腳本命令的入口,調用lib的入口,入口在package.json內紅框定義。我們姑且先放下業務邏輯,來看看這個入口文件。

現在,我們先放下所有的疑慮,我們打開bin/vue.js。我們可以看到以下內容:

看完之后有什么感覺?咦?怎么跟終端內輸出的好像?沒錯,就是這樣,這就是我們使用vue-cli的時候具體的命令。我們去終端輸入vue:

發現了嗎,終端內的具體命令全在vue.js內定義過了。

program.command('create <app-name>').description('create a new project powered by vue-cli-service') program.command('add <plugin> [pluginOptions]').description('install a plugin and invoke its generator in an already created project') program.command('invoke <plugin> [pluginOptions]')

好了,剩下代碼有興趣的可以自行打開對應目錄讀下去,可以學習人家優秀的設計思想。對于本文來說,剩下的許多東西都是業務代碼了。我們開頭的疑問為什么會這樣運行呢?已經了解了一個大概了。我們現在來看看我們自己是否也能寫一個腳手架工具?,答案是肯定的。開始動手吧。

手寫一個自己的腳手架

先來看看可能需要用到哪些npm的包:

  • commander:參數解析
  • inquirer:交互式命令行工具,有他就可以實現命令行的選擇功能
  • chalk:輸出文本顏色,為了美麗~
    后續可能隨著模塊的增加,會出現更多需要的包

1. 創建項目

npm init -y # 初始化package.json

2. 創建文件目錄

  • 在package.json內添加“bin”
  • bin下的文件沒有格式,且第一行必須是#! /usr/bin/env node

3. 鏈接包到全局

npm link # // 取消鏈接 npm unlink

有時候可能需要在上面命令后面拼接 --force,mac權限問題記得前面sudo
可以去目錄:/usr/local/lib/node_modules 查看,發現我們多了一個,同時在這時候終端輸入一下試試,我們在package.json下叫的name叫superman-cli,所以我們的命令就是叫superman-cli:

好了,基礎配置初始化的工作全部結束了!

4. 第一個命令

首先安裝包commander

npm install commander --save

在目錄bin/superman內

#! /usr/bin/env node// console.log(1) const program = require('commander')program.version(`Version is ${require('../package.json').version}`).description('從0開始 手寫腳手架').usage('<command> [options]')program.parse(process.argv)

測試有效!

然后我們在前面Version命令下加入代碼:

program.command('create <app-name>').description('create a new project').option('-f, --force', 'Overwrite target directory if it exists').option('-c, --clone', 'Use git clone when fetching remote preset').action((name, cmd) => {console.log('name', name)console.log('cmd', cmd)})

仔細對比我們的代碼合終端的輸出,我們就可以看到我們寫的很多東西都生效了。接下來我們就優化一下.action下的參數,畢竟一大堆也不好處理:

program.command('create <app-name>').description('create a new project').option('-f, --force', 'Overwrite target directory if it exists').option('-c, --clone', 'Use git clone when fetching remote preset').action((name, cmd) => {const options = cleanArgs(cmd)console.log(options)}) function camelize (str) {return str.replace(/-(w)/g, (_, c) => c ? c.toUpperCase() : '') } function cleanArgs (cmd) {const args = {}// console.log(cmd)cmd.options.forEach(o => {const key = camelize(o.long.replace(/^--/, ''))// console.log(key)// console.log(cmd[key])// console.log(typeof cmd[key])if (typeof cmd[key] !== 'function' && typeof cmd[key] !== 'undefined') {args[key] = cmd[key]}})return args }

具體不懂的也可以像我注釋的console.log一樣,慢慢看就明白了


image

我們第一個命令已經完成一大半了,接下來就是我們這個create命令具體干什么事情。(在這個文件里,我們只管命令,就像vue-cli一樣,這也是我們需要學習的地方,模塊如何去處理)

// 在上面.action內補充一行代碼.action((name, cmd) => {const options = cleanArgs(cmd)console.log(options)require('../lib/create')(name, options)})

同時去lib下創建文件create.js

const path = require('path') // const fs = require('fs-extra') async function create (projectName, options) {console.log(projectName, options)const cwd = process.cwd(); // 獲取當前命令執行時的工作目錄const targetDir = path.join(cwd,projectName); // 目標目錄console.log(targetDir) }module.exports = (...args) => {return create(...args) }

繼續執行superman-cli create hello -f,我們可以得到,force:true,如果新建的話,將來的目錄會是/Users/chenjing/hello

接下來我們嘗試創建目錄hello,不過我們需要考慮幾個問題:

  • 是否已經存在目錄hello了?(使用fs-extra包)
  • 若存在是要刪除覆蓋還是停止操作?(這里就需要用到插件inquirer啦,進行選擇)
npm install fs-extra --save npm install inquirer --save

直接上代碼:

const path = require('path') const fsextra = require('fs-extra') const fs = require('fs') const Inquirer = require('inquirer') async function create (projectName, options) {console.log(projectName, options)const cwd = process.cwd(); // 獲取當前命令執行時的工作目錄const targetDir = path.join(cwd,projectName); // 目標目錄console.log(targetDir)if (fsextra.existsSync(targetDir)) {if (options.force) {// 如果強制創建 ,刪除已有的await fsextra.remove(targetDir);console.log('刪除成功')createDir(projectName)} else {let { action } = await Inquirer.prompt([{name: 'action',type: 'list',message: 'Target directory already exists Pick an action:',choices: [{name:'Overwrite',value:'overwrite'},{name:'Cancel',value:false}]}])if (!action) {console.log('取消操作')return} else if (action === 'overwrite') {console.log(`rnRemoving....`);await fsextra.remove(targetDir)console.log('刪除成功')createDir(projectName)}}} else {createDir(projectName)} } function createDir (projectName) {fs.mkdir(`./${projectName}`, function (err) {if (err) {console.log('創建失敗')} else {console.log('創建成功')}}) }module.exports = (...args) => {return create(...args) }

看效果,先來的一個空目錄

superman-cli create hello superman-cli create hello // 再次 superman-cli create hello -f // 覆蓋

4. 小結

本篇的源碼github地址

并不是說我們手寫腳手架就到此結束了,只是要完整實現一個功能不是一兩篇文章可以搞定的。不過我相信寫到這里,動手能力強的一定也能體驗一把手動模仿vue-cli的爽了。至于能寫出什么牛C的腳手架,真的就是個人需求和業務代碼堆加。當然可以發散思維后續還可以做許多許多事情。強烈建議閱讀vue-cli。或者其他腳手架的源碼,都在目錄:/usr/local/lib/node_modules 下面,看源碼真的是學習最直接的方法了,甚至copy人家的代碼到自己的cli內執行。其樂無窮

作者:超人陳立青
鏈接:https://www.jianshu.com/p/75de24392de8
來源:簡書

總結

以上是生活随笔為你收集整理的vue 使用fs_模仿vue-cli,手写一个脚手架的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。