顯示具有 vite 標籤的文章。 顯示所有文章
顯示具有 vite 標籤的文章。 顯示所有文章

2023年9月20日 星期三

vite支援老舊瀏覽器

 前言:公司客服反映有八年前android(chrome)跟十年前5s(safari),打開網頁看不到畫面,換台3000塊以上的手機很難嗎==這要求跟要我支援ie差不多吧,好在客戶群沒很大,老闆就沒逼很急,所以花了點時間研究,做一下紀錄。

簡單說就是vite有出一個plugin:@vite/plugin-lagacy,看名字應該看得出來是為了骨灰級瀏覽器而有的,新的瀏覽器都支援ESM,然而不支援ESM的瀏覽器只好使用pollyfill去讓他被支援,詳細配置如下

// vite.config.js
plugins: [
......
legacy({
targets: ["defaults", "ie 11"],
additionalLegacyPolyfills: ["regenerator-runtime/runtime"],
}),
],

基本上配置這樣就可以了,我都支援到ie11了總可以放過我了吧。確實在同事口中傳回來捷報說有畫面了,但是!人生最可怕的就是這個但是,但是在打某支api會出現,promise rejection.....

只好下一篇待續

2023年7月14日 星期五

webpack轉換vite使用心得

 最近把公司專案從webpack4搬到vite上,所以研究了一下,只能說我非常喜歡vite的風格,不像webpack有一大堆看不懂的設定跟一堆plugin,設定起來非常快速跟方便。

不過兩之間還是有一定的差距,不可能只搬打包工具而程式碼不動,這裡就列出幾個會有影響的程式碼

require
vite是不支援require的,就算裝了套件vite-plutin-require,require進來的也只會有路徑而已,但svg可以透過vite-plugin-svgr把require進來的東西轉成component,但如果要做到dynamic import也只能透過異步加載(loadable)的方式來處理

process.env
在webpack可以用這種寫法將環境變數注入到程式碼中,vite當然也可以,但寫法不同,是用import.meta.env,如果不想改寫法,可以在vite.config.js裡面設定define把process.env.API_HOST: 127.0.0.1之類的,讓vite專案也看得懂process.env.XXXX
ps. 如果使用import.meta.env記得要將環境變數以VITE_開頭才讀取得到喔

static public資料夾
webpack好像不特別設定是不會打包靜態資料夾的,可以進行另外處理,但在vite有個publicDir,預設為public,在打包時就會把public裡面的東西打包進目標資料夾的根目錄,例如/public/image => /dist/image
如果不想打包可以設為false

image
在專案中如果是css設定background-image: url(...),vite會自動判斷最終這張圖片是否是存在靜態資料夾,如果不是則是會被打包成圖片檔+hash的檔名,等於把路徑寫在css裡,路徑跟圖片是會被強迫編譯的,這點跟webpack就不一樣,少了一點彈性,沒辦法拿來做文章。
如果在html裡,<img src="/image/logo.png"/>則不會被編譯,當然如果你網址是指到你的根目錄這完全不會有任何問題,但如果你的網址有前綴,例如https://test.com/web/xxxxx,這樣/image/logo.png就會找不到圖片,因為圖片在/web/image/logo.png,所以解決方式是使用import logo from "/public/image/logo.png"
<img src={logo} />
這樣打包完src就會被編譯成/web/image/logo.png

如果像上述情況有前綴,在vite.config.js裡面有個base: "/web",這樣所有的引入都會加上前綴/web

我有試過官方提供new URL("image path").href,在固定路徑的情況下可以,但如果是dynamic path就會變成undefined,試了好幾次也沒辦法,只好放棄

曾經我有試過require("image path")的方式把引入變成路徑,一開始有成功,但重開專案之後又失敗了,也是很神奇的一次經驗。

大致上遇到要調整的就這些,只能說vite真的是很神,設定簡單,也不用裝一堆外掛,編譯速度又快

之後有空也可以pwa的部分

2021年9月23日 星期四

vite vue3 ts踩過的坑

記錄一下踩過的坑

在src/interface/index.ts寫了如下

export interface iSelf {
id: number
phone: string
role: number
email?: string
name_ch?: string
name_en?: string
gender: number
identity_id?: string
birthday?: string
resident_status: string
}

export interface iUser extends iSelf {
checked: boolean
}


再引用時卻出現

Uncaught SyntaxError: The requested module 'src/interface/index.ts' does not provide an export named 'iUser'

這沒道理啊,一個檔案寫一個interface就正常,寫兩個就抱錯了!

網上高手給出ts3.8的export type特性

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html?fbclid=IwAR1pDqvqiYjNJkzFarak8i29xKAnPCCtK5fy2xgjUUmcS0BW4eRnqaesISo

但使用過後依然沒效

最終找到 https://github.com/vitejs/vite/issues/2117 這理尤大給出的答案,vite只支援ES Module,所以對於typescript的支援需要安裝套件

基本上安裝@rollup/plugin-typescript + tslib,然後到vite.config.ts加上plugin

import typescript from "@rollup/plugin-typescript"

export default defineConfig({
plugins: [vue(), typescript()],
})

然後src/interface/index.ts修改如下

/// <reference path="_user.d.ts" />

src/interface/_user.d.ts內容如下(對於src/interface模組進行擴充)

declare module "src/interface" {
interface iSelf {
id: number
phone: string
role: number
email?: string
}

interface iUser extends iSelf {
checked: boolean
}
}

使用方式如下(注意是import type)

import type { iUser } from "src/interface"
const datas: Array<iUser> = []

這樣運行就正常了

----------------------- 我是分隔線 ------------------------

以下不是常規方法,但總算是我試出來的分法,也記錄一下

如果不想引用套件,那src/interface/index.ts就要額外宣告變數

/// <reference path="_user.d.ts" />

export const iUser = {}
export const iSelf = {}

使用

import { iUser } from "src/interface"

但這樣有時還是會錯誤,iUser有時會被認為是any,所以還是乖乖正規吧

小結

看來一門技術只出來一年,還是有許多坑要採,沒關係要用就用得徹底一點,繼續踩坑吧

----------------------- 我是分隔線 ------------------------

9/5補充

不知為何當天需要安裝@rollup/plugin-typescript, tslib套件,vite原生就可以支援typescript才對,今天測試把套件拿掉結果一樣可以跑,所以就這樣吧~