Skip to content

Commit

Permalink
feat: expose all block attrs via query
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Mar 21, 2018
1 parent 6b73b74 commit cda1ec3
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 36 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,15 @@ The good news is that you can now configure `localIdentName` in one place:
}
```

If you only want to use CSS Modules in some of your Vue components, you can use a `oneOf` rule and check for the `cssModules` string in resourceQuery:
If you only want to use CSS Modules in some of your Vue components, you can use a `oneOf` rule and check for the `module` string in resourceQuery:

``` js
{
test: /\.css$/,
oneOf: [
// this matches <style module>
{
resourceQuery: /cssModules/,
resourceQuery: /module/,
use: [
'vue-style-loader',
{
Expand Down
11 changes: 10 additions & 1 deletion lib/customBlocks.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
module.exports = function genCustomBlocksCode () {
// const { attrsToQuery } = require('./utils')

module.exports = function genCustomBlocksCode (
blocks,
resourcePath
) {
// blocks.map((block, i) => {
// const src = block.src || resourcePath
// const langQuery = getLangQuery(block)

// })
}
36 changes: 14 additions & 22 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ const qs = require('querystring')
const plugin = require('./plugin')
const selectBlock = require('./select')
const loaderUtils = require('loader-utils')
const { attrsToQuery } = require('./utils')
const genStylesCode = require('./styles')
const { genHotReloadCode } = require('./hotReload')
const genStyleInjectionCode = require('./styleInjection')
const genCustomBlocksCode = require('./customBlocks')
const componentNormalizerPath = require.resolve('./runtime/componentNormalizer')

module.exports = function (source) {
Expand Down Expand Up @@ -59,9 +61,7 @@ module.exports = function (source) {

// feature information
const hasScoped = descriptor.styles.some(s => s.scoped)
const templateAttrs = (descriptor.template && descriptor.template.attrs) || {}
const hasFunctional = templateAttrs.functional
const hasComment = templateAttrs.comments
const hasFunctional = descriptor.template && descriptor.template.attrs.functional
const needsHotReload = (
!isServer &&
!isProduction &&
Expand All @@ -73,12 +73,10 @@ module.exports = function (source) {
let templateImport = `var render, staticRenderFns`
if (descriptor.template) {
const src = descriptor.template.src || resourcePath
const langQuery = getLangQuery(descriptor.template)
const idQuery = `&id=${id}`
const scopedQuery = hasScoped ? `&scoped` : ``
const fnQuery = hasFunctional ? `&functional` : ``
const commentQuery = hasComment ? `&comment` : ``
const query = `?vue&type=template${scopedQuery}${idQuery}${langQuery}${fnQuery}${commentQuery}`
const scopedQuery = hasScoped ? `&scoped=true` : ``
const attrsQuery = attrsToQuery(descriptor.template.attrs)
const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}`
const request = stringifyRequest(src + query)
templateImport = `import { render, staticRenderFns } from ${request}`
}
Expand All @@ -87,8 +85,8 @@ module.exports = function (source) {
let scriptImport = `var script = {}`
if (descriptor.script) {
const src = descriptor.script.src || resourcePath
const langQuery = getLangQuery(descriptor.script, 'js')
const query = `?vue&type=script${langQuery}`
const attrsQuery = attrsToQuery(descriptor.script.attrs, 'js')
const query = `?vue&type=script${attrsQuery}`
const request = stringifyRequest(src + query)
scriptImport = (
`import script from ${request}\n` +
Expand All @@ -97,15 +95,14 @@ module.exports = function (source) {
}

// styles
let styleInjectionCode = ``
let stylesCode = ``
if (descriptor.styles.length) {
styleInjectionCode = genStyleInjectionCode(
stylesCode = genStylesCode(
loaderContext,
descriptor.styles,
id,
resourcePath,
stringifyRequest,
getLangQuery,
needsHotReload,
isServer || isShadow // needs explicit injection?
)
Expand All @@ -114,22 +111,22 @@ module.exports = function (source) {
let code = `
${templateImport}
${scriptImport}
${styleInjectionCode}
${stylesCode}
import normalizer from ${stringifyRequest(`!${componentNormalizerPath}`)}
var component = normalizer(
script,
render,
staticRenderFns,
${hasFunctional ? `true` : `false`},
${/injectStyles/.test(styleInjectionCode) ? `injectStyles` : `null`},
${/injectStyles/.test(stylesCode) ? `injectStyles` : `null`},
${hasScoped ? JSON.stringify(id) : `null`},
${isServer ? JSON.stringify(hash(request)) : `null`}
${isShadow ? `,true` : ``}
)
`.trim()

if (descriptor.customBlocks && descriptor.customBlocks.length) {
// TODO custom blocks
code += genCustomBlocksCode(descriptor.customBlocks)
}

// Expose filename. This is used by the devtools and vue runtime warnings.
Expand All @@ -146,9 +143,4 @@ var component = normalizer(
return code
}

function getLangQuery (block, fallback) {
const lang = block.lang || fallback
return lang ? `&lang=${lang}` : ``
}

module.exports.VueLoaderPlugin = plugin
2 changes: 1 addition & 1 deletion lib/style-post-loader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = function (source, map) {
const id = `data-v-${query.id}`
const plugins = [trim()]

if (query.scoped != null) {
if (query.scoped) {
plugins.push(scoped({ id }))
}

Expand Down
9 changes: 4 additions & 5 deletions lib/styleInjection.js → lib/styles.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { attrsToQuery } = require('./utils')
const hotReloadAPIPath = require.resolve('vue-hot-reload-api')

module.exports = function genStyleInjectionCode (
Expand All @@ -6,7 +7,6 @@ module.exports = function genStyleInjectionCode (
id,
resourcePath,
stringifyRequest,
getLangQuery,
needsHotReload,
needsExplicitInjection
) {
Expand All @@ -19,12 +19,11 @@ module.exports = function genStyleInjectionCode (

function genStyleRequest (style, i) {
const src = style.src || resourcePath
const langQuery = getLangQuery(style, 'css')
const attrsQuery = attrsToQuery(style.attrs, '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 moduleQuery = style.module ? `&cssModules` : ``
const query = `?vue&type=style&index=${i}${langQuery}${scopedQuery}${moduleQuery}`
const idQuery = style.scoped ? `&id=${id}` : ``
const query = `?vue&type=style&index=${i}${idQuery}${attrsQuery}`
return stringifyRequest(src + query)
}

Expand Down
7 changes: 3 additions & 4 deletions lib/template-loader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,14 @@ function actuallyCompile (sourceTemplate, options, loaderContext, query) {
const isProduction = loaderContext.minimize || process.env.NODE_ENV === 'production'
const needsHotReload = !isServer && !isProduction && options.hotReload !== false
const defaultModules = [transformAssetUrl(options.transformAssetUrl), transformSrcset()]
const hasComment = query.comment != null
const hasFunctionalTemplate = query.functional != null
const hasFunctionalTemplate = query.functional

const userCompilerOptions = options.compilerOptions || {}

const compilerOptions = Object.assign({}, userCompilerOptions, {
scopeId: query.scoped != null ? `data-v-${id}` : null,
scopeId: query.scoped ? `data-v-${id}` : null,
modules: defaultModules.concat(userCompilerOptions.modules || []),
comments: hasComment
comments: query.comments
})

// support user compiler
Expand Down
15 changes: 15 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const qs = require('querystring')

exports.attrsToQuery = (attrs, langFallback) => {
let query = ``
for (const name in attrs) {
const value = attrs[name]
if (name !== 'src') {
query += `&${qs.escape(name)}=${value ? qs.escape(value) : ``}`
}
}
if (langFallback && !(`lang` in attrs)) {
query += `&lang=${langFallback}`
}
return query
}
2 changes: 1 addition & 1 deletion test/advanced.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ test('support rules with oneOf', async () => {
use: 'vue-style-loader',
oneOf: [
{
resourceQuery: /cssModules/,
resourceQuery: /module/,
use: [
{
loader: 'css-loader',
Expand Down

0 comments on commit cda1ec3

Please sign in to comment.