學習 launch-editor 源碼整體架構,探究 vue-devtools「在編輯器中打開組件」功能實現原理...

1. 前言

你好,我是若川[1],微信搜索「若川視野」關注我,專注前端技術分享,一個愿景是幫助5年內前端開闊視野走向前列的公眾號。歡迎加我微信ruochuan12,長期交流學習。

這是學習源碼整體架構系列 之 launch-editor 源碼(第九篇)。學習源碼整體架構系列文章(有哪些必看的JS庫):jQuery、underscore、lodash、sentry、vuex、axios、koa、redux。整體架構這詞語好像有點大,姑且就算是源碼整體結構吧,主要就是學習是代碼整體結構,不深究其他不是主線的具體函數的實現。本篇文章學習的是實際倉庫的代碼。下一篇應該是《學習 Vuex 4 源碼整體架構,深入理解其原理及provide/inject原理》。

本文倉庫地址[2]git clone https://github.com/lxchuan12/open-in-editor.git,本文最佳閱讀方式,克隆倉庫自己動手調試,容易吸收消化。

要是有人說到怎么讀源碼,正在讀文章的你能推薦我的源碼系列文章,那真是無以為報啊

我的文章盡量寫得讓想看源碼又不知道怎么看的讀者能看懂。我都是推薦使用搭建環境斷點調試源碼學習哪里不會點哪里邊調試邊看,而不是硬看。正所謂:授人與魚不如授人予漁

閱讀本文后你將學到:

  1. 如何解決該功能報錯問題

  2. 如何調試學習源碼

  3. launch-editor 等實現原理

1.1 短時間找不到頁面對應源文件的場景

不知道你們有沒有碰到這樣的場景,打開你自己(或者你同事)開發的頁面,卻短時間難以找到對應的源文件。

這時你可能會想要是能有點擊頁面按鈕自動用編輯器打開對應文件的功能,那該多好啊。

vue-devtools提供了這樣的功能,也許你不知道。我覺得很大一部分人都不知道,因為感覺很多人都不常用vue-devtools

open-in-editor

你也許會問,我不用vue,我用react有沒有類似功能啊,有啊,請看react-dev-inspector[3]

本文就是根據學習尤大寫的 launch-editor[4] 源碼,本著知其然,知其所以然的宗旨,探究 vue-devtools「在編輯器中打開組件」功能實現原理。

1.2 一句話簡述其原理

code?path/to/file

一句話簡述原理:利用nodejs中的child_process,執行了類似code path/to/file命令,于是對應編輯器就打開了相應的文件,而對應的編輯器則是通過在進程中執行ps xWindow則用Get-Process)命令來查找的,當然也可以自己指定編輯器。

1.3 打開編輯器無法打開組件的報錯解決方法

而你真正用這個功能時,你可能碰到報錯,說不能打開這個文件。

Could?not?open?App.vue?in?the?editor.To?specify?an?editor,?specify?the?EDITOR?env?variable?or?add?"editor"?field?to?your?Vue?project?config.
控制臺不能打開編輯器的錯誤提示

這里說明下寫這篇文章時用的是 Windows 電腦,在Ubuntu子系統下使用的終端工具。同時推薦我的文章使用 ohmyzsh 打造 windows、ubuntu、mac 系統高效終端命令行工具,用過的都說好

解決辦法也簡單,就是這句英文的意思。具體說明編輯器,在環境變量中說明指定編輯器。在vue項目的根目錄下,對應本文則是:vue3-project,添加.env.delelopment文件,其內容是EDITOR=code

#?.env.development
#?當然,我的命令行終端已經有了code這個命令。
EDITOR=code

不用指定編輯器的對應路徑(c/Users/lxchu/AppData/Local/Programs/Microsoft VS Code/bin/code),因為會報錯。為什么會報錯,因為我看了源碼且試過。因為會被根據空格截斷,變成c/Users/lxchu/AppData/Local/Programs/Microsoft,當然就報錯了。

接下來我們從源碼角度探究「在編輯器中打開組件」功能的實現原理。

2. vue-devtools Open component in editor 文檔

探究原理之前,先來看看vue-devtools官方文檔。

vuejs/vue-devtools[5]文檔

Open component in editor
To enable this feature, follow this guide[6].

這篇指南中寫了在Vue CLI 3中是開箱即用

Vue?CLI?3?supports?this?feature?out-of-the-box?when?running?vue-cli-service?serve.

也詳細寫了如何在Webpack下使用。

#?1.?Import?the?package:
var?openInEditor?=?require('launch-editor-middleware')
#?2.?In?the?devServer?option,?register?the?/__open-in-editor?HTTP?route:
devServer:?{before?(app)?{app.use('/__open-in-editor',?openInEditor())}
}
#?3.?The?editor?to?launch?is?guessed.?You?can?also?specify?the?editor?app?with?the?editor?option.?See?the?supported?editors?list.
#?用哪個編輯器打開會自動猜測。你也可以具體指明編輯器。這里顯示更多的支持編輯器列表
openInEditor('code')
#?4.?You?can?now?click?on?the?name?of?the?component?in?the?Component?inspector?pane?(if?the?devtools?knows?about?its?file?source,?a?tooltip?will?appear).
#?如果`vue-devtools`開發者工具有提示點擊的組件的顯示具體路徑,那么你可以在編輯器打開。

同時也寫了如何在Node.js中使用等。

Node.js
You can use the launch-editor[7] package to setup an HTTP route with the /__open-in-editor path. It will receive file as an URL variable.

查看更多可以看這篇指南[8]

3. 環境準備工作

熟悉我的讀者,都知道我都是推薦調試看源碼的,正所謂:哪里不會點哪里。而且調試一般都寫得很詳細,是希望能幫助到一部分人知道如何看源碼。于是我特意新建一個倉庫open-in-editor[9] git clone https://github.com/lxchuan12/open-in-editor.git,便于大家克隆學習。

安裝vue-cli

npm?install?-g?@vue/cli
#?OR
yarn?global?add?@vue/cli
node?-V
#?v14.16.0
vue?-V?
#?@vue/cli?4.5.12
vue?create?vue3-project
#?這里選擇的是vue3、vue2也是一樣的。
#?Please?pick?a?preset:?Default?(Vue?3?Preview)?([Vue?3]?babel,?eslint)
npm?install
#?OR
yarn?install

這里同時說明下我的vscode版本。

code?-v
1.55.2

前文提到的Vue CLI 3開箱即用Webpack使用方法。

vue3-project/package.json中有一個debug按鈕。

debug示意圖

選擇第一項,serve vue-cli-service serve

我們來搜索下'launch-editor-middleware'這個中間件,一般來說搜索不到node_modules下的文件,需要設置下。當然也有個簡單做法。就是「排除的文件」右側旁邊有個設置圖標「使用“排查設置”與“忽略文件”」,點擊下。

其他的就不贅述了。可以看這篇知乎回答:vscode怎么設置可以搜索包含node_modules中的文件?[10]

這時就搜到了vue3-project/node_modules/@vue/cli-service/lib/commands/serve.js中有使用這個中間件。

4. vue-devtools 開箱即用具體源碼實現

接著我們來看Vue CLI 3開箱即用具體源碼實現。

//?vue3-project/node_modules/@vue/cli-service/lib/commands/serve.js
//?46行
const?launchEditorMiddleware?=?require('launch-editor-middleware')
//?192行
before?(app,?server)?{//?launch?editor?support.//?this?works?with?vue-devtools?&?@vue/cli-overlayapp.use('/__open-in-editor',?launchEditorMiddleware(()?=>?console.log(`To?specify?an?editor,?specify?the?EDITOR?env?variable?or?`?+`add?"editor"?field?to?your?Vue?project?config.\n`)))//?省略若干代碼...
}

點擊vue-devtools中的時,會有一個請求,http://localhost:8080/__open-in-editor?file=src/App.vue,不出意外就會打開該組件啦。

open src/App.vue in editor

接著我們在launchEditorMiddleware的具體實現。

5. launch-editor-middleware

看源碼時,先看調試截圖。

debug-launch

launch-editor-middleware中間件中作用在于最終是調用 launch-editor 打開文件。

//?vue3-project/node_modules/launch-editor-middleware/index.js
const?url?=?require('url')
const?path?=?require('path')
const?launch?=?require('launch-editor')module.exports?=?(specifiedEditor,?srcRoot,?onErrorCallback)?=>?{//?specifiedEditor?=>?這里傳遞過來的則是?()?=>?console.log()?函數//?所以和?onErrorCallback?切換下,把它賦值給錯誤回調函數if?(typeof?specifiedEditor?===?'function')?{onErrorCallback?=?specifiedEditorspecifiedEditor?=?undefined}//?如果第二個參數是函數,同樣把它賦值給錯誤回調函數//?這里傳遞過來的是undefinedif?(typeof?srcRoot?===?'function')?{onErrorCallback?=?srcRootsrcRoot?=?undefined}//?srcRoot?是傳遞過來的參數,或者當前node進程的目錄srcRoot?=?srcRoot?||?process.cwd()//?最后返回一個函數,?express?中間件return?function?launchEditorMiddleware?(req,?res,?next)?{//?省略?...}
}

上一段中,這種切換參數的寫法,在很多源碼中都很常見。為的是方便用戶調用時傳參。雖然是多個參數,但可以傳一個或者兩個

可以根據情況打上斷點。比如這里我會在launch(path.resolve(srcRoot, file), specifiedEditor, onErrorCallback)打斷點。

//?vue3-project/node_modules/launch-editor-middleware/index.js
module.exports?=?(specifiedEditor,?srcRoot,?onErrorCallback)?=>?{//?省略上半部分return?function?launchEditorMiddleware?(req,?res,?next)?{//?根據請求解析出file路徑const?{?file?}?=?url.parse(req.url,?true).query?||?{}//?如果沒有文件路徑,則報錯if?(!file)?{res.statusCode?=?500res.end(`launch-editor-middleware:?required?query?param?"file"?is?missing.`)}?else?{//?否則拼接路徑,用launch打開。launch(path.resolve(srcRoot,?file),?specifiedEditor,?onErrorCallback)res.end()}}
}

6. launch-editor

跟著斷點來看,走到了launchEditor函數。

//?vue3-project/node_modules/launch-editor/index.js
function?launchEditor?(file,?specifiedEditor,?onErrorCallback)?{//?解析出文件路徑和行號列號等信息const?parsed?=?parseFile(file)let?{?fileName?}?=?parsedconst?{?lineNumber,?columnNumber?}?=?parsed//?判斷文件是否存在,不存在,直接返回。if?(!fs.existsSync(fileName))?{return}//?所以和?onErrorCallback?切換下,把它賦值給錯誤回調函數if?(typeof?specifiedEditor?===?'function')?{onErrorCallback?=?specifiedEditorspecifiedEditor?=?undefined}//?包裹一層函數onErrorCallback?=?wrapErrorCallback(onErrorCallback)//?猜測當前進程運行的是哪個編輯器const?[editor,?...args]?=?guessEditor(specifiedEditor)if?(!editor)?{onErrorCallback(fileName,?null)return}//?省略剩余部分,后文再講述...
}

6.1 wrapErrorCallback 包裹錯誤函數回調

onErrorCallback?=?wrapErrorCallback(onErrorCallback)

這段的代碼,我相信讀者朋友能看懂,我單獨拿出來講述,主要是因為這種包裹函數的形式在很多源碼里都很常見。這里也就是文章開頭終端錯誤圖Could not open App.vue in the editor.輸出的代碼位置。

//?vue3-project/node_modules/launch-editor/index.js
function?wrapErrorCallback?(cb)?{return?(fileName,?errorMessage)?=>?{console.log()console.log(chalk.red('Could?not?open?'?+?path.basename(fileName)?+?'?in?the?editor.'))if?(errorMessage)?{if?(errorMessage[errorMessage.length?-?1]?!==?'.')?{errorMessage?+=?'.'}console.log(chalk.red('The?editor?process?exited?with?an?error:?'?+?errorMessage))}console.log()if?(cb)?cb(fileName,?errorMessage)}
}

6.2 guessEditor 猜測當前正在使用的編輯器

這個函數主要做了如下四件事情:

  1. 如果具體指明了編輯器,則解析下返回。

  2. 找出當前進程中哪一個編輯器正在運行。macOSLinuxps x 命令
    windows 則用 Get-Process 命令

  3. 如果都沒找到就用 process.env.VISUAL或者process.env.EDITOR。這就是為啥開頭錯誤提示可以使用環境變量指定編輯器的原因。

  4. 最后還是沒有找到就返回[null],則會報錯。

const?[editor,?...args]?=?guessEditor(specifiedEditor)
if?(!editor)?{onErrorCallback(fileName,?null)return
}
//?vue3-project/node_modules/launch-editor/guess.js
const?shellQuote?=?require('shell-quote')module.exports?=?function?guessEditor?(specifiedEditor)?{//?如果指定了編輯器,則解析一下,這里沒有傳入。如果自己指定了路徑。//?比如?c/Users/lxchu/AppData/Local/Programs/Microsoft?VS?Code/bin/code?//???會根據空格切割成?c/Users/lxchu/AppData/Local/Programs/Microsoftif?(specifiedEditor)?{return?shellQuote.parse(specifiedEditor)}//?We?can?find?out?which?editor?is?currently?running?by://?`ps?x`?on?macOS?and?Linux//?`Get-Process`?on?Windowstry?{//??省略...}?catch?(error)?{//?Ignore...}//?Last?resort,?use?old?skool?env?varsif?(process.env.VISUAL)?{return?[process.env.VISUAL]}?else?if?(process.env.EDITOR)?{return?[process.env.EDITOR]}return?[null]
}

看完了 guessEditor 函數,我們接著來看 launch-editor 剩余部分。

6.3 launch-editor 剩余部分

以下這段代碼不用細看,調試的時候細看就行。

//?vue3-project/node_modules/launch-editor/index.js
function?launchEditor(){//??省略上部分...if?(process.platform?===?'linux'?&&fileName.startsWith('/mnt/')?&&/Microsoft/i.test(os.release()))?{//?Assume?WSL?/?"Bash?on?Ubuntu?on?Windows"?is?being?used,?and//?that?the?file?exists?on?the?Windows?file?system.//?`os.release()`?is?"4.4.0-43-Microsoft"?in?the?current?release//?build?of?WSL,?see:?https://github.com/Microsoft/BashOnWindows/issues/423#issuecomment-221627364//?When?a?Windows?editor?is?specified,?interop?functionality?can//?handle?the?path?translation,?but?only?if?a?relative?path?is?used.fileName?=?path.relative('',?fileName)}if?(lineNumber)?{const?extraArgs?=?getArgumentsForPosition(editor,?fileName,?lineNumber,?columnNumber)args.push.apply(args,?extraArgs)}?else?{args.push(fileName)}if?(_childProcess?&&?isTerminalEditor(editor))?{//?There's?an?existing?editor?process?already?and?it's?attached//?to?the?terminal,?so?go?kill?it.?Otherwise?two?separate?editor//?instances?attach?to?the?stdin/stdout?which?gets?confusing._childProcess.kill('SIGKILL')}if?(process.platform?===?'win32')?{//?On?Windows,?launch?the?editor?in?a?shell?because?spawn?can?only//?launch?.exe?files._childProcess?=?childProcess.spawn('cmd.exe',['/C',?editor].concat(args),{?stdio:?'inherit'?})}?else?{_childProcess?=?childProcess.spawn(editor,?args,?{?stdio:?'inherit'?})}_childProcess.on('exit',?function?(errorCode)?{_childProcess?=?nullif?(errorCode)?{onErrorCallback(fileName,?'(code?'?+?errorCode?+?')')}})_childProcess.on('error',?function?(error)?{onErrorCallback(fileName,?error.message)})
}

這一大段中,主要的就是以下代碼,用子進程模塊。簡單來說子進程模塊有著執行命令的能力。

const?childProcess?=?require('child_process')if?(process.platform?===?'win32')?{//?On?Windows,?launch?the?editor?in?a?shell?because?spawn?can?only//?launch?.exe?files._childProcess?=?childProcess.spawn('cmd.exe',['/C',?editor].concat(args),{?stdio:?'inherit'?})}?else?{_childProcess?=?childProcess.spawn(editor,?args,?{?stdio:?'inherit'?})
}

行文至此,就基本接近尾聲了。

7. 總結

這里總結一下:首先文章開頭通過提出「短時間找不到頁面對應源文件的場景」,并針對容易碰到的報錯情況給出了解決方案。其次,配置了環境跟著調試學習了vue-devtools中使用的尤大寫的 yyx990803/launch-editor[11]

7.1 一句話簡述其原理

我們回顧下開頭的原理內容。

code?path/to/file

一句話簡述原理:利用nodejs中的child_process,執行了類似code path/to/file命令,于是對應編輯器就打開了相應的文件,而對應的編輯器則是通過在進程中執行ps xWindow則用Get-Process)命令來查找的,當然也可以自己指定編輯器。

最后還能做什么呢。

可以再看看 umijs/launch-editor[12] 和 react-dev-utils/launchEditor.js[13] 。他們的代碼幾乎類似。

也可以利用Node.js做一些提高開發效率等工作,同時可以學習child_process等模塊。

參考資料

[1]

若川: https://lxchuan12.gitee.io

[2]

本文倉庫地址: https://github.com/lxchuan12/open-in-editor.git


其他引用略,具體可以點擊閱讀原文查看。


最近組建了一個江西人的前端交流群,如果你也是江西人可以加我微信 ruochuan12 拉你進群。


·················?若川出品?·················

今日話題

五一結束啦,我在假期最后一天耗時一天把這篇文章寫完,這是今年第一篇技術文,慚愧慚愧。接下來會發布第二篇《學習 Vuex 4 源碼整體架構,深入理解其原理及provide/inject原理》。歡迎在下方留言~? 歡迎分享、收藏、點贊、在看我的公眾號文章~

一個愿景是幫助5年內前端人走向前列的公眾號

可加我個人微信?ruochuan12,長期交流學習

推薦閱讀

我在阿里招前端,我該怎么幫你?(現在還能加我進模擬面試群)

若川知乎問答:2年前端經驗,做的項目沒什么技術含量,怎么辦?

點擊方卡片關注我、加個星標,或者查看源碼等系列文章。
學習源碼整體架構系列、年度總結、JS基礎系列

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/275931.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275931.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275931.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

:傳遞給 left 或 substring 函數的長度參數無效。_Java函數式編碼結構-好程序員

好程序員Java培訓分享Java函數式編碼結構,本文將探討三種下一代JVM語言:Groovy、Scala和Clojure,比較并對比新的功能和范例,讓Java開發人員對自己近期的未來發展有大體的認識,下面我們一起來看一下吧。當垃圾回收成為主…

系統架構師學習筆記_第十一章(上)_連載

第十一章 信息安全技術 11.1 信息安全關鍵技術 11.1.1 加密和解密 有意的計算機犯罪 和 無意的數據破壞 被動攻擊:非法地從傳輸信道上截取信息,或從存儲載體上 偷竊、復制 信息。 主動攻擊:對傳輸或存儲的數據進行 惡意的刪除、篡改 等。 …

跨庫一致性_設計跨平臺的一致性

跨庫一致性I offended an Apple employee the other day when I was checking out the new iPad Pro and I told him that I was an Android phone user. Eyes rolled, jokes were made, and we agreed to disagree.前幾天,我在檢閱新iPad Pro時冒犯了一名蘋果員工&…

React-生命周期雜記

前言 自從React發布Fiber之后,更新速度日新月異,而生命周期也隨之改變,雖然原有的一些生命周期函數面臨廢棄,但理解其背后更新的機制也是一種學習 在這里根據官方文檔以及社區上其他優秀的文章進行一個對于生命周期的總結&#xf…

漫畫 | 一個NB互聯網項目的上線過程…

大家好,我是若川(點這里加我微信 ruochuan12,長期交流學習)。今天雖然是周六,但還是要上班,所以就推薦一篇比較輕松的漫畫。點擊下方卡片關注我、加個星標,或者查看源碼等系列文章。學習源碼整體…

stm32 中斷處理級別_STM32中斷優先級徹底講解

文章來源:http://blog.sina.com.cn/s/blog_4fed55ce0100j7nd.html一:綜述STM32 目前支持的中斷共為 84 個(16 個內核68 個外部), 16 級可編程中斷優先級的設置(僅使用中斷優先級設置 8bit 中的高 4 位)和16個搶占優先級(因為搶占優先級最多可…

胖子臉:庫珀·布萊克100年

In 16th century Europe, roman typefaces were the first to surpass blackletter as the preferred choice for expressing emphasis in print. True bold weight roman letters didn’t appear until the 19th century, which critics quickly coined “Fat Faces” due to …

C語言中的布爾值

C語言的布爾類型在C語言標準(C89)沒有定義布爾類型,所以C語言判斷真假時以0為假,非0為真。所以我們通常使用邏輯變量的做法: //定義一個int類型變量,當變量值為0時表示false,值為1時表示trueint flag;flag 0;//......…

用委托實現窗體間傳值

1.新建一個工程.在Form1中添加一個Label和一個Button.新建一個事件類,讓它有一個string 類型的屬性,用于傳值. 1 ///ReturnValueEventArgs.cs 2 using System; 3 using System.Collections.Generic; 4 using System.Text; 5 6 namespace test 7 { 8 public class Return…

c++ explicit關鍵字_聊一聊 C++的特性 explicit 匿名空間

聊一聊 C的特性 explicit && 匿名空間explicit關鍵字首先看一下explicit的作用:explicit 是避免構造函數的參數自動轉換為類對象的標識符,平時代碼中并不是經常用到,但是,有時候就是因為這個,會造成一定的BUG出…

谷歌瀏覽器那些有趣的隱藏功能

大家好,我是若川(點這里加我微信 ruochuan12,長期交流學習)。今天推薦一篇實用文章。文末有抽獎。點擊下方卡片關注我、加個星標,或者查看源碼等系列文章。學習源碼整體架構系列、年度總結、JS基礎系列很多小伙伴說還是…

AppDelegate的模塊化+瘦身

前言 關于iOS的模塊化,要追溯到16年接觸的BeeHive了,BeeHive將功能模塊化,以module的形式進行構建,以performSelector:的形式進行module的事件響應,以protocol的形式進行module間的通信。可以說思路非常清晰…

yii mysql_Yii2框架操作數據庫的方法分析【以mysql為例】

本文實例講述了Yii2框架操作數據庫的方法。分享給大家供大家參考,具體如下:準備數據庫DROP TABLE IF EXISTS pre_user;CREATE TABLE pre_user(id int(11) AUTO_INCREMENT PRIMARY KEY,username varchar(255) NOT NULL,password varchar(32) NOT NULL DEF…

C++接口注意

1. 用Record接口,要注意 Packed的區別 2. cdecl和stdcall的區別 3. C導出的函數建議用C格式stdcall導出,使用Def文件定義名稱 4. 用VS寫的API dll要注意是否引用了MFC的DLL,否則會使LoadLibrary失敗,并GetLastError后返回14001 Ap…

Vue 3.1.0 的 beta 版發布

大家好,我是若川(點這里加我微信 ruochuan12,長期交流學習)。昨晚尤大視頻號直播說到vue 3.1.0 beta版發布了,今天分享這篇文章。也有小伙伴可能注意到了昨晚我一直在送禮物。點擊下方卡片關注我、加個星標&#xff0c…

設計模式練習_設計練習是邪惡的

設計模式練習It was the final round of interviews. Or, so the candidate thought.這是采訪的最后一輪。 或者,所以候選人認為。 She’d spent all day interviewing in our office. As the final interviewer, I walked her out the building. She seemed confi…

morningcat2018 LearningDocs

2019獨角獸企業重金招聘Python工程師標準>>> LearningDocs 學習資料與文檔 JCP(Java Community Process ,Java社區進程 ) https://www.jcp.org/en/home/index JSR(Java Specification Requests,Java規范請求…

firefox下可惡的value

前幾天做項目 遇到這樣一個情況 document.getElementById("txtTest").value "111"; 這條語句在ff下和ie下都是好用的 但是用開發工具看html代碼 ie下顯示正常 ff下顯示的卻是修改之前的(實際上已經修改了,只是html沒有修改過來) 用js修改input…

據說 99% 的人不知道 vue-devtools 還能直接打開對應組件文件?本文原理揭秘

1. 前言你好,我是若川[1],微信搜索「若川視野」關注我,專注前端技術分享,一個愿景是幫助5年內前端開闊視野走向前列的公眾號。歡迎加我微信ruochuan12,長期交流學習。這是學習源碼整體架構系列 之 launch-editor 源碼&…

mysql 存儲 事務_MYSQL 可以在存儲過程里實現事務控制嗎

展開全部6.7 MySQL 事務與鎖定命令6.7.1 BEGIN/COMMIT/ROLLBACK 句法缺省的,MySQL 運行在 autocommit 模式。這就意味著,當你執行完一e69da5e887aa62616964757a686964616f31333361326265個更新時,MySQL 將立刻將更新存儲到磁盤上。如果你使用…