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: option to filter style tags from callback #1783

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion lib/index.d.ts
Expand Up @@ -17,7 +17,8 @@ declare namespace VueLoader {
cacheDirectory?: string
cacheIdentifier?: string
prettify?: boolean
exposeFilename?: boolean
exposeFilename?: boolean,
filterStyleTag?: (styleTagAttributes: Object) => boolean,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I typed it as an Object even though it is a ParsedUrlQuery internally (users don't need to know its real interface in my opinion, but it is poorly typed with just object).
I'm opened to types suggestions here!

}
}

Expand Down
6 changes: 5 additions & 1 deletion lib/loaders/pitcher.js
Expand Up @@ -50,7 +50,7 @@ module.exports = code => code
// and transform it into appropriate requests.
module.exports.pitch = function (remainingRequest) {
const options = loaderUtils.getOptions(this)
const { cacheDirectory, cacheIdentifier } = options
const { cacheDirectory, cacheIdentifier, filterStyleTag } = options
const query = qs.parse(this.resourceQuery.slice(1))

let loaders = this.loaders
Expand Down Expand Up @@ -110,6 +110,10 @@ module.exports.pitch = function (remainingRequest) {

// Inject style-post-loader before css-loader for scoped CSS and trimming
if (query.type === `style`) {
// If filterStyleTag function is provided, check that it's truthy for this query or ignore it
if (typeof filterStyleTag === 'function' && !filterStyleTag(query)) {
return ''
}
const cssLoaderIndex = loaders.findIndex(isCSSLoader)
if (cssLoaderIndex > -1) {
const afterLoaders = loaders.slice(0, cssLoaderIndex + 1)
Expand Down
3 changes: 2 additions & 1 deletion lib/plugin-webpack4.js
Expand Up @@ -85,7 +85,8 @@ class VueLoaderPlugin {
},
options: {
cacheDirectory: vueLoaderUse.options.cacheDirectory,
cacheIdentifier: vueLoaderUse.options.cacheIdentifier
cacheIdentifier: vueLoaderUse.options.cacheIdentifier,
filterStyleTag: vueLoaderUse.options.filterStyleTag
}
}

Expand Down
3 changes: 2 additions & 1 deletion lib/plugin-webpack5.js
Expand Up @@ -126,7 +126,8 @@ class VueLoaderPlugin {
},
options: {
cacheDirectory: vueLoaderUse.options.cacheDirectory,
cacheIdentifier: vueLoaderUse.options.cacheIdentifier
cacheIdentifier: vueLoaderUse.options.cacheIdentifier,
filterStyleTag: vueLoaderUse.options.filterStyleTag
}
}

Expand Down
35 changes: 35 additions & 0 deletions test/core.spec.js
Expand Up @@ -174,3 +174,38 @@ test('cloned rules should not intefere with each other', done => {
done()
})
})

test('ignore style tags', done => {
mockBundleAndRun({
entry: 'style-dynamic.vue',
modify: config => {
config.module.rules = [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
filterStyleTag: ({ keep }) => {
return keep
}
}
},
{
oneOf: [
{
test: /\.css$/,
use: ['vue-style-loader', 'css-loader']
}
]
}
]
}
}, ({ window, module }) => {
mockRender(module)

let style = window.document.querySelector('style').textContent
style = normalizeNewline(style)
expect(style).toContain(`h2[${module._scopeId}] {\n color: orange;\n}`)
expect(style).not.toContain(`color: cyan;`)
done()
})
})
25 changes: 25 additions & 0 deletions test/fixtures/style-dynamic.vue
@@ -0,0 +1,25 @@
<template>
<h2>{{msg}}</h2>
</template>

<script>
export default {
data () {
return {
msg: 'Hello from themed styled Component!'
}
}
}
</script>

<style scoped>
h2 {
color: cyan;
}
</style>

<style scoped keep>
h2 {
color: orange;
}
</style>