damianstasik / vue-svg-loader

🔨 webpack loader that lets you use SVG files as Vue components
https://vue-svg-loader.js.org
MIT License
645 stars 86 forks source link

Why is babel required? #126

Closed Tofandel closed 4 years ago

Tofandel commented 4 years ago

I believe importing an svg that is just an xml template doesn't require any logic in the component

So why is there? The svgToVue dependency uses a spread operator and there is some logic in the generated vue component that doesn't work without babel

Wouldn't it be so much easier on everyone if the component was just a functional component without even a script?

Eg: entire vue file

<template functional>
  <svg v-bind="data.attrs" :class="data.staticClass" :style="data.staticStyle" version="1.1" viewBox="0 0 151 21" xmlns="http://www.w3.org/2000/svg">
    <circle cx="100" cy="17" r="4.5" fill="#ee2a7b"/>
  </svg>
</template>

It achieves exactly what this loader tries to do in the render function but so much simpler

So it might be worth documenting that we can get a simple result with the default vue loader. Or to integrate this solution into svg-to-vue to avoid the need for babel, see https://github.com/visualfanatic/svg-to-vue/pull/28 for what it would look like, which would give you 100% the same output but defers the logic to vue-template-compiler which is already a dependency

vue cli config

chainWebpack: (config) => {
    const svgRule = config.module.rule('svg');

    svgRule.uses.clear();

    const compiler = { ...require('vue-template-compiler') };
    const parse = compiler.parseComponent;
    compiler.parseComponent = (file, options) => {
      return parse('<template functional>' + file.replace('<svg', '<svg v-bind="data.attrs" :class="data.staticClass" :style="data.staticStyle"') + '</template>', options);
    };
    svgRule
      .oneOf('inline').set('resourceQuery', /inline/)
      .use('file-loader')
      .loader('file-loader')
      .end().end()
      .oneOf('default')
      .use('vue-loader')
      .loader('vue-loader')
      .options({
        compiler,
      })
      .end();
}

webpack config

const compiler = { ...require('vue-template-compiler') };
const parse = compiler.parseComponent;
compiler.parseComponent = (file, options) => {
  return parse('<template functional>' + file.replace('<svg', '<svg v-bind="data.attrs" :class="data.staticClass" :style="data.staticStyle"') + '</template>', options);
};

module.exports = {
  module: {
    rules: [
      /* config.module.rule('svg') */
      {
        test: /\.(svg)(\?.*)?$/,
        oneOf: [
          /* config.module.rule('svg').rule('inline') */
          {
            resourceQuery: /inline/,
            use: [
              {
                loader: 'file-loader',
              },
            ],
          },
          /* config.module.rule('svg').rule('default') */
          {
            use: [
              {
                loader: 'vue-loader',
                options: {
                  compiler,
                },
              },
            ],
          },
        ],
      },

    ],
  },
};
wesgro commented 4 years ago

Big plus 1 to this

damianstasik commented 4 years ago

babel-loader is no longer needed in the latest beta version 💪