方法一:插件
vite-plugin-vue-setup-extend
方法二:
<template>
<div>
</div>
</template>
<script name='xm' lang="ts" setup>
import { ref, reactive } from 'vue'
const props = defineProps({
data: {},
})
</script>
/src/utils/pluginName.ts
import type { Plugin } from 'vite'
//@vue/compiler-sfc 這個插件是處理我們單文件組件的代碼解析
import { compileScript, parse } from '@vue/compiler-sfc'
export default function setupName(): Plugin {
return {
name: 'vite:plugin:vue:name',
//一個 Vite 插件可以額外指定一個 `enforce` 屬性
//(類似於 webpack 加載器)來調整它的應用順序。`enforce` 的值可以是`pre` 或 `post`
//加載順序爲
//Alias
//帶有 `enforce: 'pre'` 的用戶插件
//Vite 核心插件
//沒有 enforce 值的用戶插件
//Vite 構建用的插件
//帶有 `enforce: 'post'` 的用戶插件
//Vite 後置構建插件(最小化,manifest,報告)
enforce: "pre",
//transform code參數就是我們寫的代碼比如vue代碼 id就是路徑例如/src/xx/xx.vue
transform(code, id) {
//只處理vue結尾的文件
if (/.vue$/.test(id)) {
let { descriptor } = parse(code)
//通過compileScript 處理script 返回result
//attrs: { name: 'xm', lang: 'ts', setup: true },
//lang: 'ts',
//setup: true,
const result = compileScript(descriptor, { id })
//attrs 此時就是一個對象
const name = result.attrs.name
const lang = result.attrs.lang
const inheritAttrs = result.attrs.inheritAttrs
//寫入script
const template = `
<script ${lang ? `lang=${lang}` : ''}>
export default {
${name ? `name:"${name}",` : ''}
${inheritAttrs ? `inheritAttrs: ${inheritAttrs !== 'false'},` : ''}
}
</script>
`;
//最後拼接上這段代碼 也就是我們加的script這一段 返回code
code += template;
// console.log(code)
}
return code
}
}
}
vite.config.ts 加入
import { defineConfig, loadEnv, UserConfigExport, ConfigEnv, searchForWorkspaceRoot } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import Components from 'unplugin-vue-components/vite';
import html,{createHtmlPlugin} from 'vite-plugin-html';
// import legacy from '@vitejs/plugin-legacy'
import viteCompression from 'vite-plugin-compression';
import { ElementPlusResolver, NaiveUiResolver, VantResolver } from 'unplugin-vue-components/resolvers';
import styleImport, { createStyleImportPlugin,ElementPlusResolve } from 'vite-plugin-style-import';
import AutoImport from 'unplugin-auto-import/vite';
import WindiCSS from 'vite-plugin-windicss';
import ViteImages from 'vite-plugin-vue-images';
// import cesium from "vite-plugin-cesium";
import OptimizationPersist from 'vite-plugin-optimize-persist';
import PkgConfig from 'vite-plugin-package-config';
import pluginName from './src/utils/pluginName'
const pathResolve = (dir: string): string => resolve(__dirname, '.', dir);
export default ({ command, mode }: ConfigEnv): UserConfigExport => {
// 環境變量
const env = loadEnv(mode, process.cwd());
// 開發環境判斷
const isDev = mode === 'dev';
// vite插件
const plugins = [
vue({
script: {
refSugar: true, //ref轉換
},
template: {
compilerOptions: {
isCustomElement: (tag) => /^micro-app/.test(tag),
},
},
}),
html({
inject: {
// injectData: { ...env },
data: {
env: env,
},
},
minify: true,
}),
pluginName(),
// elementUi組件自動引入
Components({
resolvers: [ElementPlusResolver(), NaiveUiResolver(), VantResolver()],
dts: 'src/components.d.ts',
}),
styleImport({
resolves: [ElementPlusResolve()],
}),
// 自動引入
AutoImport({
imports: ['vue', 'vue-router', 'vuex'],
resolvers: [ElementPlusResolver()],
// 可以選擇auto-import.d.ts生成的位置,使用ts建議設置爲'src/auto-import.d.ts'
dts: 'src/auto-import.d.ts',
exclude: [/node_modules/, /\.git/, /web-metadata\.js/],
}),
WindiCSS(),
/**
* 把src/icons 下的所有svg 自動加載到body下,供組件使用
* 類似於webpack中的svg-sprite-loader
* 文檔:https://github.com/anncwb/vite-plugin-svg-icons
*/
// viteSvgIcons({
// // 指定需要緩存的圖標文件夾
// iconDirs: [resolve(process.cwd(), 'src/icons')],
// // 指定symbolId格式
// symbolId: 'icon-[name]'
// })
ViteImages({
dirs: ['src/assets/moduleImages'], // 指明圖片存放目錄
}),
PkgConfig(),
OptimizationPersist(),
];
if (!isDev) {
plugins.push(
// // 兼容插件
// legacy({
// targets: ['defaults', 'not IE 11'],
// }),
// gzip插件,打包壓縮代碼成gzip 文檔: https://github.com/anncwb/vite-plugin-compression
viteCompression(),
);
}
// https://vitejs.dev/config/
return defineConfig({
plugins,
// base: isDev || mode == "buildDev" ? "/" : "/lhzh", // 設置打包路徑
//靜態資源服務的文件夾
base: './',
publicDir: 'public',
server: {
// 設置代理,根據我們項目實際情況配置
open: false, // 設置服務啓動時是否自動打開瀏覽器
cors: true, // 允許跨域
port: 80,
hmr: { overlay: false },
host: '0.0.0.0',
proxy: {
'/api': {
target: 'http://12.12.23.4:2123/',
changeOrigin: true, // 是否跨域
secure: false,
rewrite: (path) => path.replace(/^\/api/, ''),
},
'^/socket': {
target: 'ws://12.12.23.4:2123',
changeOrigin: true,
ws: true,
rewrite: (path) => path.replace(/^\/socket/, ''),
},
},
},
resolve: {
alias: [
{ find: '@', replacement: pathResolve('src') },
// { find: '@h5', replacement: pathResolve('h5') },
// 解決警告You are running the esm-bundler build of vue-i18n. It is recommended to configure your bundler to explicitly replace feature flag globals with boolean literals to get proper tree-shaking in the final bundle.
// {
// find: "vue-i18n",
// replacement: "vue-i18n/dist/vue-i18n.cjs.js",
// },
],
},
build: {
sourcemap: false,
target: 'es2015',
outDir: env.VITE_APP_outputDir,
assetsDir: 'assets',
assetsInlineLimit: 2048,
cssCodeSplit: true,
// Terser 相對較慢,但大多數情況下構建後的文件體積更小。ESbuild 最小化混淆更快但構建後的文件相對更大。
minify: isDev ? 'esbuild' : 'terser',
terserOptions: {
compress: {
// 生產環境去除console
// drop_console: !isDev,
},
},
rollupOptions: {
input: {
main: resolve(__dirname, 'index.html'),
system: resolve(__dirname, 'system.html'),
oneScreen: resolve(__dirname, 'oneScreen.html'),
h5: resolve(__dirname, 'h5.html'),
},
},
},
css: {
preprocessorOptions: {
scss: {
additionalData: `
@import '@/assets/scss/main.scss';
@import "@/h5/styles/vw-rem/_util.scss";
@import "@/h5/styles/func.scss";
`,
},
},
},
});
};
組件中使用
<template>
<div>
</div>
</template>
<script name='xm' lang="ts" setup>
import { ref, reactive } from 'vue'
const props = defineProps({
data:{
type:Array,
default:[]
}
})
</script>