Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add default import config option #42

Merged
merged 4 commits into from Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Expand Up @@ -54,6 +54,18 @@ import IconComponent from './my-icon.svg?component'
// <IconComponent />
```

### Default import config
When no explicit params are provided SVGs will be imported as Vue components by default.
This can be changed using the `defaultImport` config setting,
such that SVGs without params will be imported as URLs (or raw strings) instead.

#### `vite.config.js`
```js
svgLoader({
defaultImport: 'url' // or 'raw'
})
```

### SVGO Configuration
#### `vite.config.js`
```js
Expand Down
39 changes: 39 additions & 0 deletions examples/vue/src/App-url.vue
@@ -0,0 +1,39 @@
<script setup>
// this component can only be used when defaultImport === 'url'

import { defineAsyncComponent } from 'vue'

import HelloWorld from './components/HelloWorld.vue'
import Test from './assets/test.svg?component'
import testUrl from './assets/test.svg?url'
import testRaw from './assets/test.svg?raw'

// variables are not supported in dynamic imports
// because https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars
// does not support query params
const Async = defineAsyncComponent(() => import(`./assets/circle.svg?component`))
</script>

<template>
<div id="component">
<Test class="test-svg" data-animal="bird" aria-hidden="true" />
</div>

<div id="image">
<img src="./assets/test.svg">
</div>

<div id="async">
<Async />
</div>

<div id="url">
{{ testUrl }}
</div>

<div id="raw">
{{ testRaw }}
</div>

<HelloWorld msg="Hello Vue 3 + Vite" />
</template>
2 changes: 1 addition & 1 deletion examples/vue/src/main.js
@@ -1,4 +1,4 @@
import { createApp } from 'vue'
import App from './App.vue'
import App from 'App.vue' // note: this is dynamically resolved in vite.config.js

createApp(App).mount('#app')
23 changes: 20 additions & 3 deletions examples/vue/vite.config.js
@@ -1,8 +1,25 @@
import { defineConfig } from 'vite'
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import viteSvgLoader from '../../'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), viteSvgLoader()]
export default defineConfig(({ mode }) => {
const env = { ...process.env, ...loadEnv(mode, process.cwd()) }
// define in .env:
// VITE_SVG_DEFAULT_IMPORT=url
// or as npm param:
// npm --svg_default_import=url run build
const DEFAULT_IMPORT = env.VITE_SVG_DEFAULT_IMPORT || env.npm_config_svg_default_import

return {
plugins: [vue(), viteSvgLoader({ defaultImport: DEFAULT_IMPORT })],

resolve: {
alias: {
// dynamically change App component based on the default import
'App.vue': DEFAULT_IMPORT === 'url' ? './App-url.vue' : './App.vue'
}
}

}
})
2 changes: 1 addition & 1 deletion index.d.ts
@@ -1,7 +1,7 @@
declare module 'vite-svg-loader' {
import { Plugin } from 'vite'
import { OptimizeOptions } from 'svgo'
function svgLoader(options?: { svgoConfig?: OptimizeOptions, svgo?: boolean }): Plugin
function svgLoader(options?: { svgoConfig?: OptimizeOptions, svgo?: boolean, defaultImport?: 'url' | 'raw' | 'component' }): Plugin
export default svgLoader
}

Expand Down
16 changes: 8 additions & 8 deletions index.js
Expand Up @@ -3,30 +3,30 @@ const { compileTemplate } = require('@vue/compiler-sfc')
const { optimize: optimizeSvg } = require('svgo')

module.exports = function svgLoader (options = {}) {
const { svgoConfig, svgo } = options
const { svgoConfig, svgo, defaultImport } = options

const svgRegex = /\.svg(\?(raw|component))?$/

return {
name: 'svg-loader',
enforce: 'pre',

resolveid (id) {
if (id.match(svgRegex)) {
return id
}
},

async load (id) {
if (!id.match(svgRegex)) {
return
}

const [path, query] = id.split('?', 2)

const importType = query || defaultImport

if (importType === 'url') {
return // Use default svg loader
}

let svg = await fs.readFile(path, 'utf-8')

if (query === 'raw') {
if (importType === 'raw') {
return `export default ${JSON.stringify(svg)}`
}

Expand Down