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}
#參考資料
©️版權申明:版權所有@安木夕,本文內容僅供學習,歡迎指正、交流,轉載請註明出處!原文編輯地址-語雀