Vue3 setup 支持 name 插件實現 思路借鑑上面插件

方法一:插件 

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>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章