Vue 3 項(xiàng)目實(shí)戰(zhàn)總結(jié)
作為今年前端圈中最大的新聞之一,vue 3 的正式版的發(fā)布引起了幾乎所有前端 er 的圍觀。步入 2021 年,我開(kāi)始在項(xiàng)目中使用 vue 3 進(jìn)行開(kāi)發(fā)。以下是我使用 vue 3 一個(gè)月后的一些經(jīng)驗(yàn)總結(jié)以及看法。
開(kāi)發(fā)環(huán)境方面
一般我們使用 vue 3 都是使用 vue 官方的腳手架新建項(xiàng)目,要么是 vue-cli 或者 vite。考慮到 vite 是新出的東西,兼容性方面還有待檢測(cè),于是我使用的是 vue-cli 來(lái)新建項(xiàng)目。
vue.config.js 的 externals 設(shè)置
作為一家小公司的前端工程師,我覺(jué)得 externals 這一個(gè)設(shè)置幾乎是整個(gè)開(kāi)發(fā)環(huán)境中最重要的東西。
首先簡(jiǎn)單介紹一下 externals 這個(gè)設(shè)置的作用。
Externals 是來(lái)自于 webpack 的配置項(xiàng),主要作用是提供了「從輸出的 bundle 中排除依賴」的方法。簡(jiǎn)單舉個(gè)例子就是,假如有個(gè)幾個(gè)項(xiàng)目都使用到了 axios,那么如果不使用 externals,每個(gè)項(xiàng)目都會(huì)打包一份 axios 到 ventor 中。使用了 externals 之后,可以把 axios 進(jìn)行外部引入,而 axios 的庫(kù)文件可以用第三方 cdn 或者放到統(tǒng)一的 cdn 服務(wù)器上面。
配置方法十分簡(jiǎn)單:
const externals = {
jquery: "jQuery",
};
module.exports = {
configureWebpack: (config) => {
Object.assign(config, {
externals,
});
},
};
這里要打開(kāi) jquery.min.js 的查看 jquery 暴露的全局名稱,jquery 的是 jQuery,然后在 index.html 中使用 script 引入就可以了:
src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous">
Externals 為什么如此重要,我認(rèn)為有以下幾個(gè)原因:
節(jié)省服務(wù)器空間,減少項(xiàng)目之間的代碼重復(fù)
充分使用 cdn 服務(wù)器
減少開(kāi)發(fā)過(guò)程中,編譯的時(shí)間
開(kāi)發(fā)過(guò)程中的模擬數(shù)據(jù)
模擬數(shù)據(jù)在前端開(kāi)發(fā)中經(jīng)常用到,在后端同事沒(méi)有完成接口的時(shí)候,前端需要自己模擬后端返回?cái)?shù)據(jù),提高工作效率。
目前我接觸到的模擬數(shù)據(jù)方法有幾個(gè):
Mock.js:
Mock.js 應(yīng)該算最常用的模擬數(shù)據(jù)庫(kù)了,通過(guò)簡(jiǎn)單配置即可模擬接口數(shù)據(jù)。優(yōu)點(diǎn)在于配置方便快捷,功能相對(duì)齊全。缺點(diǎn)是維護(hù) mock.js 的人不多,很多代碼已經(jīng)是幾年前的代碼
Postman:
Postman 中有自帶 mock 的功能,配置也非常簡(jiǎn)單,而且不需要在項(xiàng)目中引入任何額外的庫(kù)。而這個(gè)方法的問(wèn)題是 Postman mock 的原理是把配置的接口上傳到 postman 的服務(wù)器,很多公司的項(xiàng)目不希望自己的接口數(shù)據(jù)被別人知道,安全性不足 自建 json 文件:自己新建接口返回值對(duì)應(yīng)的 json 文件,代碼中判斷是開(kāi)發(fā)模式還是生產(chǎn)來(lái)切換。好處是所有的數(shù)據(jù)都能自己配置,不受其他庫(kù)和平臺(tái)的約束。不足是需要自己寫代碼,不夠簡(jiǎn)便
最后一個(gè)是我一直在使用的方法,因?yàn)?vue cli 內(nèi)部是使用 webpack dev server,而 webpack dev server 使用 express,利用 webpack 的 proxy 功能搭配上 express 可以自建一個(gè) api 服務(wù)器,具體操作如下:
使用 before 調(diào)用內(nèi)部 express 的 app 實(shí)例
const { setApi } = require('./mock/api');
// vue.config.js
devServer: {
open: process.platform === 'darwin',
host: '0.0.0.0',
port: 3000,
https: false,
disableHostCheck: true,
before: (app) => {
setApi(app)
}
}
使用 app 實(shí)例創(chuàng)建 api 服務(wù)器(可以加入 swagger 等等的庫(kù),增加 api 服務(wù)器的用戶體驗(yàn)):
// ./mock/api.js
const swaggerUi = require("swagger-ui-express");
const submit = require("./submit");
const setApi = (app) => {
const apiData = {
api: [...cj, ...submit, ...question, ...vote],
};
const swaggerDocument = {
swagger: "2.0",
paths: {
"/pets": {},
},
};
apiData.api.forEach((api) => {
app[api.type](`/api${api.paths}`, (req, res) => {
res.json(api.responses);
});
swaggerDocument.paths[`/api${api.paths}`] = {
[api.type]: {
tags: [api.tags],
responses: {
[api.responses.statusCode]: {
description: `successful operation ${JSON.stringify(
api.responses
)}`,
},
},
},
};
});
app.use(
"/api/docs",
swaggerUi.serve,
swaggerUi.setup(swaggerDocument, {
swaggerOptions: {
validatorUrl: null,
},
})
);
};
module.exports = { setApi };
// ./mock/submit.js
module.exports = [{
type: "post",
paths: "/submit",
tags: "submit",
responses: {
statusCode: "200",
data: "",
msg: "提交成功!",
},
}
]
最終效果是請(qǐng)求 http://ip地址/api/接口名稱 可以請(qǐng)求數(shù)據(jù),請(qǐng)求 http://ip地址/api/docs ,可以看到自定義的接口文檔
圖片
模塊導(dǎo)入
Vue 3 當(dāng)中的模塊導(dǎo)入,其實(shí)跟 vue 2 區(qū)別不大,但是因?yàn)?vue 3 使用了 typescript,所以涉及到 typescript 模塊的一些知識(shí)。
搭配 externals 的模塊導(dǎo)入
當(dāng)我們使用前面說(shuō)到的 externals 的時(shí)候,原則上來(lái)說(shuō)我們不再需要去安裝已經(jīng)設(shè)置了 externals 的模塊。正如上面的例子:
src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous">
Script 引入了 jquery 之后,我們不需要再 npm i jquery。然而由于我們一般會(huì)使用 eslint 進(jìn)行代碼格式檢驗(yàn),如果我們不安裝 jquery 的話,eslint 會(huì)報(bào)錯(cuò)。這個(gè)時(shí)候,使用 javascript 開(kāi)發(fā)的話,我們需要配置一下 eslint 規(guī)則,會(huì)把 jquery 設(shè)置成 core-modules:
// .eslintrc.js
settings: {
'import/core-modules': ['jquery'],
}
但是如果是用 typescript 的話,設(shè)置了 core-modules 還不行,因?yàn)榫庉嬈鳎╲scode)沒(méi)有找到對(duì)應(yīng)的 d.ts 文件,所以就算 eslint 不報(bào)錯(cuò),開(kāi)發(fā)起來(lái)也沒(méi)有 typescript 的提示。這時(shí)候,我的解決辦法是,依舊使用 npm i 安裝對(duì)應(yīng)依賴的聲明文件。如果庫(kù)聲明文件包含在庫(kù)里面,則直接安裝依賴。
這樣處理雖然 node_modules 會(huì)變大,但是編譯的時(shí)候 webpack 是不會(huì)把 node_modules 中的庫(kù)打包進(jìn)項(xiàng)目中。
導(dǎo)入沒(méi)有聲明文件的庫(kù)
對(duì)于一些老舊的或者沒(méi)有聲明文件的庫(kù),需要在 shims-vue.d.ts 來(lái)為庫(kù)定義類型,例如微信的 js 文件 res.wx.qq.com/open/js/jwe…
declare module '*.vue' {
import type { DefineComponent } from 'vue';
const component: DefineComponent<{}, {}, any>;
export default component;
}
declare module '*.svg'
declare module '*.png'
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.gif'
declare module '*.bmp'
declare module '*.tiff'
declare module '*.json'
declare module '*.mp3'
declare const wx: any;