diff --git a/lib/codegen/customBlocks.js b/lib/codegen/customBlocks.js index 593a2e221..64e78a16e 100644 --- a/lib/codegen/customBlocks.js +++ b/lib/codegen/customBlocks.js @@ -4,13 +4,15 @@ const { attrsToQuery } = require('./utils') module.exports = function genCustomBlocksCode ( blocks, resourcePath, + resourceQuery, stringifyRequest ) { return `\n/* custom blocks */\n` + blocks.map((block, i) => { const src = block.attrs.src || resourcePath const attrsQuery = attrsToQuery(block.attrs) const issuerQuery = block.attrs.src ? `&issuerPath=${qs.escape(resourcePath)}` : '' - const query = `?vue&type=custom&index=${i}&blockType=${qs.escape(block.type)}${issuerQuery}${attrsQuery}` + const inheritQuery = resourceQuery ? `&${resourceQuery.slice(1)}` : '' + const query = `?vue&type=custom&index=${i}&blockType=${qs.escape(block.type)}${issuerQuery}${attrsQuery}${inheritQuery}` return ( `import block${i} from ${stringifyRequest(src + query)}\n` + `if (typeof block${i} === 'function') block${i}(component)` diff --git a/lib/codegen/styleInjection.js b/lib/codegen/styleInjection.js index ac8b010d5..b11e488a2 100644 --- a/lib/codegen/styleInjection.js +++ b/lib/codegen/styleInjection.js @@ -20,10 +20,11 @@ module.exports = function genStyleInjectionCode ( function genStyleRequest (style, i) { const src = style.src || resourcePath const attrsQuery = attrsToQuery(style.attrs, 'css') + const inheritQuery = `&${loaderContext.resourceQuery.slice(1)}` // 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 idQuery = style.scoped ? `&id=${id}` : `` - const query = `?vue&type=style&index=${i}${idQuery}${attrsQuery}` + const query = `?vue&type=style&index=${i}${idQuery}${attrsQuery}${inheritQuery}` return stringifyRequest(src + query) } diff --git a/lib/index.js b/lib/index.js index 6225a2aa7..f631baef5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -34,7 +34,9 @@ module.exports = function (source) { resourceQuery } = loaderContext - const incomingQuery = qs.parse(resourceQuery.slice(1)) + const rawQuery = resourceQuery.slice(1) + const inheritQuery = `&${rawQuery}` + const incomingQuery = qs.parse(rawQuery) const options = loaderUtils.getOptions(loaderContext) || {} const isServer = target === 'node' @@ -61,7 +63,9 @@ module.exports = function (source) { // module id for scoped CSS & hot-reload const shortFilePath = path .relative(context, resourcePath) - .replace(/^(\.\.[\\\/])+/, '') + .replace(/^(\.\.[\\\/])+/, '') + + resourceQuery + const id = hash( isProduction ? (shortFilePath + '\n' + source) @@ -86,7 +90,7 @@ module.exports = function (source) { const idQuery = `&id=${id}` const scopedQuery = hasScoped ? `&scoped=true` : `` const attrsQuery = attrsToQuery(descriptor.template.attrs) - const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}` + const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}${inheritQuery}` const request = templateRequest = stringifyRequest(src + query) templateImport = `import { render, staticRenderFns } from ${request}` } @@ -96,7 +100,7 @@ module.exports = function (source) { if (descriptor.script) { const src = descriptor.script.src || resourcePath const attrsQuery = attrsToQuery(descriptor.script.attrs, 'js') - const query = `?vue&type=script${attrsQuery}` + const query = `?vue&type=script${attrsQuery}${inheritQuery}` const request = stringifyRequest(src + query) scriptImport = ( `import script from ${request}\n` + @@ -141,6 +145,7 @@ var component = normalizer( code += genCustomBlocksCode( descriptor.customBlocks, resourcePath, + resourceQuery, stringifyRequest ) } diff --git a/test/advanced.spec.js b/test/advanced.spec.js index 50c804655..d6fc9b6c0 100644 --- a/test/advanced.spec.js +++ b/test/advanced.spec.js @@ -28,6 +28,24 @@ test('support chaining with other loaders', done => { }) }) +test('inherit queries on files', done => { + mockBundleAndRun({ + entry: 'basic.vue?change', + modify: config => { + config.module.rules[0] = { + test: /\.vue$/, + use: [ + 'vue-loader', + require.resolve('./mock-loaders/query') + ] + } + } + }, ({ module }) => { + expect(module.data().msg).toBe('Changed!') + done() + }) +}) + test('expose filename', done => { mockBundleAndRun({ entry: 'basic.vue' diff --git a/test/mock-loaders/query.js b/test/mock-loaders/query.js new file mode 100644 index 000000000..0a2ff8727 --- /dev/null +++ b/test/mock-loaders/query.js @@ -0,0 +1,22 @@ +module.exports = function (content) { + const query = this.resourceQuery.slice(1) + + if (/change/.test(query)) { + return ` + <template> + <div>Changed!</div> + </template> + <script> + export default { + data () { + return { + msg: 'Changed!' + } + } + } + </script> + ` + } + + return content +} diff --git a/test/utils.js b/test/utils.js index d14eba7ee..71a6310ca 100644 --- a/test/utils.js +++ b/test/utils.js @@ -57,7 +57,7 @@ function bundle (options, cb, wontThrowError) { config.module.rules[vueIndex] = Object.assign({}, vueRule, { options: vueOptions }) } - if (/\.vue$/.test(config.entry)) { + if (/\.vue/.test(config.entry)) { const vueFile = config.entry config = merge(config, { entry: require.resolve('./fixtures/entry'),