免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      一篇學會如何使用Vite重構(gòu)Vue3項目

      一篇學會如何使用Vite重構(gòu)Vue3項目

      前言

      截止發(fā)文時間,vite正式版已經(jīng)發(fā)布快2年時間了,vue3也發(fā)布到3.2版本了,它的周邊設(shè)施基本上已經(jīng)齊活了。也是時候再次重構(gòu)下我那個vue3.0的開源項目了。

      本篇文章就記錄下我的重構(gòu)過程,歡迎各位感興趣的開發(fā)者閱讀本文。

      環(huán)境搭建

      1年多前,我用Vue Cli 4.5構(gòu)建的此項目,有關(guān)此項目的更多細節(jié)請移步我的另一篇文章使用Vue3重構(gòu)Vue2項目。同樣的,從CLI遷移到Vite仍然是在package.json中添加vite的依賴項,在項目中添加它的配置文件

      此次項目構(gòu)建還加入了volta的相關(guān)配置,對此感興趣的開發(fā)者請移步:強大的JavaScript工具管理器Volta

      新增vite相關(guān)依賴項

      我們打開package.json,找到devDependencies字段,移除CLI相關(guān)的依賴,添加vite相關(guān)的依賴,如下所示:

      • +綠色標識代表新增
      • -紅色標識代表移除

      { “dependencies”: {- “compression-webpack-plugin”: “^5.0.1”, }, “devDependencies”: {+ “@vitejs/plugin-vue”: “^3.0.0”,+ “vite”: “^3.0.0”,+ “vue-tsc”: “^0.38.4”,+ “@types/node”: “^18.6.3”,- “sass-loader”: “^8.0.2”,- “@vue/cli-plugin-babel”: “~4.5.0”,- “@vue/cli-plugin-eslint”: “~4.5.0”,- “@vue/cli-plugin-router”: “~4.5.0”,- “@vue/cli-plugin-typescript”: “~4.5.0”,- “@vue/cli-plugin-vuex”: “~4.5.0”,- “@vue/cli-service”: “~4.5.0”,- “@vue/compiler-sfc”: “^3.0.0-0”- }}

      隨后,我們找到scripts字段,修改項目的運行與構(gòu)建命令。

      { “scripts”: { “serve”: “vite –open”, “build”: “vue-tsc –noEmit && vite build”, “preview”: “vite preview” }}

      vite3.x版本要求node版本必須大于14.18.0,因此我們需要在engines字段中做一下提示,如下所示:

      { “engines”: { “npm”: “please-use-yarn”, “yarn”: “>= 1.0.0”, “node”: “>= 14.18.0” }}

      除了上述配置外,我們還需要在項目的根目錄創(chuàng)建.npmrc文件,寫入下述內(nèi)容:

      engine-strict = true

      配置完成后,我們執(zhí)行在終端執(zhí)行yarn install安裝依賴即可。

      在上述配置中,我們還強制設(shè)置了yarn作為項目的包管理工具,如果項目開發(fā)成員使用了npm install則不會開始安裝依賴并提示其使用yarn來安裝依賴。

      添加vite配置文件

      在vite中,index.html已經(jīng)從public文件夾遷移到項目的根目錄下了,官方文檔對此的解釋為:在開發(fā)期間 Vite 是一個服務(wù)器,而 index.html 是該 Vite 項目的入口文件。

      有關(guān)此變更的詳細解釋請移步:index.html 與項目根目錄

      接下來,我們在項目的根目錄創(chuàng)建index.html文件(將public目錄下的文件刪除)

      • 引入靜態(tài)文件時不需要使用%PUBLIC_URL%作為占位符,可以直接寫/來訪問,vite會將其解析到public根目錄下
      • 通過

        注意:如果你的項目比較復雜,有多個入口,那么就將index.html文件放到對應(yīng)入口的根目錄下。

        最后,我們創(chuàng)建vite.config.ts文件,配置代碼如下所示:

        • 設(shè)置開發(fā)環(huán)境的端口號
        • 設(shè)置路徑別名
        • 設(shè)置打包后base地址以及打包輸出目錄

        import { defineConfig } from “vite”;import { resolve } from “path”;import vue from “@vitejs/plugin-vue”;const IS_PRODUCTION = process.env.NODE_ENV === “production”;export default defineConfig({ plugins: [vue()], server: { host: true, port: 8020, proxy: {} }, resolve: { // 設(shè)置路徑別名 alias: { “@”: resolve(__dirname, “./src”), “*”: resolve(“”) } }, base: IS_PRODUCTION ? “/chat-system” : “./”, define: { “process.env”: {} }, build: { outDir: resolve(__dirname, “dist”) }});

        注意:我的項目配置比較簡單,它只有一個入口,打包后只會部署到生產(chǎn)環(huán)境。如果你的項目較為復雜,也不必太過擔心,你的應(yīng)用場景vite也是支持的,按照文檔進行相關(guān)的配置就好,如下所示:

        • 自定義構(gòu)建
        • 多頁面應(yīng)用模式
        • 環(huán)境變量和模式

        當你的項目有多個入口時,期望通過不同命令來啟動不同項目時,你可以使用yarn的–cwd指令來指定其運行時的工作目錄。

        例如:你有兩個入口,那么就在src目錄下創(chuàng)建兩個文件夾:**A、B **。A和B中分別有自己的index.html、main.ts以及package.json文件(配置start、build命令,傳入不同的參數(shù)來啟動/構(gòu)建不同入口的項目)

        根目錄的package.json中你就可以配置啟動/構(gòu)建命令為:

        { “scripts”: { “dev:A”: “yarn –cwd ./src/A run start”, “dev:B”: “yarn –cwd ./src/B run start”, “build:A”: “yarn –cwd ./src/A run build”, “build:B”: “yarn –cwd ./src/B run build”, “build”: “vue-tsc –noEmit && vite build”, “preview”: “vite preview” },}

        最后,我們以A入口為例,列舉下package.json文件中的配置:

        { “name”: “A”, “version”: “1.0.0”, “main”: “index.js”, “license”: “MIT”, “scripts”: { “start”: “vite serve –config ../../vite.config-A.ts –mode development”, “build”: “vue-tsc –noEmit && vite build –config ../../vite.config-A.ts –mode production” }}

        升級Vue周邊依賴項

        vue3.2的單文件組件引入了setup規(guī)范,它可以讓代碼變得更簡潔,可以使用純 TypeScript 聲明 props 和拋出事件,有著更好的運行時性能。這些優(yōu)點讓我有了升級vue版本的動力,之前的3.0版本寫起來很臃腫,需要return一大堆東西,甚是麻煩。

        打開package.json文件作出下述變動:

        • 更新了vue、router、vuex的版本號
        • 新增了vueuse包,這是一個基于 Composition API 的實用函數(shù)集合,封裝了一些常用的功能(實時獲取鼠標位置、防抖、節(jié)流、獲取客戶端系統(tǒng)主題等),可以避免一些重復性的工作內(nèi)容,大大提升開發(fā)效率。

        { “dependencies”: { – “vue”: “^3.0.0-0”,- “vue-class-component”: “^8.0.0-0”- “vue-router”: “^4.0.0-0”,- “vuex”: “^4.0.0-0”,+ “vue”: “^3.2.37”,+ “vue-router”: “^4.1.3”,+ “vuex”: “^4.0.2”,+ “@vueuse/components”: “^8.9.2”,+ “@vueuse/core”: “^8.9.2” }}

        最后執(zhí)行yarn install即可完成整個環(huán)境的搭建,本章節(jié)重構(gòu)完成后的完整文件請移步:

        • .npmrc
        • index.html
        • package.json
        • vite.config.ts

        經(jīng)驗分享

        本章節(jié)就跟大家分享下,我切到新環(huán)境后做的一些優(yōu)化點以及遇到的問題和解決方案。

        本章節(jié)修改到的文件,完整文件代碼如下:

        • package.json
        • tsconfig.json

        require不存在

        一切準備就緒后,按下了項目啟動按鈕,很快啊,651ms項目就啟動了,不愧是vite速度就是快,嘴角瘋狂上揚。

        瀏覽器加載完項目后,我傻眼了,我的登陸界面呢:new_moon_with_face:?順勢打開控制臺,發(fā)現(xiàn)報錯require is not defined。

        解決方案

        打開Login.vue文件后,發(fā)現(xiàn)我用require導入了一些圖片文件,在VueCLI環(huán)境下的require會交給webpack處理。在vite中是不存在的,那么我們就需要查看vite是怎么處理靜態(tài)文件了。

        翻了下文檔后,在靜態(tài)資源處理章節(jié)發(fā)現(xiàn)他有兩種處理方法

        • 通過import語句直接導入圖片
        • 通過new URL來導入圖片

        我打算將所有組件都重構(gòu)為setup形式,因此直接使用import方式來導入圖片可以保持組件的一致性,可以大大提升可讀性。

        我們寫個簡單的demo來嘗試下,如下所示:

        已經(jīng)可以正確解析出圖片的路徑了。

        注意:本文不會過多講解setup的語法,對此不了解的開發(fā)者請移步:單文件組件 – script setup

        new URL方式可以用來引入一個動態(tài)資源,例如:你有一份json配置文件,里面描述了圖片的文件名,這些圖片是放在項目中的,他們的訪問前綴都一樣,此時你就可以通過遍歷json文件通過此方式來引入這些圖片。

        vue相關(guān)模塊不存在

        我試圖從vue的包中導入shallowRef時,編輯器報錯: TS2305: Module ‘xxx’ has no exported member ‘shallowRef’. 。

        解決方案

        經(jīng)過一番排查后,是因為項目typescript版本是3.x,跟3.2版本的vue不兼容,需要將其升級至4.x版本。

        打開package.json文件,作出如下所示的修改,重新執(zhí)行yarn install命令即可。

        { “devDependencies”: {- “typescript”: “~3.9.3”,+ “typescript”: “~4.7.4”, }}

        setup中的變量警告未被使用

        當我在setup中聲明了一個函數(shù)或者導入了一個文件,在template中已經(jīng)使用了,但是他卻報錯ESLint: ‘xx’ is assigned a value but never used.(@typescript-eslint/no-unused-vars)

        解決方案

        在 eslint-plugin-vue 插件的Issues中看到有人遇到了跟我同樣的問題,在v9.0.0: regression in unused variables in script setup中我找到了解決方案。

        我們需要升級下@vue/eslint-config-typescript和eslint-plugin-vue的版本號,如下所示:

        { “devDependencies”: { “@vue/eslint-config-typescript”: “^11.0.0”, “eslint-plugin-vue”: “^9.0.0” }}

        隨后在eslint的配置文件中,添加parser屬性,重新執(zhí)行yarn install命令即可。

        module.exports = {+ parser: ‘vue-eslint-parser’}

        模塊隔離

        Vite 使用 esbuild 來轉(zhuǎn)譯 TypeScript,并受限于單文件轉(zhuǎn)譯的限制,因此需要在ts的配置文件中將isolatedModules屬性設(shè)置為true。

        { “compilerOptions”: { “isolatedModules”: true }}

        process不存在

        在路由配置文件中,我們需要從process中獲取BASE_URL,此時編輯器報錯: TS2591: Cannot find name ‘process’. Do you need to install type definitions for node? Try npm i –save-dev @types/node and then add ‘node’ to the types field in your tsconfig.

        解決方案

        由于vite中已經(jīng)沒有process了,需要用import.meta來代替,那么上述的路由配置文件就應(yīng)該改為:

        const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), // 地址欄不帶# routes});

        無法導入json文件

        在表情面板模塊,我將每個表情都放入了json文件中。在vite中引入文件需要使用import,改了寫法后,發(fā)現(xiàn)它報錯:Cannot find module ‘xx.json’. Consider using ‘–resolveJsonModule’ to import module with ‘.json’ extension.

        解決方案

        我們需要在ts的配置文件中添加resolveJsonModule屬性,如下所示:

        { “compilerOptions”: {+ “resolveJsonModule”: true }}

        使用vite提供的對象

        當我想使用vite所提供的glob屬性時,發(fā)現(xiàn)編輯器報錯: TS2339: Property ‘glob’ does not exist on type ‘ImportMeta’.

        解決方案也很簡單,我們只需要在ts的配置文件中添加vite/client即可,如下所示:

        { “compilerOptions”: { “types”: [+ “vite/client” ] }}

        獲取全局屬性

        當我們使用一些第三方庫的時候它會在globalProperties掛載一些方法,當在ts+setup環(huán)境下使用時,會出現(xiàn)類型無法推導問題,如下所示:

        第三方庫提供了一個$connect方法

        我們通過proxy來訪問

        他會出現(xiàn)報錯: TS2339: Property ‘xx’ does not exist on type ‘ComponentPublicInstance{}, {}, {}, {}, {}, {}, {}, {}, false, ComponentOptionsBase >’.

        解決方案

        我們可以在type目錄下新建一個global文件夾,在這里存放一些我們擴展出來的全局方法。

        如下所示,我們:

        • 創(chuàng)建了一個useCurrentInstance方法
        • 將globalProperties屬性暴露出去

        import { ComponentInternalInstance, getCurrentInstance } from “vue”;export default function useCurrentInstance() { const { appContext } = getCurrentInstance() as ComponentInternalInstance; const proxy = appContext.config.globalProperties; return { proxy };}

        我們在組件中使用暴露出來的proxy即可,如下所示:

        無法識別NodeJS類型

        我們在給setinterval和setTimeout指定類型時,會用到NodeJS模塊,會出現(xiàn)報錯:ESLint: ‘NodeJS’ is not defined.(no-undef)。

        這個問題的解決方案是:打開eslint的配置文件在globals對象中添加NodeJS選項,如下所示:

        { globals: { NodeJS: true }}

        除了將類型聲明為NodeJS.Timeout外,我們還可以將其聲明為number類型,但是需要攜帶window前綴(window.setinterval/window.setTimeout)

        管理靜態(tài)資源

        當我們在組件中使用import導入很多靜態(tài)資源時,組件看起來會很雜亂。此時我們可以將其按照功能類型進行拆分。我的做法如下:

        • 在src下創(chuàng)建resource文件夾
        • 根據(jù)功能類型創(chuàng)建ts文件,將其導出

        import defaultAvatar from “@/assets/img/login/[email protected]”;import defaultLoginBtnIcon from “@/assets/img/login/[email protected]”;import //imgq8.q578.com/ef/0816/df977c06ae2a4ebf.jpg from “@/assets/img/login/[email protected]”;import loginBtnHover from “@/assets/img/login/[email protected]”;import loginBtnDown from “@/assets/img/login/[email protected]”;export { defaultAvatar, defaultLoginBtnIcon, //imgq8.q578.com/ef/0816/df977c06ae2a4ebf.jpg, loginBtnHover, loginBtnDown};

        分離模版與邏輯代碼

        我的項目中有一個很復雜的組件,有上千行代碼,去年我用CompositionAPI優(yōu)化了一版,將組件中所有的方法都拆分成了一個個獨立的ts文件,做到了邏輯代碼與模版代碼分離,模版需要什么方法我就通過import導入進來,最后return給模版。

        在拆分出來的文件中,是沒有辦法訪問vue提供的一些內(nèi)置屬性的,比如:defineProps、defineEmits、getCurrentInstance。因此我想了一個奇妙的方法:將這些無法訪問的屬性都存起來。具體的做法請移步我另一篇文章:使用Vue3的CompositionAPI來優(yōu)化代碼量-創(chuàng)建InitData.ts文件

        適配方案

        vue3.2的setup語法糖支持import進來的方法都能在模版中直接使用,那我們的組件又可以精簡下了,我花了億點點時間對其進行了適配。

        之前我們想獲取組件的emit需要從context中拿,props聲明并從setup函數(shù)的參數(shù)中獲取,如下所示:

        現(xiàn)在我們就不用這么麻煩了,直接通過defineProps、defineEmits獲取即可,如下所示:

        鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
      用戶投稿
      上一篇 2022年8月16日 12:20
      下一篇 2022年8月16日 12:20

      相關(guān)推薦

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時間:周一至周五,10:30-18:30,節(jié)假日休息