00、前端搬磚框架
開發 ⇨ 構建 ⇨ 部署上線 ⇨ 摸魚:
01、Node.js/npm
Node.JS 是一個基於 Chrome V8 引擎 的 JavaScript 執行時環境,不是JS庫(是C++開發的),是用來解釋執行JavaScript 程式碼的。我們開發Web應用中的JavaScript 程式碼都是執行在瀏覽器上,有了Node.JS,就可以用JavaScript 來開發中介軟體、後端服務了。
我們在VSCode中用到的很多元件都是基於Node.JS來開發執行的,如構建工具webpack、vue-cli。
1.1、什麼是npm?
npm(Node Package Manager)為Node.JS的包管理器,用來管理JS元件模組的,包括安裝、解除安裝、管理依賴等。很多語言都有自己的包管理器,如Java
的maven
、.Net
的Nuget
等。
npm倉庫(registry):官方的 npm倉庫 存放了大量的、幾乎所有的 JS元件(輪子)。在這裡,你會發現你不是一個人在戰鬥!大家開源的各種前端元件庫都是釋出到這個集中式的大倉庫裡,使用npm工具就可以從倉庫裡學習(copy)、安裝使用各種元件了。
1.2、什麼是yarn/pnpm?
yarn、pnpm的作用同npm一樣,都是包管理工具,使用方式都比較相似。
- npm:這是Node.js官方自帶的包管理工具,
- yarn:由於早期npm存在一些不完善的問題,於是一些大公司推出了yarn。
- npm完善:受yarn的反向推動,後來npm逐步升級完善。
- pnpm:一個比較新包管理工具,相比npm、yarn,有更好的下載速度、磁碟管理、依賴管理。
1.3、npm命令/配置
NodeJS官網 下載安裝包,安裝Node.JS的時候就自帶npm了,可以直接使用。npm是一個命令列工具,指令都是在cmd命令列工具中執行的,常用指令如下:
常用指令 | 說明 |
---|---|
node -v | 檢視nodeJS版本,也用來驗證node是否安裝 |
node | 進入node命令環境,可執行任何JavaScript程式碼了 |
console.log('hello world') | 在node環境中執行JS程式碼 |
npm -v | 檢視npm版本 |
npm install -g <包名稱@版本號> | 安裝一個模組,@可指定版本號,-g 表示全域性安裝。npm install -g vuex@3 |
npm uninstall <包名稱> | 解除安裝一個模組 |
npm update <包名稱> | 更新模組 |
npm list -g | 檢視所有全域性安裝的模組 |
npm list <包名稱> | 檢視模組的版本資訊,npm list vuex |
npm init | npm初始化,會生成一個 package.json 檔案 |
npm install | 自動安裝 package.json 檔案中的模組 |
npm install -save <包名稱> | 在package 檔案的dependencies 寫入依賴,用於生產環境。簡寫 npm i -S |
npm install -save-dev <包名稱> | 在package 檔案的devDependencies 寫入依賴,開發環境。簡寫:npm i -D |
npm cache clean -f | 清除快取 |
?配置本地的包儲存目錄:新建npm包的資料夾用於存放包的資源。
- 全域性npm包儲存路徑
node_global
:npm config set prefix "D:\Project_Files\npm\node_global"
- npm包的快取路徑
node_cache
:npm config set cache "D:\Project_Files\npm\node_cache"
?環境配置:修改環境變數:系統屬性 ➤ 環境變數。重啟一下VSCode、命令列工具才生效。
- ❶ 新增一個系統變數:系統變數 ➤ 新建:變數名=
NODE_PATH
,變數值= 上面準備好的全域性npm
包的路徑下的模組路徑D:\Project_Files\npm\node_global\node_modules
。 - ❷ 新增Path路徑:開啟系統變數列表中的
Path
變數,新建一個值=全域性npm路徑D:\Project_Files\npm\node_global
到這裡就完成了基礎配置了,可以透過命令安裝元件了。
?npm倉庫映象:預設的npm倉庫在國外,下載可能不穩定、比較慢,可以改為國內的淘寶映象(每10分鐘更新一次)。
- 檢視包的倉庫地址:
npm config get registry
- 設定倉庫地址為淘寶映象:
npm config set registry https://registry.npmmirror.com/
- 或者安裝
cnmp
外掛:npm install -g cnpm --registry=https://registry.npmmirror.com
?在VSCode中使用:
設定
>> Terminal › Integrated › Default Profile: Windows
的選項值為一個命令列工具,推薦“Git Bash”,重啟VS!就可以VSCode中的終端使用npm指令了。
1.4、package.json
每個專案都有一個 package.json 檔案,內容是一個json物件。用於定義專案依賴的各種模組,及專案配置資訊、模組的配置資訊。命令 npm init -y
可建立一個初始package.json檔案。
{
"name": "vuep3", //*專案/模組名稱
"version": "0.1.0", //*專案版本,格式為:「主版本號. 次版本號. 修訂號」
"private": true, //是否私有
"scripts": { //npm 指令碼命令,透過 npm run 執行命令
"serve": "vue-cli-service serve", //啟動vue-cli-server服務
"build": "vue-cli-service build", //編譯
"test:unit": "vue-cli-service test:unit", //執行單元測試
"lint": "vue-cli-service lint" //執行程式碼檢查?
},
"dependencies": { //生產環境專案依賴,透過"npm install -save <包名稱>"安裝元件,或"npm i -S"
"core-js": "^3.8.3", //key為模組名,value為模組版本號
"vue": "^2.6.14" //
},
"devDependencies": { //開發環境專案依賴,開發、編譯中使用,不會輸出到生產環境,安裝指令:npm i -D
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/eslint-config-airbnb": "^6.0.0",
"eslint": "^7.32.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-vue": "^8.0.3",
"eslint-plugin-vuejs-accessibility": "^1.1.0",
"vue-template-compiler": "^2.6.14"
},
"eslintConfig": { //檢查檔案配置
"root": true,
"env": {"node": true},
"extends": [ "plugin:vue/essential", "@vue/airbnb" ],
"parserOptions": {"parser": "@babel/eslint-parser" },
"rules": {}
},
"browserslist": [ //專案需要相容的瀏覽器配置,處理js、css相容性是會用到
"> 1%",
"last 2 versions",
"not dead"
]
}
?package.json檔案中版本號的說明,版本號格式:「主版本號. 次版本號. 修訂號」
。
~
:匹配最新的修改的版本號,"~1.2.3
" 匹配1.2.x
中最新的版本。^
:匹配最新的此版本+修訂版本號,^1.2.3
會匹配1.x.x
中最新的版本。*
:匹配最新的x.x.x
版本。
02、babel/polyfill 為何物?
babel 是用來編譯JavaScript程式碼的,解決JavaScript相容性問題的。
2.1、什麼是polyfill?
polyfill 意為 膩子 /墊片,目的是解決JavaScript程式碼的相容性問題,解決方式就是用瀏覽器支援的方式模擬實現一遍。如ES2015+ 的很多不錯的特性在一些古老的瀏覽器下存在相容性問題,如非同步promise
、map、新API方法等。於是就有了替代方案,如下示例程式碼,判斷如果不支援promise
則模擬實現一個,這就稱之為 polyfill
(polyfill/ˈpɒli fɪl/ 膩子指令碼)。
window.Promise = (function(window){
if(window.Promise){
return window.Promise
}else{
window.Promise = function(){ } // 相容程式碼,模擬實現
}
})(window)
於是各種各樣的polyfill
就出現了,為了統一規範和管理,於是出現了 babel
!
2.2、什麼是babel?
babel 是一個針對ECMScript語言相容性處理的工具鏈,(babel /ˈbeɪbl/ 巴別塔,一座通往天堂的高塔,來自聖經的故事),將ES2015+的程式碼轉譯為向後相容的JavaScript程式碼。其核心功能就是轉譯程式碼,轉譯過程簡單來說,先對JS程式碼進行詞法、語法分析抽象為語法樹,然後對語法樹進行變換和程式碼生成。第二步就有很多babel的工具鏈外掛參與了,用於不同型別程式碼的轉換生成。
❓babel能幹什麼?
- 語法轉換,如let、const、箭頭函式等新的語法。
polyfill
程式碼,如非同步promise
、map、新API方法等。需引入外掛,如@babel/polyfill
,由於存在全域性汙染+重複程式碼問題,被廢棄;@babel/plugin-transform-runtime
代替- 其他程式碼轉換,如TypeScript、JSX。
❓大量的冗餘程式碼怎麼辦?
使用babel,可以在程式碼編譯的時候就解決所有的JS相容性問題。但問題是冗餘JS程式碼會比較多,有些客戶的瀏覽器比較先進,並不需要polyfill
(或只需要少量即可),也要載入這麼多JS。於是有兩個解決方法:
- 靜態按需引入:在編譯時指定需要相容的瀏覽器及版本,按需引入
polyfill
,如@babel/preset-env
外掛,useBuiltIns
引數設定需相容的瀏覽器。 - 動態按需引入:把
polyfill
程式碼放到伺服器上,客戶端動態的判斷瀏覽器的情況再請求polyfill
程式碼,如@polyfill.io
方案。
❓怎麼使用?簡單瞭解下
- 安裝babel核心庫,@babel/core
- 安裝外掛babel的工具鏈外掛/預設(preset預設的外掛集合)
- 透過
@babel/cli
指令,或者webpack、vue-cli來執行babel
編譯轉換。
2.3、Vue-cli中的babel
vue-cli中使用了@vue/babel-preset-app
預設,包含了babel-preset-env、JSX 支援以及為最小化包體積最佳化過的配置,可以透過 babel.config.js
進行配置。
03、webpack速覽
vue-cli
是建立在webpack基礎之上的,簡化了繁瑣的webpack配置和使用,先初步瞭解下webpack基本原理和流程。
3.1、webpack是幹什麼的?
webpack 是一個強大的前端構建工具,也是基於Node.js開發和執行,作用就是把開發態的各種程式碼編譯(構建、打包)為瀏覽器可(更好)執行的程式碼。webpack配置靈活,包含豐富的擴充套件外掛,webpack的各項能力也都是透過這些外掛來完成的。
✔️核心作用:提高開發效率!
- ✅程式碼編譯:提高寫Bug效率,可以愉快的利用模組化、現代的ES6語法,及高階的CSS。
- CSS程式碼編譯:less、sass的轉換,CSS相容性補全等。
- JS程式碼編譯:ES6語法的相容性轉,利用
babel/polyfill
相關外掛 - 程式碼校驗:對CSS、JS程式碼的規範性校驗檢查,
ESLint
外掛 - 熱更新:開發態修改程式碼動態更新頁面,實時預覽,方便開發除錯。
- ✅程式碼最佳化:
- 模組依賴,處理各種第三方元件的依賴,避免重複載入、衝突。
- 程式碼模組打包:程式碼合併、壓縮,減少體積、網路請求次數。
- 程式碼混淆:提高程式碼安全性。
- 資源最佳化,不限於JS、CSS,支援處理各種資源,如小圖最佳化內嵌到程式碼中。
? 在webpack中,每個檔案都是模組,webpack 按照一定規則來載入、編譯這些模組。
?webpack 核心概念:
- ?entry 入口 : 從哪裡開始?從一個根檔案入口,如“
./src/main.js
”。 - ?output 出口 : 到哪裡去?檔案編譯輸出位置,如“
./dist
”。 - ?loader 載入器 : 對原始碼進行轉換,不同型別模組(檔案)採用不同的載入器來編譯轉換。
- css程式碼:css-loader、less-loader、sass-loader、postcss-loader ... 。
- 圖片資源:url-loader、file-loader ... 。
- HTML:html-minify-loader 壓縮。
- Javscript:
babel-loader
轉換ES6檔案到ES5,babel是webpack內建的JS編譯器元件。 - ...等等。
- ?plugin 外掛 : 處理載入器完成不了的功能,透過webpack暴露的API和生命週期鉤子來執行各種處理,所以外掛可以在打包的不同階段參與。
- 打包輸出檔案處理:拆分chunk以控制輸出的檔案,如提取css到一個單獨檔案。
vue
中複製public
到輸出目錄的copy-webpack-plugin
。- 每次打包前清空
dist
目錄的clean-webpack-plugin
。
3.2、構建流程
webpack的構建是一個序列過程,這個過程就是把各個外掛(loader、plugin)串聯起來執行。✏️畫圖圖吧,大概這樣子的:
① 初始化?
- 讀取並組裝配置資訊進行初始化,配置資訊來源包括配置檔案、
cli
引數、預設配置。 - 初始化外掛、配置外掛的引數。
② 編譯?
- 從
entry
入口檔案開始(vue中入口檔案預設為“./src/main.js
”),遞迴找到所有的依賴模組,呼叫相應的loader
編譯處理檔案內容。 - 產生chunk:chunk(/tʃʌŋk/ 塊)是webpack構建過程中的塊,一個chunk包括等多個模組,為某個入口檔案找到的所有依賴模組。然後webpack根據配置為chunk 生成資源列表(chunk assets),最終輸出到檔案。
③ 輸出?
根據配置確定輸出的路徑、檔名,輸出到檔案系統。
3.3、安裝使用
npm安裝webpack
、webpack-cli
兩個元件。
//1.全域性環境安裝webpack
npm install webpack -g
//2.進入專案目錄
npm init -y //初始化npm,-y忽略詢問
npm install webpack webpack-cli --save-dev //安裝webpack、webpack-cli 到開發環境
webpack.config.js檔案簡介:
var path = require('path');
module.exports = {
//模式 開發模式打包的是未壓縮檔案
mode:"development",
// 入口檔案,是模組構建的起點,同時每一個入口檔案對應最後生成的一個 chunk。
entry: './src/main.js',
// 生成檔案,是模組構建的終點,包括輸出檔案與輸出路徑。
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
// 這裡配置了處理各模組的 loader ,包括 css 預處理 loader ,es6 編譯 loader,圖片處理 loader。
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: { presets: ['@babel/preset-env'] }
}
}
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' }
]},
// webpack 各外掛物件,在 webpack 的事件流中執行對應的方法。
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
package.json中新增構建指令,就可以執行了:npm run build
來編譯程式碼了。
"scripts": {
"build":"webpack"
},
04、express搭建簡易伺服器
express 是一個基於Node.js 的元件,用於搭建一個WEB伺服器,使用非常簡便、靈活,(express /ɪkˈspres/ 快速、快遞)。有必要了解一下,就可以自己開發服務端API了。
express 是 Node.js 官方推薦的Web開發框架,使用廣泛,除了核心http服務,還有很多功能。如靜態資源服務、模板解析(可用於服務端渲染)、豐富的外掛支援等。如果要建立一個完整的後端專案,可以藉助express
的腳手架元件搭建一個更完整的web框架。
①、準備環境:先建立一個專案資料夾 server-express
//1、建立一個專案資料夾 server-express
//2、進入專案目錄
cd ../server-express
//3、初始化npm
npm init -f
//4、安裝express
npm install express -D
②、編寫服務端程式:建立一個index.js
//引入express模組,注意該程式碼是要基於Node.js執行,需要用Node的模組寫法
let express = require('express');
let path = require('path');
//建立express例項
let server = new express();
//設定靜態資源訪問,就可以直接訪問./static 目錄的靜態資源了
server.use('/static',express.static(path.resolve(__dirname, './static')));
//啟用json解析支援,用於解析body的json資料
server.use(express.json());
//新增監聽埠
server.listen(3000, err => {
if (!err)
console.log('伺服器端啟動成功!地址:http://localhost:3000');
})
//配置API路由:get
server.get('/user/:userId', (req, res) => {
//req.params 獲取路由動態引數,req.query獲取url上的get引數,同vue-router
console.log(req.params, req.query);
//返回響應資料
res.json({ id: req.params.userId, name: 'sam', age: 30 });
})
//配置API路由:post
server.post('/user/add', (req, res) => {
//req.body 獲取post資料
console.log(req.body);
//返回響應資料
res.send({ status: 'OK', message: "更新成功" });
})
③、執行:node index.js
//啟動服務端
$ node index.js
伺服器端啟動成功!地址:http://localhost:3000
//測試
http://localhost:3000/static/img01.jpg
http://localhost:3000/user/100?type=vip
http://localhost:3000/user/add // post: {"name": "張三", "age": 40}
#參考資料
©️版權申明:版權所有@安木夕,本文內容僅供學習,歡迎指正、交流,轉載請註明出處!原文編輯地址-語雀