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

feat: use svg-to-vue-component under the hood #27

Merged
merged 10 commits into from
Jan 9, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@ module.exports = {
},
extends: [
'@nuxtjs'
]
],
rules: {
'vue/attribute-hyphenation': ['error', 'always', {
ignore: ['viewBox']
}]
}
}
35 changes: 28 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
## Features

* Full support of SVGs as components. Import them like your Vue SFCs
* Built on top of [vue-svg-loader](https://github.com/visualfanatic/vue-svg-loader)
* Use Vue bindings as you'd do it with normal components
* Built on top of [svg-to-vue-component](https://github.com/egoist/svg-to-vue-component)
* Nuxt 2 (and only Nuxt 2) support
* Fully tested!

Expand All @@ -31,7 +32,7 @@ A [live demo](https://zxr9l743l3.sse.codesandbox.io/) is available through the [
{
modules: [
'nuxt-svg-loader',
],
]
}
```

Expand Down Expand Up @@ -73,9 +74,11 @@ export default {

## Configuration

The plugin will work seamlessly out of the box. If you are in need of
configuring the loader options (eg for [id prefixing](https://vue-svg-loader.js.org/faq.html#how-to-use-both-inline-and-external-svgs)),
you can do that:
The plugin will work seamlessly out of the box.
It will also include SVGO defaults to avoid collisions between your optimized SVG files!

If you want to configure the underlying loader (or SVGO), you can do that easily as well.
(All options available [here](https://github.com/egoist/svg-to-vue-component#loader-options))

```js
// file: nuxt.config.js
Expand All @@ -84,9 +87,27 @@ export default {
// ...
// Your loader options as svgLoader object
svgLoader: {
svgo: {
svgoConfig: {
plugins: [
{ prefixIds: true },
{ prefixIds: false }, // Disables prefixing for SVG IDs
manniL marked this conversation as resolved.
Show resolved Hide resolved
]
}
}
}
```

## Migrating from 0.x

1. Update the deps (of course!)
2. Rename `svgo` to `svgoConfig`
3. If you used id prefixing manually before, you can delete the config:

```js
export default {
svgLoader: {
svgo: { //Rename to svgoConfig
plugins: [
{ prefixIds: true } // Delete that line (or the whole svgLoader object if you don't have any other configurations)
]
}
}
Expand Down
22 changes: 19 additions & 3 deletions lib/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,39 @@ const logger = require('consola').withScope('nuxt-svg-loader')

export default function nuxtSvgLoader() {
const { svgLoader: options } = this.options

if (options && options.svgo && !options.svgoConfig) {
options.svgoConfig = options.svgo
}

this.extendBuild(setupVueSvgLoader(options))
}

const svgRulePredicate = rule => rule.test && rule.test.test('.svg')

const setupVueSvgLoader = options => (config) => {
const imageLoaderRule = config.module.rules.find(rule => rule.test && /svg/.test(rule.test.toString()))
// https://github.com/egoist/svg-to-vue-component#nuxtjs-2
const imageLoaderRule = config.module.rules.find(svgRulePredicate)

if (!imageLoaderRule) {
logger.error('Could not modify image loader rule!')
return
}

// Don't process .svg files in default image rule
// from https://github.com/nuxt/nuxt.js/blob/76b10d2d3f4e5352f1c9d14c52008f234e66d7d5/lib/builder/webpack/base.js#L203
imageLoaderRule.test = /\.(png|jpe?g|gif|webp)$/

// Add a new rule for .svg file
config.module.rules.push({
test: /\.svg$/,
loader: 'vue-svg-loader',
options
use: [
'vue-loader',
{
loader: 'svg-to-vue-component/loader',
options
}
]
})
}

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
"forceExit": true
},
"dependencies": {
"consola": "^1.4.5",
"vue-svg-loader": "^0.11.0"
"consola": "^2.3.2",
"svg-to-vue-component": "^0.2.6"
},
"devDependencies": {
"@commitlint/cli": "^7.2.1",
Expand All @@ -76,7 +76,7 @@
"husky": "^1.2.0",
"jest": "^23.6.0",
"jsdom": "^13.0.0",
"nuxt-edge": "^2.3.0-25706271.cca799c",
"nuxt-edge": "^2.4.0-25783204.eef2af35",
"standard-version": "^4.4.0"
},
"husky": {
Expand Down
36 changes: 9 additions & 27 deletions test/__snapshots__/module.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@
exports[`ssr correctly register SVG loader and load SVG correctly 1`] = `
"<!doctype html>
<html data-n-head-ssr data-n-head=\\"\\">
<head>
<title data-n-head=\\"true\\"></title><style data-vue-ssr-id=\\"fd547dac:0\\">
.nuxt-progress{position:fixed;top:0;left:0;right:0;height:2px;width:0;opacity:1;transition:width .1s,opacity .4s;background-color:#000;z-index:999999
}
.nuxt-progress.nuxt-progress-notransition{transition:none
}
.nuxt-progress-failed{background-color:red
}</style>
<head data-n-head=\\"\\">
<title data-n-head=\\"true\\"></title><style data-vue-ssr-id=\\"17cfdfa9:0\\">.nuxt-progress{position:fixed;top:0;left:0;right:0;height:2px;width:0;opacity:1;transition:width .1s,opacity .4s;background-color:#000;z-index:999999}.nuxt-progress.nuxt-progress-notransition{transition:none}.nuxt-progress-failed{background-color:red}</style>
</head>
<body data-n-head=\\"\\">
<div data-server-rendered=\\"true\\" id=\\"__nuxt\\"><!----><div id=\\"__layout\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 1000 1000\\"><style></style><g id=\\"nuxt\\"><path d=\\"M317.9 852H3.7l408.1-704 408.1 704H507.7\\" fill=\\"#41b883\\"></path><path d=\\"M779.8 852h216.5l-354-608.5-351 608.5h216.5\\" fill=\\"#328170\\"></path><path d=\\"M651.2 852h159.5L549.9 403.8 291.3 852h159.5\\" fill=\\"#35495e\\"></path></g></svg></div></div><script>window.__NUXT__={layout:\\"default\\",data:[{}],error:null,serverRendered:true};</script><script src=\\"/_nuxt/runtime.js\\" defer></script><script src=\\"/_nuxt/pages/index.js\\" defer></script><script src=\\"/_nuxt/commons.app.js\\" defer></script><script src=\\"/_nuxt/app.js\\" defer></script>
<div data-server-rendered=\\"true\\" id=\\"__nuxt\\"><!----><div id=\\"__layout\\"><svg viewBox=\\"1 2 3 4\\" width=\\"100\\"><g id=\\"Nuxt_svg__nuxt\\"><path d=\\"M317.9 852H3.7l408.1-704 408.1 704H507.7\\" fill=\\"#41b883\\"></path><path d=\\"M779.8 852h216.5l-354-608.5-351 608.5h216.5\\" fill=\\"#328170\\"></path><path d=\\"M651.2 852h159.5L549.9 403.8 291.3 852h159.5\\" fill=\\"#35495e\\"></path></g></svg></div></div><script>window.__NUXT__={layout:\\"default\\",data:[{}],error:null,serverRendered:true};</script><script src=\\"/_nuxt/runtime.js\\" defer></script><script src=\\"/_nuxt/pages/index.js\\" defer></script><script src=\\"/_nuxt/commons.app.js\\" defer></script><script src=\\"/_nuxt/app.js\\" defer></script>
</body>
</html>
"
Expand All @@ -22,17 +16,11 @@ exports[`ssr correctly register SVG loader and load SVG correctly 1`] = `
exports[`ssr honor custom build.extend function 1`] = `
"<!doctype html>
<html data-n-head-ssr data-n-head=\\"\\">
<head>
<title data-n-head=\\"true\\"></title><style data-vue-ssr-id=\\"fd547dac:0\\">
.nuxt-progress{position:fixed;top:0;left:0;right:0;height:2px;width:0;opacity:1;transition:width .1s,opacity .4s;background-color:#000;z-index:999999
}
.nuxt-progress.nuxt-progress-notransition{transition:none
}
.nuxt-progress-failed{background-color:red
}</style>
<head data-n-head=\\"\\">
<title data-n-head=\\"true\\"></title><style data-vue-ssr-id=\\"17cfdfa9:0\\">.nuxt-progress{position:fixed;top:0;left:0;right:0;height:2px;width:0;opacity:1;transition:width .1s,opacity .4s;background-color:#000;z-index:999999}.nuxt-progress.nuxt-progress-notransition{transition:none}.nuxt-progress-failed{background-color:red}</style>
</head>
<body data-n-head=\\"\\">
<div data-server-rendered=\\"true\\" id=\\"__nuxt\\"><!----><div id=\\"__layout\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 1000 1000\\"><style></style><g id=\\"nuxt\\"><path d=\\"M317.9 852H3.7l408.1-704 408.1 704H507.7\\" fill=\\"#41b883\\"></path><path d=\\"M779.8 852h216.5l-354-608.5-351 608.5h216.5\\" fill=\\"#328170\\"></path><path d=\\"M651.2 852h159.5L549.9 403.8 291.3 852h159.5\\" fill=\\"#35495e\\"></path></g></svg></div></div><script>window.__NUXT__={layout:\\"default\\",data:[{}],error:null,serverRendered:true};</script><script src=\\"/_nuxt/runtime.js\\" defer></script><script src=\\"/_nuxt/pages/index.js\\" defer></script><script src=\\"/_nuxt/commons.app.js\\" defer></script><script src=\\"/_nuxt/app.js\\" defer></script>
<div data-server-rendered=\\"true\\" id=\\"__nuxt\\"><!----><div id=\\"__layout\\"><svg viewBox=\\"1 2 3 4\\" width=\\"100\\"><g id=\\"Nuxt_svg__nuxt\\"><path d=\\"M317.9 852H3.7l408.1-704 408.1 704H507.7\\" fill=\\"#41b883\\"></path><path d=\\"M779.8 852h216.5l-354-608.5-351 608.5h216.5\\" fill=\\"#328170\\"></path><path d=\\"M651.2 852h159.5L549.9 403.8 291.3 852h159.5\\" fill=\\"#35495e\\"></path></g></svg></div></div><script>window.__NUXT__={layout:\\"default\\",data:[{}],error:null,serverRendered:true};</script><script src=\\"/_nuxt/runtime.js\\" defer></script><script src=\\"/_nuxt/pages/index.js\\" defer></script><script src=\\"/_nuxt/commons.app.js\\" defer></script><script src=\\"/_nuxt/app.js\\" defer></script>
</body>
</html>
"
Expand All @@ -41,17 +29,11 @@ exports[`ssr honor custom build.extend function 1`] = `
exports[`ssr honor custom loader options 1`] = `
"<!doctype html>
<html data-n-head-ssr data-n-head=\\"\\">
<head>
<title data-n-head=\\"true\\"></title><style data-vue-ssr-id=\\"fd547dac:0\\">
.nuxt-progress{position:fixed;top:0;left:0;right:0;height:2px;width:0;opacity:1;transition:width .1s,opacity .4s;background-color:#000;z-index:999999
}
.nuxt-progress.nuxt-progress-notransition{transition:none
}
.nuxt-progress-failed{background-color:red
}</style>
<head data-n-head=\\"\\">
<title data-n-head=\\"true\\"></title><style data-vue-ssr-id=\\"17cfdfa9:0\\">.nuxt-progress{position:fixed;top:0;left:0;right:0;height:2px;width:0;opacity:1;transition:width .1s,opacity .4s;background-color:#000;z-index:999999}.nuxt-progress.nuxt-progress-notransition{transition:none}.nuxt-progress-failed{background-color:red}</style>
</head>
<body data-n-head=\\"\\">
<div data-server-rendered=\\"true\\" id=\\"__nuxt\\"><!----><div id=\\"__layout\\"><svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 1000 1000\\"><style></style><g id=\\"Nuxt_svg__nuxt\\"><path d=\\"M317.9 852H3.7l408.1-704 408.1 704H507.7\\" fill=\\"#41b883\\"></path><path d=\\"M779.8 852h216.5l-354-608.5-351 608.5h216.5\\" fill=\\"#328170\\"></path><path d=\\"M651.2 852h159.5L549.9 403.8 291.3 852h159.5\\" fill=\\"#35495e\\"></path></g></svg></div></div><script>window.__NUXT__={layout:\\"default\\",data:[{}],error:null,serverRendered:true};</script><script src=\\"/_nuxt/runtime.js\\" defer></script><script src=\\"/_nuxt/pages/index.js\\" defer></script><script src=\\"/_nuxt/commons.app.js\\" defer></script><script src=\\"/_nuxt/app.js\\" defer></script>
<div data-server-rendered=\\"true\\" id=\\"__nuxt\\"><!----><div id=\\"__layout\\"><svg viewBox=\\"1 2 3 4\\" width=\\"100\\"><g id=\\"nuxt\\"><path d=\\"M317.9 852H3.7l408.1-704 408.1 704H507.7\\" fill=\\"#41b883\\"></path><path d=\\"M779.8 852h216.5l-354-608.5-351 608.5h216.5\\" fill=\\"#328170\\"></path><path d=\\"M651.2 852h159.5L549.9 403.8 291.3 852h159.5\\" fill=\\"#35495e\\"></path></g></svg></div></div><script>window.__NUXT__={layout:\\"default\\",data:[{}],error:null,serverRendered:true};</script><script src=\\"/_nuxt/runtime.js\\" defer></script><script src=\\"/_nuxt/pages/index.js\\" defer></script><script src=\\"/_nuxt/commons.app.js\\" defer></script><script src=\\"/_nuxt/app.js\\" defer></script>
</body>
</html>
"
Expand Down
1 change: 1 addition & 0 deletions test/fixture/configs/error-without-image-loader-rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
},
modules: ['@@', '@/modules/error'],
build: {
quiet: false,
filenames: {
app: '[name].js',
chunk: '[name].js'
Expand Down
1 change: 1 addition & 0 deletions test/fixture/configs/with-extend-fn.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = {
},
modules: ['@@'],
build: {
quiet: false,
filenames: {
app: '[name].js',
chunk: '[name].js'
Expand Down
2 changes: 1 addition & 1 deletion test/fixture/configs/with-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = {
svgLoader: {
svgo: {
plugins: [
{ prefixIds: true }
{ prefixIds: false }
]
}
},
Expand Down
5 changes: 3 additions & 2 deletions test/fixture/modules/error.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = function () {
this.extendBuild((config, options) => {
const imageLoaderRule = config.module.rules.find(rule => rule.test && /svg/.test(rule.test.toString()))
const svgRulePredicate = rule => rule.test && rule.test.test('.svg')
this.extendBuild((config) => {
const imageLoaderRule = config.module.rules.find(svgRulePredicate)
imageLoaderRule.test = /^$/
})
}
2 changes: 1 addition & 1 deletion test/fixture/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<nuxt-logo/>
<nuxt-logo viewBox="1 2 3 4" width="100" />
</template>

<script>
Expand Down
9 changes: 3 additions & 6 deletions test/module.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@ jest.setTimeout(60 * 1000)
let nuxt, port

describe('ssr', () => {
let log

beforeEach(() => {
log = jest.fn()
consola.clear().add({ log })
consola.mockTypes(() => jest.fn())
})

test('emit error when loader can\'t be registered', async () => {
try {
await setupNuxt(require('./fixture/configs/error-without-image-loader-rule'))
} catch (e) {
expect(e).toBe('Nuxt Build Error')
expect(e.message).toBe('Nuxt Build Error')
return
}
Error('Never reach this state')
Expand All @@ -34,7 +31,7 @@ describe('ssr', () => {
nuxt = await setupNuxt(require('./fixture/configs/with-extend-fn'))

const messageInExtendFunction = 'Build fn'
const consolaMessages = log.mock.calls.map(c => c[0].message)
const consolaMessages = consola.fatal.mock.calls.map(c => c[0])
expect(consolaMessages).toContain(messageInExtendFunction)

const { html } = await nuxt.renderRoute('/')
Expand Down
Loading