面試官:說說你對作用域鏈和閉包的理解?
自己先想一分鐘。
關於上面的面試題,阮一峰大大寫過一篇很棒的文章,你可以狠狠的戳這裡檢視,希望你看完有所收穫!
寫在前面
2019年關鍵詞:盤它! 新年第一篇文章,希望是一個好的開篇吧。
為啥要學?
人為啥要讀書呢?我覺得讀別人的原始碼才是精華所在。學習別人專案建設、構建、開發、部署中的一些思路,吸取精華然後為我所用。
如何去學?
剝洋蔥法一層一層,由外而內,循序漸進去學習 Element 原始碼帶給我的樂趣。我打算這樣來安排學習程式:
- 首先先搞清楚它的專案結構
- 接下來就是粗略瞭解下
package.json
中每個構建命令的作用 - 然後逐一的去拆分,解讀每個命令列對應的檔案的程式碼邏輯(關鍵一步)
- 最後是拜讀每個元件的實現原理(重要一步,我知道很漫長,Hold on!)
- 造輪子唄(經歷過以上四步,才會去做!)
為何選擇 Element ?
現如今比較流行的 Vue 前端元件庫,加之我在專案當中用的也是它,故選之。
你應該瞭解的
- ES6+
- node &
npm &
package.json - Rollup
- Webpack
- Scss
- Vue
- Typescript
你將會知道
- Element 的專案結構
- package.json 中每個構建命令的作用
一點補充
- 本次原始碼學習參考的是 Element 的
dev
分支 - 文章中的程式碼大部分都用註釋標註了,方便以後複習
- 文筆和知識有限,文章中有錯別字或理解有誤的地方,歡迎各位留言斧正!
- 堅持就是勝利,我會持續更新哦…
瞭解 Element 的專案結構
你可以把 Element 的原始碼 clone 到本地,也可以安裝方便線上檢視 GitHub 倉庫程式碼的 Chrome 擴充套件,總之我們首先要做的事情就是先把 Element 原始碼的目錄結構都弄清楚:瞭解每個檔案的作用是什麼,Element 是如何規劃目錄的等等。
詳細目錄介紹如下:
element├── build # 存放所有的打包,自動化生成、構建、部署工具├── examples # 專案示例,官網頁面等├── packages # 所有的元件及主題檔案├── src # 原始碼│ ├── directives # 指令│ ├── locale # 國際化│ ├── mixins # 混合│ ├── transitions # 內建過度動畫元件│ ├── utils # 工具│ └── index.js # 入口檔案。這個檔案是自動生成的├── test # 存放測試檔案├── types # .ts 檔案,為元件定義一些資料型別規範├── .babelrc # babel 配置檔案├── .eslintignore # eslint 校驗忽略├── .eslintrc # eslint 配置檔案├── .gitattributes # github 自動識別專案屬於哪種語言├── .gitignore # git 提交忽略├── .travis.yml # 線上構建配置├── CHANGElOG.*.MD # 更新日誌├── FAQ.MD # 一些開發中的常見問題彙總及解決方法├── LICENSE # 專案版權宣告├── Makefile # Make 配置檔案。用來自動化部署專案├── README.md # 專案介紹├── components.json # 元件及入口檔案。為了後續自動化處理├── element_logo.svg├── package.json # 專案依賴及配置├── postcss.config.js # Css 預處理配置└── yarn.lock # yarn 模組安裝工具生成的版本鎖檔案複製程式碼
關於上面對目錄和檔案的描述也許你一眼看上去一頭霧水,還是不理解他在幹什麼,沒關係,這是正常的,在你沒有深入到原始碼之前,僅僅憑藉幾句話就理解這個檔案的作用是不可能的,所以不要灰心,只需要有個大概印象混個眼熟就可以了。
構建命令列總覽
弄清楚 Element 各個目錄的作用之後,接下來就是看下 package.json
每個構建命令的作用了。開啟這個檔案,找到 scripts
屬性:
{
"scripts": {
// 安裝專案依賴。有 yarn 就用,無則使用 npm 安裝依賴 "bootstrap": "yarn || npm i", // 檔案相關的構建 // 除了 build-entry.js 其他都是為官網服務的 "build:file": "node build/bin/iconInit.js &
node build/bin/build-entry.js &
node build/bin/i18n.js &
node build/bin/version.js", // 主題檔案相關的構建 "build:theme": "node build/bin/gen-cssfile &
&
gulp build --gulpfile packages/theme-chalk/gulpfile.js &
&
cp-cli packages/theme-chalk/lib lib/theme-chalk", // 工具檔案相關的構建 "build:utils": "cross-env BABEL_ENV=utils babel src --out-dir lib --ignore src/index.js", // 把國際化檔案打包成 umd 格式 "build:umd": "node build/bin/build-locale.js", // 刪除 "clean": "rimraf lib &
&
rimraf packages/*/lib &
&
rimraf test/**/coverage", // 官網構建打包 "deploy:build": "npm run build:file &
&
cross-env NODE_ENV=production webpack --config build/webpack.demo.js &
&
echo element.eleme.io>
>
examples/element-ui/CNAME", // 開發相關構建 "dev": "npm run bootstrap &
&
npm run build:file &
&
cross-env NODE_ENV=development webpack-dev-server --config build/webpack.demo.js &
node build/bin/template.js", // 開發演示 "dev:play": "npm run build:file &
&
cross-env NODE_ENV=development PLAY_ENV=true webpack-dev-server --config build/webpack.demo.js", // 生產構建 "dist": "npm run clean &
&
npm run build:file &
&
npm run lint &
&
webpack --config build/webpack.conf.js &
&
webpack --config build/webpack.common.js &
&
webpack --config build/webpack.component.js &
&
npm run build:utils &
&
npm run build:umd &
&
npm run build:theme", // 國際化 "i18n": "node build/bin/i18n.js", // 校驗 "lint": "eslint src/**/* test/**/* packages/**/* build/**/* --quiet", // 釋出 "pub": "npm run bootstrap &
&
sh build/git-release.sh &
&
sh build/release.sh &
&
node build/bin/gen-indices.js &
&
sh build/deploy-faas.sh", // 測試 "test": "npm run lint &
&
npm run build:theme &
&
cross-env CI_ENV=/dev/ karma start test/unit/karma.conf.js --single-run", // 自動化測試 "test:watch": "npm run build:theme &
&
karma start test/unit/karma.conf.js"
}
}複製程式碼
接下來讓我們從第一個命令開始學習,哦不,讓我們從第二個吧,因為第一個沒啥可說的。