真香
vite的特點簡單理解
- 使用原生esm編譯
- 使用rollup打包
- 支援熱更新(即時編譯)
- 更輕更快
分析常常會用到的需求
- 安裝搭配vue3與vue-router
- 環境變數功能
- 設定api proxy
- 設定檔案引入別名
- 設定拆分打包檔案
- 設定打包後靜態資料夾位置與名稱
- 設定打包後輸出資料夾位置與名稱
- 設定打包後服務器引入檔案路徑
- 設定打包後使用cdn引入
- 所有檔案共享指定scss檔案
安裝與啟動
安裝vite
npm init vite@latest //vite的
npm init vue@next //vue官網推薦
安裝vue3
# npm 6.x
npm init vite@latest my-vue-app --template vue
# npm 7+, extra double-dash is needed:
npm init vite@latest my-vue-app -- --template vue
安裝vue-router
npm install vue-router@next -S
搭建vue-router
# main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
# router > index.js
import { createRouter, createWebHashHistory } from "vue-router";
const routes = [
{
path: "/", component: () => import("../views/HelloWorld.vue"),
}
]
export default createRouter({
history: createWebHashHistory(),
routes
});
npm run dev 啟動
npm run build 打包
npm run serve 預覽打包後的結果
環境變數功能
檔案裡面的變數都要開頭為VITE才可以在組建內使用
#檔案名稱
.env # loaded in all cases
.env.local # loaded in all cases, ignored by git
.env.[mode] # only loaded in specified mode
.env.[mode].local # only loaded in specified mode, ignored by git
API PROXY
# vite.config.js
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
export default defineConfig({
server: {
port: 3030, //npm run dev port
proxy: { //跨域代理
// 字符串简写写法
'/foo': 'http://localhost:4567',
// 选项写法
'/api': {
target: 'https://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
},
// 正则表达式写法
'^/fallback/.*': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/fallback/, '')
},
// 使用 proxy 实例
// '/api': {
// target: 'http://jsonplaceholder.typicode.com',
// changeOrigin: true,
// configure: (proxy, options) => {
// // proxy 是 'http-proxy' 的实例
// }
// }
}
}
})
設定檔案引入別名
# vite.config.js
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
export default defineConfig({
resolve: {
alias: {
'@/': `${path.resolve(__dirname, 'src')}/` //別名
}
},
})
打包設定
- 設定打包後靜態資料夾位置與名稱
- 設定打包後輸出資料夾位置與名稱
- 設定打包後服務器引入檔案路徑
- 設定打包後使用cdn引入
# vite.config.js
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import externalGlobals from "rollup-plugin-external-globals"; //打包後要使用cdn的變數時需要安裝此外掛,開發時一樣可以用import引入使用.
export default defineConfig({
build: {
rollupOptions: {
//當成外部模組
external: ['vue', 'axios', 'vue-router'], //不打包 用cdn引入要記得在index.html頁面掛上cdn不然打包後會出錯
output: {
manualChunks(id) { //分割打包
if (id.includes('node_modules') && id.includes('@vue')) {
return 'vender'
}
if (id.includes('node_modules')) {
if (id.includes('vue/dist/vue.runtime.esm-bundler.js')) return
return id.toString().split('node_modules/')[1].split('/')[0].toString()
}
}
},
plugins: [
externalGlobals({ //打包後使用cdn的配置
vue: "Vue",
axios: 'axios',
['vue-router']: 'VueRouter'
})
],
chunkSizeWarningLimit: 500, // chunk 大小警告的限制
outDir: 'dist', // 構建輸出路徑
assetsDir: 'assets', //靜態資原始檔夾,和outDir同級
assetsInlineLimit: 4096, // kb, 小於此值將內聯base64格式
cssCodeSplit: true, // 執行css檔案按chunk拆分,chunk載入時插入,如果false則所有的樣式匯出為一個css檔案
},
})
所有檔案共享指定scss檔案
# vite.config.js
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
export default defineConfig({
css: {
preprocessorOptions: { //所有檔案共享某個scss感覺我會用來做變量等等放置的檔案
scss: {
additionalData: `@import "@/assets/style/base.scss";`
}
}
}
})
資料夾模組化引入
import.meta.globEager('./modules/*.ts')
一次性引入某個資料夾的檔案
https://cn.vitejs.dev/guide/features.html#glob-import
import { createRouter, createWebHistory } from 'vue-router'
const routes:any = []
const modules = import.meta.globEager('./modules/*.ts')
for (const path in modules) {
routes.push(...modules[path].default)
}
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default router
全部的設定
import path from 'path'
import externalGlobals from "rollup-plugin-external-globals"; //cdn
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
root: path.resolve(__dirname), //index.html所在資料夾
publicDir: 'public', //靜態資源
base: './', //服務器檔案引入路徑
build: {
rollupOptions: {
//當成外部模組
external: ['vue', 'axios', 'vue-router'], //不打包 用cdn引入
output: {
manualChunks(id) { //分割打包
if (id.includes('node_modules') && id.includes('@vue')) {
return 'vender'
}
if (id.includes('node_modules')) {
if (id.includes('vue/dist/vue.runtime.esm-bundler.js')) return
return id.toString().split('node_modules/')[1].split('/')[0].toString()
}
}
},
plugins: [
externalGlobals({
vue: "Vue",
axios: 'axios',
['vue-router']: 'VueRouter'
})
],
// chunk 大小警告的限制
chunkSizeWarningLimit: 500,
},
outDir: 'dist', // 構建輸出路徑
assetsDir: 'assets', //靜態資原始檔夾,和outDir同級
assetsInlineLimit: 4096, // kb, 小於此值將內聯base64格式
cssCodeSplit: true, // 執行css檔案按chunk拆分,chunk載入時插入,如果false則所有的樣式匯出為一個css檔案
},
plugins: [vue()],
resolve: {
alias: {
'@/': `${path.resolve(__dirname, 'src')}/` //別名
}
},
server: {
port: 3030, //npm run dev port
proxy: { //跨域代理
// 字符串简写写法
'/foo': 'http://localhost:4567',
// 选项写法
'/api': {
target: 'https://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
},
// 正则表达式写法
'^/fallback/.*': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/fallback/, '')
},
// 使用 proxy 实例
// '/api': {
// target: 'http://jsonplaceholder.typicode.com',
// changeOrigin: true,
// configure: (proxy, options) => {
// // proxy 是 'http-proxy' 的实例
// }
// }
}
},
css: {
preprocessorOptions: { //可以所有檔案共享某個scss 感覺我會用來做變量等等的宣告
scss: {
additionalData: `@import "@/assets/style/base.scss";`
}
}
}
})
參考資料
官網
https://vitejs.dev/guide/env-and-mode.html#production-replacement
postcss
https://cythilya.github.io/2018/08/10/postcss/
cdn注入
https://github.com/vitejs/vite/discussions/2836
gzip
https://www.npmjs.com/package/vite-plugin-compression