Commit 542aacca authored by Evan You's avatar Evan You

test: ssr + scoped CSS

parent 5d0c4f7b
...@@ -75,9 +75,10 @@ module.exports = function (source) { ...@@ -75,9 +75,10 @@ module.exports = function (source) {
const src = descriptor.template.src || resourcePath const src = descriptor.template.src || resourcePath
const langQuery = getLangQuery(descriptor.template) const langQuery = getLangQuery(descriptor.template)
const idQuery = `&id=${id}` const idQuery = `&id=${id}`
const scopedQuery = hasScoped ? `&scoped` : ``
const fnQuery = hasFunctional ? `&functional` : `` const fnQuery = hasFunctional ? `&functional` : ``
const commentQuery = hasComment ? `&comment` : `` const commentQuery = hasComment ? `&comment` : ``
const query = `?vue&type=template${idQuery}${langQuery}${fnQuery}${commentQuery}` const query = `?vue&type=template${scopedQuery}${idQuery}${langQuery}${fnQuery}${commentQuery}`
const request = stringifyRequest(src + query) const request = stringifyRequest(src + query)
templateImport = `import { render, staticRenderFns } from ${request}` templateImport = `import { render, staticRenderFns } from ${request}`
} }
......
...@@ -20,6 +20,8 @@ module.exports = function genStyleInjectionCode ( ...@@ -20,6 +20,8 @@ module.exports = function genStyleInjectionCode (
function genStyleRequest (style, i) { function genStyleRequest (style, i) {
const src = style.src || resourcePath const src = style.src || resourcePath
const langQuery = getLangQuery(style, 'css') const langQuery = getLangQuery(style, 'css')
// make sure to only pass id when necessary so that we don't inject
// duplicate tags when multiple components import the same css file
const scopedQuery = style.scoped ? `&scoped&id=${id}` : `` const scopedQuery = style.scoped ? `&scoped&id=${id}` : ``
const query = `?vue&type=style&index=${i}${langQuery}${scopedQuery}` const query = `?vue&type=style&index=${i}${langQuery}${scopedQuery}`
return stringifyRequest(src + query) return stringifyRequest(src + query)
......
...@@ -80,10 +80,10 @@ function actuallyCompile (sourceTemplate, options, loaderContext, query) { ...@@ -80,10 +80,10 @@ function actuallyCompile (sourceTemplate, options, loaderContext, query) {
} = options.compilerOptions || {} } = options.compilerOptions || {}
const compilerOptions = { const compilerOptions = {
scopeId: query.scoped != null ? `data-v-${id}` : null,
preserveWhitespace, preserveWhitespace,
modules: defaultModules.concat(modules || []), modules: defaultModules.concat(modules || []),
directives: directives || {}, directives: directives || {},
scopeId: id,
comments: hasComment comments: hasComment
} }
......
...@@ -55,3 +55,11 @@ h1 { ...@@ -55,3 +55,11 @@ h1 {
<svg><template><p></p></template></svg> <svg><template><p></p></template></svg>
</div> </div>
</template> </template>
<script>
export default {
data () {
return { ok: true }
}
}
</script>
import Vue from 'vue'
import App from './scoped-css.vue'
export default () => new Vue({
render: h => h(App)
})
const SSR = require('vue-server-renderer') const SSR = require('vue-server-renderer')
const { const {
genId,
bundle bundle
} = require('./utils') } = require('./utils')
...@@ -43,6 +44,58 @@ test('SSR style and moduleId extraction', done => { ...@@ -43,6 +44,58 @@ test('SSR style and moduleId extraction', done => {
}) })
}) })
test('SSR with scoped CSS', done => {
bundle({
target: 'node',
entry: './test/fixtures/ssr-scoped-style.js',
output: {
path: '/',
filename: 'test.build.js',
libraryTarget: 'commonjs2'
},
externals: ['vue']
}, code => {
const renderer = SSR.createBundleRenderer(code, {
basedir: __dirname,
runInNewContext: 'once'
})
const context = {
_registeredComponents: new Set()
}
renderer.renderToString(context, (err, res) => {
if (err) return done(err)
const id = `data-v-${genId('scoped-css.vue')}`
expect(res).toContain('data-server-rendered')
expect(res).toContain(`<div ${id}>`)
expect(res).toContain(`<svg ${id}>`)
const style = context.styles
expect(style).toContain(`.test[${id}] {\n color: yellow;\n}`)
expect(style).toContain(`.test[${id}]:after {\n content: \'bye!\';\n}`)
expect(style).toContain(`h1[${id}] {\n color: green;\n}`)
// scoped keyframes
expect(style).toContain(`.anim[${id}] {\n animation: color-${id} 5s infinite, other 5s;`)
expect(style).toContain(`.anim-2[${id}] {\n animation-name: color-${id}`)
expect(style).toContain(`.anim-3[${id}] {\n animation: 5s color-${id} infinite, 5s other;`)
expect(style).toContain(`@keyframes color-${id} {`)
expect(style).toContain(`@-webkit-keyframes color-${id} {`)
expect(style).toContain(
`.anim-multiple[${id}] {\n animation: color-${id} 5s infinite,opacity-${id} 2s;`
)
expect(style).toContain(`.anim-multiple-2[${id}] {\n animation-name: color-${id},opacity-${id};`)
expect(style).toContain(`@keyframes opacity-${id} {`)
expect(style).toContain(`@-webkit-keyframes opacity-${id} {`)
// >>> combinator
expect(style).toContain(`.foo p[${id}] .bar {\n color: red;\n}`)
done()
})
})
})
// TODO // TODO
// test('css-modules in SSR', done => { // test('css-modules in SSR', done => {
// bundle({ // bundle({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment