登峰造极境

  • WIN
    • CSharp
    • JAVA
    • OAM
    • DirectX
    • Emgucv
  • UNIX
    • FFmpeg
    • QT
    • Python
    • Opencv
    • Openwrt
    • Twisted
    • Design Patterns
    • Mysql
    • Mycat
    • MariaDB
    • Make
    • OAM
    • Supervisor
    • Nginx
    • KVM
    • Docker
    • OpenStack
  • WEB
    • ASP
    • Node.js
    • PHP
    • Directadmin
    • Openssl
    • Regex
  • APP
    • Android
  • AI
    • Algorithm
    • Deep Learning
    • Machine Learning
  • IOT
    • Device
    • MSP430
  • DIY
    • Algorithm
    • Design Patterns
    • MATH
    • X98 AIR 3G
    • Tucao
    • fun
  • LIFE
    • 美食
    • 关于我
  • LINKS
  • ME
Claves
长风破浪会有时,直挂云帆济沧海
  1. 首页
  2. Programming
  3. Vue
  4. 正文

vue3-vite-组件动态编译

2022-08-07

想做一个vite svg loader插件来着,转了一圈发现已经有现成的了,看了下代码,主要是动态编译组件的技术。

svgicon/index.js

import { compileTemplate } from '@vue/compiler-sfc';
import { readFileSync } from 'fs';
import SVGO from 'svgo';

async function compileSvg(source, id) {
  let { code } = compileTemplate({
    id,
    source,
    transformAssetUrls: false,
  });

  code = code.replace('export function render', 'function render');
  code += `\nexport default { render };`;

  return code;
}

async function optimizeSvg(svgo, content, path) {
  const { data } = await svgo.optimize(content, {
    path,
  });

  return data;
}

export default (options = {}) => {
  const { svgoConfig, defaultExport = 'url' } = options;
  const svgo = new SVGO(svgoConfig);
  const cache = new Map();
  const svgRegex = /\.svg(?:\?(component|url))?$/

  return {
    name: 'vue-svg',
    async transform(source, id, isBuild) {
      const result = id.match(svgRegex);

      if (result) {
        const type = result[1];

        if ((defaultExport === 'url' && typeof type === 'undefined') || type === 'url') {
          return source;
        }

        if ((defaultExport === 'component' && typeof type === 'undefined') || type === 'component') {
          const idWithoutQuery = id.replace('.svg?component', '.svg')
          let result = cache.get(idWithoutQuery);

          if (!result) {
            const code = readFileSync(idWithoutQuery);

            const svg = await optimizeSvg(svgo, code, idWithoutQuery);

            result = await compileSvg(svg, idWithoutQuery);

            if (isBuild) {
              cache.set(idWithoutQuery, result);
            }
          }

          return result;
        }
      }
    }
  }
}

用法:

vite.config.j注册:

const vueSvgPlugin = require('./src/components/SvgIcon/index').default;
plugins: [vue(),
    vueSvgPlugin()]

views使用:

import MyIcon from './assets/icons/svg/user.svg?component';
<MyIcon/>
标签: 暂无
最后更新:2022-08-07

代号山岳

知之为知之 不知为不知

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2099 登峰造极境. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备14031139号-5

川公网安备51012202000587号