從開發(fā)一款基于Vue技術棧的全棧熱重載生產環(huán)境腳手架,我學到了什么
瀏覽文章前
這一期,我分享給大家三點看源碼的小技巧,這也是從別的大佬那總結的。
被反復使用的代碼
這樣的代碼是一個軟件的重點函數(shù),一個大神的寫法有很多精華值得學習。
穿越時間的代碼
如果一段代碼10年甚至15年,都還在使用。說明它的設計思想一定很棒。
好調試的代碼
一個程序的代碼很容易就調試成功,說明作者的項目結構能力很強,值得學習。
前言
今天,我們來搞一個新東西,名字叫基于Vue技術棧的全棧熱重載生產環(huán)境腳手架。實話說,這個名字我想了很久。最終,還是以這個名字作為文章標題。我先拆分解釋下:全棧的意思是支持前后端;熱重載這個名詞相信大家很熟悉,就是頁面每次改動,不需要手動去刷新,可自動刷新;生產環(huán)境這里你可以理解成線上環(huán)境,用戶使用的環(huán)境。
緣起
為什么會想到開發(fā)這樣的一款項目呢?我們平時可能更多地使用VueCLI或者Vite來開發(fā)Vue項目,但是如果就單純開發(fā)一個簡單的網頁,未免有點小題大作了。
這時,我們可能會用到Vue的生產環(huán)境版本。但是,這樣的話我們就不能用VueCLI、Vite那樣的熱重載功能,就需要不停的刷新網頁。如果在編輯器中對html文件增加或刪除了元素,或者是在css文件中修改了某個元素的某個樣式,然后想在瀏覽器中看到效果,通常的步驟是:把窗口切換到瀏覽器,然后按鍵盤上的F5刷新頁面。在制作頁面的時候這個動作可能會重復很多次。我們開發(fā)效率就大大地減少了。
所以,我們有必要開發(fā)一款可熱重載的生產環(huán)境腳手架。如果增加模擬數(shù)據接口服務,那就更完美了。光說不練假把式,我們就開發(fā)一款基于Vue技術棧的全棧熱重載生產環(huán)境腳手架。
實戰(zhàn)
一、初始化項目
首先,我們建一個空文件夾,名字可以叫gulp-vue-cli,這就是項目根文件夾。相信聰明的小伙伴可以看出,我們今天的主角是gulp。建完項目根文件夾之后,我們會使用命令快速生成package.json文件。
npm init -y
二、創(chuàng)建前端項目與后端項目
下一步,我們會在創(chuàng)建好的項目根文件夾內創(chuàng)建一個前端項目文件夾,名字可以叫src。另外,后端項目文件夾名字叫server。
下一步,我們先在src文件夾下創(chuàng)建一個前端項目,以下為目錄詳情:
css ---存放樣式目錄
js ---存放邏輯文件目錄
imgs ---存放圖片目錄
index.html ---項目主頁面
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Simple Vue</title>
<link rel="icon" href="/imgs/favicon.ico" />
<link rel="stylesheet" href="/css/index.css" />
</head>
<body>
<div id="app">
<img src="/imgs/logo.png" alt="" />
<p class="mes">{{ message }}</p>
<p class="author">{{txt}}</p>
<p class="status">{{status}}</p>
<button @click="sendData">send</button>
<p>{{resTxt}}</p>
</div>
</body>
<script src="/js/vue.js"></script>
<script type="module">
import {addTxt} from './js/utils.js';
const app = new Vue({
el: "#app",
data: {
message: "Hello Simple Vue!",
resTxt:"",
status:"",
txt:addTxt()
},
methods: {
sendData() {
fetch("http://localhost:3000/send/", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: `username=maomincoding&url=https://www.maomin.club`,
})
.then((response) => response.json())
.then((response) => {
this.resTxt = response;
})
.catch((err) => {
console.error(err);
});
},
},
mounted() {
fetch("http://localhost:3000/mes/", {
method: "GET",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
.then((response) => response.json())
.then((response) => {
this.status = response;
})
.catch((err) => {
console.error(err);
});
},
});
</script>
</html>
這個頁面很簡單,主要使用Vue.js渲染文本以及調用接口后渲染文本。調用接口的方法我們這里使用fetch方法,使用詳情大家可以到MDN網址查看:
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API
建立完前端項目了,我們下一步就開始建立后端項目,我們這里使用的是Node.js技術棧。server文件夾下只有一個主文件app.js。
app.js
const express = require('express');
const bodyParser = require('body-parser')
const app = express();
app.use(express.static("./src"));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// 跨域
app.all('*', function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1');
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
//自定義接口
app.get("/mes", function (request, response) {
response.send({
status:"success",
mes:"渲染頁面成功!"
});
})
app.post("/send",function(request,response){
response.send(request.body); // echo the result back
})
app.listen(3000, function () {
console.log("服務器運行中");
});
這里,我們也簡單地介紹一下里面涉及的知識點。express相信接觸Node的伙伴們一定知道。Express 是一個保持最小規(guī)模的靈活的Node.js,Web 應用程序開發(fā)框架,為 Web 和移動應用程序提供一組強大的功能。這里,我們主要使用它創(chuàng)建幾個API接口,供前臺調用。body-parser是在處理程序之前在中間件中解析傳入的請求體,可以在request.body中獲取從前臺傳來的數(shù)據。
在此之前,你需要安裝以下兩個依賴:
npm install express
npm install body-parser -D
三、開發(fā)前后端熱重載功能
前后端項目我們已經建立完成,下面我們將把重點放到如何開發(fā)熱重載功能上。
我會先在項目根目錄下創(chuàng)建一個gulpfile.js文件。然后,我會列出我們需要了解的知識點有哪些。
gulp
browser-sync
gulp-nodemon
gulp
gulp是基于Node.js的前端自動化構建工具,能自動化地完成 JavaScript/sass/html/image/css 等文件的的測試、檢查、合并、壓縮混淆、格式化、瀏覽器自動刷新、部署文件生成等操作,同時可以對文件進行監(jiān)聽,如果文件有改動,可以自動處理生成新的文件。所以gulp解決了開發(fā)效率(修改代碼后自動更新頁面)、資源整合(代碼的壓縮合并)、代碼質量(代碼的檢查 自動化測試)、代碼轉換(es6–>es5)等問題
這里,我們需要知道gulp是怎樣創(chuàng)建任務的。
const gulp = require('gulp');
// 創(chuàng)建任務
// 第一個參數(shù): 任務名
// 第二個參數(shù): 回調函數(shù),當我們執(zhí)行任務時就會執(zhí)行這個函數(shù)
gulp.task('test', function(){
console.log('test');
})
//執(zhí)行任務: gulp 任務名
gulp test
browser-sync
這里,我們可以重點介紹下它,它就是我們今天要找的主角。
在找它之前,我也找到其他可以實現(xiàn)自動刷新瀏覽器的插件,如:LiveReload,它也可以自動刷新頁面,實時預覽html效果。但是,我為什么沒用LiveReload呢?最痛心的一點是你需要在瀏覽器上安裝LiveReload插件,另外在本地你也得安裝一個LiveReload軟件。如果你是用的是VScode編輯器,需要在插件中心安裝LiveReload插件。默認情況下,瀏覽器和編輯器并不會自動為你激活LiveReload的功能,你需要手動配置一些東西。所以這么麻煩,干脆看看還有沒有別的解決方案。
最終,我找到了它——browser-sync,以下是官方對它的解釋:
Browsersync能讓瀏覽器實時、快速響應您的文件更改(html、js、css、sass、less等)并自動刷新頁面。更重要的是 Browsersync可以同時在PC、平板、手機等設備下進項調試。您可以想象一下:“假設您的桌子上有pc、ipad、iphone、android等設備,同時打開了您需要調試的頁面,當您使用browsersync后,您的任何一次代碼保存,以上的設備都會同時顯示您的改動”。無論您是前端還是后端工程師,使用它將提高您30%的工作效率。
當然,學習它之前,你需要注意browser-sync是基于Node.js的, 是一個Node模塊, 如果您想要快速使用它,也許您需要先安裝一下Node.js。
然后,你可以全局安裝它。
npm install -g browser-sync
也可以在本地項目下安裝它。
npm install --save-dev browser-sync
如果你想更加深度地了解它,可以在瀏覽器上搜索以下網址:
http://www.browsersync.cn/docs/
browser-sync可以單獨使用,也可以集成到gulp和grunt這樣的構建工具中使用,在Node.js項目中還能結合gulp-nodemon實現(xiàn)全棧的自動刷新。
gulp-nodemon
nodemon是一款非常實用的工具,用來監(jiān)控你 Node.js 源代碼的任何變化和自動重啟你的服務器。 gulp-nodemon幾乎和普通gulp-nodemon完全一樣,但它是為執(zhí)行Gulp任務而設計的。
介紹完我們需要了解的知識點之后,我們就深入到gulpfile.js文件中,看看是如何實現(xiàn)前后端熱重載的。
const gulp = require('gulp');
const browserSync = require('browser-sync').create();
const nodemon = require('gulp-nodemon');
gulp.task('server', function() {
nodemon({
script: 'server/app.js',
ignore: ["gulpfile.js", "node_modules/"],
env: {
'NODE_ENV': 'development'
}
}).on('start', function() {
browserSync.init({
proxy: 'http://localhost:3000',
files: ["src/**"],
port:8080
}, function() {
console.log("browser refreshed.");
});
});
});
在此之前,你需要安裝以下三個依賴:
npm install gulp -D
npm install browser-sync -D
npm install gulp-nodemon -D
安裝完依賴之后,我們就來解讀下以上代碼。
require('browser-sync').create();這行代碼的意思是創(chuàng)建browser-sync實例,并允許您創(chuàng)建多個服務器或代理。
gulp.task()代碼段作用是創(chuàng)建任務。
// 創(chuàng)建任務
// 第一個參數(shù): 任務名
// 第二個參數(shù): 回調函數(shù),當我們執(zhí)行任務時就會執(zhí)行這個函數(shù)
gulp.task('test', function(){
console.log('test');
})
nodemon中是一個配置對象。
script:指向服務器文件地址。
ignore:忽略部分對程序運行無影響的文件的改動,nodemon只監(jiān)視js文件,可用ext項來擴展別的文件類型。
env:運行環(huán)境 development 是開發(fā)環(huán)境,production 是生產環(huán)境。
這里,我們通過gulp-nodemon的start事件來觸發(fā)browser-sync的啟動。
browserSync.init()這行代碼的init方法中,第一個參數(shù)我們需要傳入一個配置對象,第二個參數(shù)我們需要定義一個回調方法。
proxy:代理服務端的接口地址。
files:需要監(jiān)聽的文件目錄。
port:端口號。
這里需要注意的是,如果是修改了服務端的js文件,會先通過nodemon重啟應用,這時瀏覽器不會刷新,要再保存一下修改的文件,browser-sync才會顯示出修改后的效果。
瀏覽效果
至此,我們的項目就大功告成了,在瀏覽之前呢!我們需要這樣一個操作。打開package.json文件。定義一個啟動命令,方便我們每次啟動。
"scripts": {
"dev": "gulp server"
},
之后,我們就可以這樣啟動項目了。
打開成功,現(xiàn)在我們改動下代碼,看看是否可以熱重載。
測試成功,這樣我們就安心地開發(fā)自己的代碼了,效率自然就提高了。之前那樣不停地F5,有沒有覺得這個動作對程序員來說很沒有創(chuàng)造力呢?現(xiàn)在可以減輕左手和F5鍵的負擔了。
作者:Vam的金豆之路
主要領域:前端開發(fā)
我的微信:maomin9761
微信公眾號:前端歷劫之路