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

1. 前言

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

這是學習源碼整體架構系列 之 launch-editor 源碼(第九篇)。學習源碼整體架構系列文章(有哪些必看的JS庫):jQuery、underscore、lodash、sentry、vuex、axios、koa、redux。

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

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

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

閱讀本文后你將學到:

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

  2. 如何調試學習源碼

  3. launch-editor-middleware、launch-editor 等實現原理

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

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

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

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

open-in-editor

你也許會問,我不用vue,我用react有沒有類似功能啊,有啊,請看react-dev-inspector[3]。你可能還會問,支持哪些編輯器呀,主流的 vscode、webstorm、atom、sublime 等都支持,更多可以看這個列表 Supported editors[4]

本文就是根據學習尤大寫的 launch-editor[5] 源碼,本著知其然,知其所以然的宗旨,探究 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 電腦,VSCode 編輯器,在Ubuntu子系統下使用的終端工具。同時推薦我的文章使用 ohmyzsh 打造 windows、ubuntu、mac 系統高效終端命令行工具,用過的都說好

解決辦法也簡單,就是這句英文的意思

1.3.1 方法一:先確保在終端能用命令打開你使用的編輯器,文中以VSCode為例

如果你的命令行本身就不能運行code等命令打開編輯器,那肯定是報錯的。這時需要把VSCode注入到命令行終端中。注入方法也簡單。我的交流群里有小伙伴提供了mac電腦的截圖。

mac 電腦在 VSCode command + shift + pWindows 則是 ctrl + shift + p。然后輸入shell,選擇安裝code。如下圖:

Install 'code' command in PATH

這樣就能在終端中打開VSCode的了。

如果能在終端打開使用命令編輯器能打開,但實際上還是報錯,那么大概率是沒有識別到你的編輯器。那么可以通過方法二設置指定編輯器。

1.3.2 方法二:具體說明編輯器,在環境變量中說明指定編輯器

vue項目的根目錄下,對應本文則是:vue3-project,添加.env.delelopment文件,其內容是EDITOR=code這里重點說明下,我的 vue-cli 版本是4.5.12,好像在vue-cli 3.5及以上版本才支持自定義EDITOR這樣的環境變量

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

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

也有可能你的編輯器路徑有中文路徑導致報錯,可以在環境變量中添加你的編輯器路徑。

如果你通過以上方法,還沒解決報錯問題。歡迎留言,或者加我微信 ruochuan12 交流。畢竟電腦環境不一,很難保證所有人都能正常執行,但我們知道了其原理,就很容易解決問題

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

2. vue-devtools Open component in editor 文檔

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

vuejs/vue-devtools[6]文檔

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

這篇指南中寫了在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[8] package to setup an HTTP route with the /__open-in-editor path. It will receive file as an URL variable.

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

3. 環境準備工作

熟悉我的讀者,都知道我都是推薦調試看源碼的,正所謂:哪里不會點哪里。而且調試一般都寫得很詳細,是希望能幫助到一部分人知道如何看源碼。于是我特意新建一個倉庫open-in-editor[10] 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中的文件?[11]

這時就搜到了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)

這段的代碼,就是傳遞錯誤回調函數,wrapErrorCallback 返回給一個新的函數,wrapErrorCallback 執行時,再去執行 onErrorCallback(cb)。

我相信讀者朋友能看懂,我單獨拿出來講述,主要是因為這種包裹函數的形式在很多源碼里都很常見

這里也就是文章開頭終端錯誤圖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')
const?childProcess?=?require('child_process')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?{//??代碼有刪減if?(process.platform?===?'darwin')?{const?output?=?childProcess.execSync('ps?x').toString()//?省略}?else?if?(process.platform?===?'win32')?{const?output?=?childProcess.execSync('powershell?-Command?"Get-Process?|?Select-Object?Path"',?{stdio:?['pipe',?'pipe',?'ignore']}).toString()//?省略}?else?if?(process.platform?===?'linux')?{const?output?=?childProcess.execSync('ps?x?--no-heading?-o?comm?--sort=comm').toString()}}?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'?})
}

行文至此,就基本接近尾聲了。原理其實就是利用nodejs中的child_process,執行了類似code path/to/file命令。

7. 總結

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

7.1 一句話簡述其原理

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

code?path/to/file

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

最后還能做什么呢。

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

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

也不要禁錮自己的思維,把前端禁錮在頁面中,應該把視野拓寬

Node.js是我們前端人探索操作文件、操作網絡等的好工具

如果讀者朋友發現有不妥或可改善之處,再或者哪里沒寫明白的地方,歡迎評論指出。另外覺得寫得不錯,對您有些許幫助,可以點贊、評論、轉發分享,也是對我的一種支持,萬分感謝。如果能關注我的前端公眾號:「若川視野」,就更好啦。

參考資料

[1]

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

[2]

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

[3]

更多參考鏈接,可以點擊閱讀原文查看


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


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

今日話題

之前發的閱讀量慘淡,所以現在主要改了標題,還有根據讀者一些反饋修改更新,所以重新編輯發布下原創,爭取投稿到一些大號。歡迎在下方留言~? 歡迎分享、收藏、點贊、在看我的公眾號文章~

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

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

推薦閱讀

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

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

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

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

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

相關文章

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

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

如何忽略證書繼續訪問_前5個最容易被忽視的可訪問性問題

如何忽略證書繼續訪問Accessibility is quickly becoming one of the most important aspects of the way we use the web, if not the most important. Just between 2017 and 2018, the number of federal court cases regarding web accessibility nearly tripled, signifyi…

《認清C++語言》のrandom_shuffle()和transform()算法

1&#xff09;STL中的函數random_shuffle()用來對一個元素序列進行重新排序&#xff08;隨機的&#xff09;&#xff0c;函數原型如下&#xff1a; template<class RandomAccessIterator> void random_shuffle( RandomAccessIterator _First, //指向序列首元素的迭代器 R…

作為前端開發,如何高效學習 TypeScript

大家好&#xff0c;我是若川。有朋友跟我說最近面試前端候選人&#xff0c;問到關于 JavaScript 的一些少見誤區問題&#xff0c;候選人很多都沒回答上來&#xff0c;他很詫異&#xff0c;一個從國際大廠出來的面試者&#xff0c;竟然對 JavaScript 的一些誤區問題都不了解。他…

figma下載_對于這10家公司,Figma是邁向新高度的起點

figma下載Hey everyone! In this post, we are highlighting 10 companies for which the use of Figma has become the starting point on the path to new heights. These are the use cases of problems and their solutions, where Figma played a decisive role.嘿大家&am…

mysql查詢條件為or_使用mysql查詢where條件里的or和and

為什么要著重講這塊內容呢?因為好多小伙伴都會混淆&#xff0c;要不就是不知道怎么組合使用&#xff0c;今天就給大家講這部分內容干貨&#xff0c;讓大家半分鐘看懂。AND、OR運算符的組合使用在WHERE子句中&#xff0c;通過AND、OR運算符可以同時連接多個條件&#xff0c;當然…

sql server(常用)

普通用法 //生成 uuid 并轉為小寫 select LOWER(SUBSTRING(uuid,1,8)-SUBSTRING(uuid,10,4)-SUBSTRING(uuid,15,4)-SUBSTRING(uuid,20,4)-SUBSTRING(uuid,25,12)) from (select cast(NEWID() as varchar(36)) as uuid) s //ea52a7bb-a2aa-44b8-be28-5ebc64defcf9//獲取時分秒…

代碼編寫中會遇到的安全性問題

一、常用的攻擊手段 1&#xff0e;腳本注入 漏洞描述&#xff1a; 腳本注入攻擊在通過瀏覽器使用用戶輸入框插入惡意標記或腳本代碼時發生。 如&#xff1a;某個輸入框允許用戶向數據存儲中插入內容&#xff0c;如果將一段js腳本插入其中&#xff0c;則當其他用戶使用或瀏覽此數…

TypeScript 原來可以這么香?!

先問一個問題&#xff0c;JavaScript有幾種數據類型&#xff1f;number、string、boolean、null、undefined、symbol、bigint、object其中 bigint 是 ES2020 新增的數據類型&#xff0c;而早在 TS3.2 時便成為 TS 的標準&#xff0c;其實還有好多 ES 標準是 TS 率先提出的&…

java8新特性stream深入解析

2019獨角獸企業重金招聘Python工程師標準>>> 繼續java8源碼的發燒熱&#xff0c;越看越是有充實的感覺。 數據時代下的產物 Java順應時代的發展推出的高效處理大量數據能力的api&#xff0c;它專注于對集合對象進行各種非常便利、高效的聚合操作&#xff0c;借助于同…

mysql內連接的自連接_mysql 內連接、外連接、自連接

一)內連接(等值連接)&#xff1a;查詢客戶姓名&#xff0c;訂單編號&#xff0c;訂單價格---------------------------------------------------select c.name,o.isbn,o.pricefrom customers c inner join orders owhere c.id o.customers_id;-------------------------------…

關于ASP.NET MVC

我是否要學習一下ASP.NET MVC呢&#xff1f;因爲從它剛發布的時候就已經初步的學習了一下&#xff0c;可是一直沒有堅持下來。不過心里對于這份惦記&#xff0c;又讓我始終放不下&#xff0c;看來應該抽個時間來系統的學習一下。 就這樣吧&#xff0c;把自己的博客當成微博來使…

版式設計與創意 pdf_戀愛與版式

版式設計與創意 pdfSince its beginnings, Libe?ration has been characterized by a very distinctive use of typeface, to such an extent that Libe? has put its mark on fonts from across different eras, appropriating these in a certain way.小號因斯它的起點&…

移動網站開發——標記語言

移動互聯網被稱為“第五次科技革命”&#xff0c;而隨著iPhone和Android等智能手機的日漸流行和iPad等平板電腦的出現&#xff0c;移動互聯網的潛力和趨勢也愈發顯現&#xff0c;針對移動設備的網站開發越來越受到關注&#xff0c;國內很多公司也開始重視面向所有移動設備的網站…

mysql適配器_MySQL適配器PyMySQL詳解

import pymysqlimport datainfoimport time#獲取參數host datainfo.hostusername datainfo.usernamepassword datainfo.passworddatabase datainfo.dbprint()#測試數據庫連接def testconnect():#打開數據庫鏈接db pymysql.connect(host,username,password,database)#使用c…

獲取當前Tomcat實例的端口

有時需要在當前代碼中獲取當前Server實例的端口號, 通過HttpServletRequest請求可以, 但有時也需要在沒有請求的情況下獲取到端口號. 用以下方法是可以獲取到的: public int getHttpPort() {try {MBeanServer server;if (MBeanServerFactory.findMBeanServer(null).size() >…

前端技術未來三年前瞻性思考

大家好&#xff0c;我是若川。今天推薦云謙大佬的一篇好文章&#xff0c;值得收藏。點擊下方卡片關注我、加個星標&#xff0c;或者查看源碼等系列文章。學習源碼整體架構系列、年度總結、JS基礎系列習慣從業務場景、用戶體驗、研發速度、維護成本四個維度來看框架等前端技術&a…

微信臨時素材接口_在接口中表達臨時性

微信臨時素材接口When interacting with today’s graphic user interfaces (GUI), we experience a sense of realism. As of now, certain aspects of realism (for example animations) create the appearance that user interface graphics behave in accordance with the …

程序員,當你寫程序寫累了怎么辦。

記得泡泡網的CEO李想說過這樣一句話&#xff0c;大體就是&#xff1a;做一件事情&#xff0c;一開始是興趣使然&#xff0c;然而當三分鐘熱度過去之后&#xff0c;就要靠毅力支撐自己來完成它。至少我到現在是能非常深刻的體會這句話。一開始再怎么喜歡做一件事&#xff0c;要想…

mysql 導致iis 假死_解決IIS無響應假死狀態

1 查看服務器iis的w3wp.exe對應的應用程序池在IIS6下&#xff0c;經常出現w3wp的內存占用不能及時釋放&#xff0c;從而導致服務器響應速度很慢。今天研究了一下&#xff0c;可以做以下配置&#xff1a;1、在IIS中對每個網站進行單獨的應用程序池配置。即互相之間不影響。2、設…