日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一篇學會如何使用Vite重構(gòu)Vue3項目

前言

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

為青縣等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及青縣網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、青縣網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

本篇文章就記錄下我的重構(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根目錄下
  • 通過

    注意:如果你的項目比較復(fù)雜,有多個入口,那么就將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)境。如果你的項目較為復(fù)雜,也不必太過擔心,你的應(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)主題等),可以避免一些重復(fù)性的工作內(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速度就是快,嘴角瘋狂上揚。

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

    解決方案

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

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

    • 通過import語句直接導(dǎo)入圖片
    • 通過new URL來導(dǎo)入圖片

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

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





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

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

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

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

    我試圖從vue的包中導(dǎo)入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ù)或者導(dǎo)入了一個文件,在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
    });

    無法導(dǎo)入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)類型無法推導(dǎo)問題,如下所示:

    第三方庫提供了一個$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導(dǎo)入很多靜態(tài)資源時,組件看起來會很雜亂。此時我們可以將其按照功能類型進行拆分。我的做法如下:

    • 在src下創(chuàng)建resource文件夾
    • 根據(jù)功能類型創(chuàng)建ts文件,將其導(dǎo)出
    import defaultAvatar from "@/assets/img/login/LoginWindow_BigDefaultHeadImage@2x.png";
    import defaultLoginBtnIcon from "@/assets/img/login/icon-enter-undo@2x.png";
    import loginUndo from "@/assets/img/login/icon-enter-undo@2x.png";
    import loginBtnHover from "@/assets/img/login/icon-enter-hover@2x.png";
    import loginBtnDown from "@/assets/img/login/icon-enter-down@2x.png";

    export {
    defaultAvatar,
    defaultLoginBtnIcon,
    loginUndo,
    loginBtnHover,
    loginBtnDown
    };

    分離模版與邏輯代碼

    我的項目中有一個很復(fù)雜的組件,有上千行代碼,去年我用CompositionAPI優(yōu)化了一版,將組件中所有的方法都拆分成了一個個獨立的ts文件,做到了邏輯代碼與模版代碼分離,模版需要什么方法我就通過import導(dǎo)入進來,最后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獲取即可,如下所示:

    此組件重構(gòu)后的完整代碼請移步:

    • message-display.vue
    • EventMonitoring.ts

    項目地址

    至此,項目的重構(gòu)工作就結(jié)束了。本文重構(gòu)好的項目代碼地址:


    分享標題:一篇學會如何使用Vite重構(gòu)Vue3項目
    URL鏈接:http://www.dlmjj.cn/article/dpedecp.html