vue-loader
Advanced tools
Comparing version 15.9.8 to 15.10.0-beta.1
@@ -0,1 +1,12 @@ | ||
<a name="15.10.0-beta.1"></a> | ||
# [15.10.0-beta.1](https://github.com/vuejs/vue-loader/compare/v15.9.8...v15.10.0-beta.1) (2022-06-14) | ||
### Features | ||
* apply js loaders to compiled template code when used with 2.7 ([30464a8](https://github.com/vuejs/vue-loader/commit/30464a8)) | ||
* compat for vue 2.7, support `<script setup>` ([308715a](https://github.com/vuejs/vue-loader/commit/308715a)) | ||
<a name="15.9.8"></a> | ||
@@ -11,2 +22,12 @@ ## [15.9.8](https://github.com/vuejs/vue-loader/compare/v15.9.7...v15.9.8) (2021-08-02) | ||
<a name="15.9.8"></a> | ||
## [15.9.8](https://github.com/vuejs/vue-loader/compare/v15.9.7...v15.9.8) (2021-08-02) | ||
### Bug Fixes | ||
* fix webpack 5.48 compatibility ([c4c5f17](https://github.com/vuejs/vue-loader/commit/c4c5f17)), closes [#1859](https://github.com/vuejs/vue-loader/issues/1859) | ||
<a name="15.9.7"></a> | ||
@@ -13,0 +34,0 @@ ## [15.9.7](https://github.com/vuejs/vue-loader/compare/v15.9.6...v15.9.7) (2021-05-11) |
@@ -8,3 +8,2 @@ const path = require('path') | ||
const { attrsToQuery } = require('./codegen/utils') | ||
const { parse } = require('@vue/component-compiler-utils') | ||
const genStylesCode = require('./codegen/styleInjection') | ||
@@ -15,20 +14,6 @@ const { genHotReloadCode } = require('./codegen/hotReload') | ||
const { NS } = require('./plugin') | ||
const { resolveCompiler } = require('./compiler') | ||
let errorEmitted = false | ||
function loadTemplateCompiler (loaderContext) { | ||
try { | ||
return require('vue-template-compiler') | ||
} catch (e) { | ||
if (/version mismatch/.test(e.toString())) { | ||
loaderContext.emitError(e) | ||
} else { | ||
loaderContext.emitError(new Error( | ||
`[vue-loader] vue-template-compiler must be installed as a peer dependency, ` + | ||
`or a compatible compiler implementation must be passed via options.` | ||
)) | ||
} | ||
} | ||
} | ||
module.exports = function (source) { | ||
@@ -38,6 +23,8 @@ const loaderContext = this | ||
if (!errorEmitted && !loaderContext['thread-loader'] && !loaderContext[NS]) { | ||
loaderContext.emitError(new Error( | ||
`vue-loader was used without the corresponding plugin. ` + | ||
`Make sure to include VueLoaderPlugin in your webpack config.` | ||
)) | ||
loaderContext.emitError( | ||
new Error( | ||
`vue-loader was used without the corresponding plugin. ` + | ||
`Make sure to include VueLoaderPlugin in your webpack config.` | ||
) | ||
) | ||
errorEmitted = true | ||
@@ -65,3 +52,4 @@ } | ||
const isShadow = !!options.shadowMode | ||
const isProduction = options.productionMode || minimize || process.env.NODE_ENV === 'production' | ||
const isProduction = | ||
options.productionMode || minimize || process.env.NODE_ENV === 'production' | ||
const filename = path.basename(resourcePath) | ||
@@ -71,5 +59,10 @@ const context = rootContext || process.cwd() | ||
const descriptor = parse({ | ||
const { compiler, templateCompiler } = resolveCompiler( | ||
rootContext, | ||
loaderContext | ||
) | ||
const descriptor = compiler.parse({ | ||
source, | ||
compiler: options.compiler || loadTemplateCompiler(loaderContext), | ||
compiler: options.compiler || templateCompiler, | ||
filename, | ||
@@ -86,2 +79,3 @@ sourceRoot, | ||
descriptor, | ||
options, | ||
loaderContext, | ||
@@ -102,3 +96,3 @@ incomingQuery, | ||
isProduction | ||
? (shortFilePath + '\n' + source.replace(/\r\n/g, '\n')) | ||
? shortFilePath + '\n' + source.replace(/\r\n/g, '\n') | ||
: shortFilePath | ||
@@ -109,10 +103,25 @@ ) | ||
const hasScoped = descriptor.styles.some(s => s.scoped) | ||
const hasFunctional = descriptor.template && descriptor.template.attrs.functional | ||
const needsHotReload = ( | ||
const hasFunctional = | ||
descriptor.template && descriptor.template.attrs.functional | ||
const needsHotReload = | ||
!isServer && | ||
!isProduction && | ||
(descriptor.script || descriptor.template) && | ||
(descriptor.script || descriptor.scriptSetup || descriptor.template) && | ||
options.hotReload !== false | ||
) | ||
// script | ||
let scriptImport = `var script = {}` | ||
// let isTS = false | ||
const { script, scriptSetup } = descriptor | ||
if (script || scriptSetup) { | ||
// const lang = script?.lang || scriptSetup?.lang | ||
// isTS = !!(lang && /tsx?/.test(lang)) | ||
const src = (script && !scriptSetup && script.src) || resourcePath | ||
const attrsQuery = attrsToQuery((scriptSetup || script).attrs, 'js') | ||
const query = `?vue&type=script${attrsQuery}${inheritQuery}` | ||
const request = stringifyRequest(src + query) | ||
scriptImport = | ||
`import script from ${request}\n` + `export * from ${request}` // support named exports | ||
} | ||
// template | ||
@@ -126,20 +135,9 @@ let templateImport = `var render, staticRenderFns` | ||
const attrsQuery = attrsToQuery(descriptor.template.attrs) | ||
// const tsQuery = | ||
// options.enableTsInTemplate !== false && isTS ? `&ts=true` : `` | ||
const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}${inheritQuery}` | ||
const request = templateRequest = stringifyRequest(src + query) | ||
const request = (templateRequest = stringifyRequest(src + query)) | ||
templateImport = `import { render, staticRenderFns } from ${request}` | ||
} | ||
// script | ||
let scriptImport = `var script = {}` | ||
if (descriptor.script) { | ||
const src = descriptor.script.src || resourcePath | ||
const attrsQuery = attrsToQuery(descriptor.script.attrs, 'js') | ||
const query = `?vue&type=script${attrsQuery}${inheritQuery}` | ||
const request = stringifyRequest(src + query) | ||
scriptImport = ( | ||
`import script from ${request}\n` + | ||
`export * from ${request}` // support named exports | ||
) | ||
} | ||
// styles | ||
@@ -159,3 +157,4 @@ let stylesCode = `` | ||
let code = ` | ||
let code = | ||
` | ||
${templateImport} | ||
@@ -196,3 +195,5 @@ ${scriptImport} | ||
// from the devtools. | ||
code += `\ncomponent.options.__file = ${JSON.stringify(rawShortFilePath.replace(/\\/g, '/'))}` | ||
code += `\ncomponent.options.__file = ${JSON.stringify( | ||
rawShortFilePath.replace(/\\/g, '/') | ||
)}` | ||
} else if (options.exposeFilename) { | ||
@@ -199,0 +200,0 @@ // Libraries can opt-in to expose their components' filenames in production builds. |
@@ -7,2 +7,3 @@ const qs = require('querystring') | ||
const stylePostLoaderPath = require.resolve('./stylePostLoader') | ||
const { resolveCompiler } = require('../compiler') | ||
@@ -94,5 +95,4 @@ const isESLintLoader = l => /(\/|\\|@)eslint-loader/.test(l.path) | ||
loaders.forEach(loader => { | ||
const identifier = typeof loader === 'string' | ||
? loader | ||
: (loader.path + loader.query) | ||
const identifier = | ||
typeof loader === 'string' ? loader : loader.path + loader.query | ||
const request = typeof loader === 'string' ? loader : loader.request | ||
@@ -107,6 +107,7 @@ if (!seen.has(identifier)) { | ||
return loaderUtils.stringifyRequest(this, '-!' + [ | ||
...loaderStrings, | ||
this.resourcePath + this.resourceQuery | ||
].join('!')) | ||
return loaderUtils.stringifyRequest( | ||
this, | ||
'-!' + | ||
[...loaderStrings, this.resourcePath + this.resourceQuery].join('!') | ||
) | ||
} | ||
@@ -135,16 +136,21 @@ | ||
const path = require('path') | ||
const cacheLoader = cacheDirectory && cacheIdentifier | ||
? [`${require.resolve('cache-loader')}?${JSON.stringify({ | ||
// For some reason, webpack fails to generate consistent hash if we | ||
// use absolute paths here, even though the path is only used in a | ||
// comment. For now we have to ensure cacheDirectory is a relative path. | ||
cacheDirectory: (path.isAbsolute(cacheDirectory) | ||
? path.relative(process.cwd(), cacheDirectory) | ||
: cacheDirectory).replace(/\\/g, '/'), | ||
cacheIdentifier: hash(cacheIdentifier) + '-vue-loader-template' | ||
})}`] | ||
: [] | ||
const cacheLoader = | ||
cacheDirectory && cacheIdentifier | ||
? [ | ||
`${require.resolve('cache-loader')}?${JSON.stringify({ | ||
// For some reason, webpack fails to generate consistent hash if we | ||
// use absolute paths here, even though the path is only used in a | ||
// comment. For now we have to ensure cacheDirectory is a relative path. | ||
cacheDirectory: (path.isAbsolute(cacheDirectory) | ||
? path.relative(process.cwd(), cacheDirectory) | ||
: cacheDirectory | ||
).replace(/\\/g, '/'), | ||
cacheIdentifier: hash(cacheIdentifier) + '-vue-loader-template' | ||
})}` | ||
] | ||
: [] | ||
const preLoaders = loaders.filter(isPreLoader) | ||
const postLoaders = loaders.filter(isPostLoader) | ||
const { is27 } = resolveCompiler(this.rootContext, this) | ||
@@ -154,6 +160,6 @@ const request = genRequest([ | ||
...postLoaders, | ||
templateLoaderPath + `??vue-loader-options`, | ||
...(is27 ? [] : [templateLoaderPath + `??vue-loader-options`]), | ||
...preLoaders | ||
]) | ||
// console.log(request) | ||
// the template compiler uses esm exports | ||
@@ -160,0 +166,0 @@ return `export * from ${request}` |
const qs = require('querystring') | ||
const { compileStyle } = require('@vue/component-compiler-utils') | ||
const { resolveCompiler } = require('../compiler') | ||
@@ -9,3 +9,4 @@ // This is a post loader that handles scoped CSS transforms. | ||
const query = qs.parse(this.resourceQuery.slice(1)) | ||
const { code, map, errors } = compileStyle({ | ||
const { compiler } = resolveCompiler(this.rootContext, this) | ||
const { code, map, errors } = compiler.compileStyle({ | ||
source, | ||
@@ -12,0 +13,0 @@ filename: this.resourcePath, |
const qs = require('querystring') | ||
const loaderUtils = require('loader-utils') | ||
const { compileTemplate } = require('@vue/component-compiler-utils') | ||
const { resolveCompiler } = require('../compiler') | ||
@@ -18,20 +18,29 @@ // Loader that compiles raw template into JavaScript functions. | ||
const isServer = loaderContext.target === 'node' | ||
const isProduction = options.productionMode || loaderContext.minimize || process.env.NODE_ENV === 'production' | ||
const isProduction = | ||
options.productionMode || | ||
loaderContext.minimize || | ||
process.env.NODE_ENV === 'production' | ||
const isFunctional = query.functional | ||
// allow using custom compiler via options | ||
const compiler = options.compiler || require('vue-template-compiler') | ||
const compilerOptions = Object.assign( | ||
{ | ||
outputSourceRange: true | ||
}, | ||
options.compilerOptions, | ||
{ | ||
scopeId: query.scoped ? `data-v-${id}` : null, | ||
comments: query.comments | ||
} | ||
) | ||
const compilerOptions = Object.assign({ | ||
outputSourceRange: true | ||
}, options.compilerOptions, { | ||
scopeId: query.scoped ? `data-v-${id}` : null, | ||
comments: query.comments | ||
}) | ||
const { compiler, templateCompiler } = resolveCompiler( | ||
loaderContext.rootContext, | ||
loaderContext | ||
) | ||
// for vue-component-compiler | ||
// for vue/compiler-sfc OR @vue/component-compiler-utils | ||
const finalOptions = { | ||
source, | ||
filename: this.resourcePath, | ||
compiler, | ||
compiler: options.compiler || templateCompiler, | ||
compilerOptions, | ||
@@ -47,3 +56,3 @@ // allow customizing behavior of vue-template-es2015-compiler | ||
const compiled = compileTemplate(finalOptions) | ||
const compiled = compiler.compileTemplate(finalOptions) | ||
@@ -59,4 +68,7 @@ // tips | ||
if (compiled.errors && compiled.errors.length) { | ||
const generateCodeFrame = | ||
(templateCompiler && templateCompiler.generateCodeFrame) || | ||
compiler.generateCodeFrame | ||
// 2.6 compiler outputs errors as objects with range | ||
if (compiler.generateCodeFrame && finalOptions.compilerOptions.outputSourceRange) { | ||
if (generateCodeFrame && finalOptions.compilerOptions.outputSourceRange) { | ||
// TODO account for line offset in case template isn't placed at top | ||
@@ -66,7 +78,9 @@ // of the file | ||
`\n\n Errors compiling template:\n\n` + | ||
compiled.errors.map(({ msg, start, end }) => { | ||
const frame = compiler.generateCodeFrame(source, start, end) | ||
return ` ${msg}\n\n${pad(frame)}` | ||
}).join(`\n\n`) + | ||
'\n' | ||
compiled.errors | ||
.map(({ msg, start, end }) => { | ||
const frame = generateCodeFrame(source, start, end) | ||
return ` ${msg}\n\n${pad(frame)}` | ||
}) | ||
.join(`\n\n`) + | ||
'\n' | ||
) | ||
@@ -73,0 +87,0 @@ } else { |
const qs = require('querystring') | ||
const RuleSet = require('webpack/lib/RuleSet') | ||
const { resolveCompiler } = require('./compiler') | ||
@@ -41,3 +42,3 @@ const id = 'vue-loader-plugin' | ||
`[VueLoaderPlugin Error] No matching rule for .vue files found.\n` + | ||
`Make sure there is at least one root-level rule that matches .vue or .vue.html files.` | ||
`Make sure there is at least one root-level rule that matches .vue or .vue.html files.` | ||
) | ||
@@ -52,3 +53,3 @@ } | ||
// get the normlized "use" for vue files | ||
// get the normalized "use" for vue files | ||
const vueUse = vueRule.use | ||
@@ -63,3 +64,3 @@ // get vue-loader options | ||
`[VueLoaderPlugin Error] No matching use for vue-loader is found.\n` + | ||
`Make sure the rule matching .vue files include vue-loader in its use.` | ||
`Make sure the rule matching .vue files include vue-loader in its use.` | ||
) | ||
@@ -75,8 +76,30 @@ } | ||
// for each user rule (expect the vue rule), create a cloned rule | ||
// for each user rule (except the vue rule), create a cloned rule | ||
// that targets the corresponding language blocks in *.vue files. | ||
const clonedRules = rules | ||
.filter(r => r !== vueRule) | ||
.map(cloneRule) | ||
const clonedRules = rules.filter(r => r !== vueRule).map(cloneRule) | ||
// rule for template compiler | ||
const templateCompilerRule = { | ||
loader: require.resolve('./loaders/templateLoader'), | ||
resourceQuery: query => { | ||
const parsed = qs.parse(query.slice(1)) | ||
return parsed.vue != null && parsed.type === 'template' | ||
}, | ||
options: vueLoaderUse.options | ||
} | ||
// for each rule that matches plain .js/.ts files, also create a clone and | ||
// match it against the compiled template code inside *.vue files, so that | ||
// compiled vue render functions receive the same treatment as user code | ||
// (mostly babel) | ||
const { is27 } = resolveCompiler(compiler.options.context) | ||
let jsRulesForRenderFn = [] | ||
if (is27) { | ||
const matchesJS = createMatcher(`test.js`) | ||
// const matchesTS = createMatcher(`test.ts`) | ||
jsRulesForRenderFn = rules | ||
.filter(r => r !== vueRule && matchesJS(r)) | ||
.map(cloneRuleForRenderFn) | ||
} | ||
// global pitcher (responsible for injecting template compiler loader & CSS | ||
@@ -99,2 +122,4 @@ // post loader) | ||
pitcher, | ||
...jsRulesForRenderFn, | ||
...(is27 ? [templateCompilerRule] : []), | ||
...clonedRules, | ||
@@ -112,7 +137,3 @@ ...rules | ||
const normalized = RuleSet.normalizeRule(clone, {}, '') | ||
return ( | ||
!rule.enforce && | ||
normalized.resource && | ||
normalized.resource(fakeFile) | ||
) | ||
return !rule.enforce && normalized.resource && normalized.resource(fakeFile) | ||
} | ||
@@ -166,3 +187,40 @@ } | ||
function cloneRuleForRenderFn (rule) { | ||
const resource = rule.resource | ||
const resourceQuery = rule.resourceQuery | ||
let currentResource | ||
const res = { | ||
...rule, | ||
resource: resource => { | ||
currentResource = resource | ||
return true | ||
}, | ||
resourceQuery: query => { | ||
const parsed = qs.parse(query.slice(1)) | ||
if (parsed.vue == null || parsed.type !== 'template') { | ||
return false | ||
} | ||
const fakeResourcePath = `${currentResource}.${parsed.ts ? `ts` : `js`}` | ||
if (resource && !resource(fakeResourcePath)) { | ||
return false | ||
} | ||
if (resourceQuery && !resourceQuery(query)) { | ||
return false | ||
} | ||
return true | ||
} | ||
} | ||
if (rule.rules) { | ||
res.rules = rule.rules.map(cloneRuleForRenderFn) | ||
} | ||
if (rule.oneOf) { | ||
res.oneOf = rule.oneOf.map(cloneRuleForRenderFn) | ||
} | ||
return res | ||
} | ||
VueLoaderPlugin.NS = NS | ||
module.exports = VueLoaderPlugin |
@@ -0,1 +1,3 @@ | ||
const { resolveCompiler } = require('./compiler') | ||
const qs = require('querystring') | ||
@@ -50,3 +52,4 @@ const id = 'vue-loader-plugin' | ||
compiler.hooks.compilation.tap(id, compilation => { | ||
const normalModuleLoader = normalModule.getCompilationHooks(compilation).loader | ||
const normalModuleLoader = normalModule.getCompilationHooks(compilation) | ||
.loader | ||
normalModuleLoader.tap(id, loaderContext => { | ||
@@ -58,3 +61,3 @@ loaderContext[NS] = true | ||
const rules = compiler.options.module.rules | ||
let rawVueRules | ||
let rawVueRule | ||
let vueRules = [] | ||
@@ -67,17 +70,5 @@ | ||
} | ||
// skip the `include` check when locating the vue rule | ||
const clonedRawRule = Object.assign({}, rawRule) | ||
delete clonedRawRule.include | ||
const ruleSet = ruleSetCompiler.compile([{ | ||
rules: [clonedRawRule] | ||
}]) | ||
vueRules = ruleSet.exec({ | ||
resource: 'foo.vue' | ||
}) | ||
vueRules = match(rawRule, 'foo.vue') | ||
if (!vueRules.length) { | ||
vueRules = ruleSet.exec({ | ||
resource: 'foo.vue.html' | ||
}) | ||
vueRules = match(rawRule, 'foo.vue.html') | ||
} | ||
@@ -90,3 +81,3 @@ if (vueRules.length > 0) { | ||
} | ||
rawVueRules = rawRule | ||
rawVueRule = rawRule | ||
break | ||
@@ -98,8 +89,10 @@ } | ||
`[VueLoaderPlugin Error] No matching rule for .vue files found.\n` + | ||
`Make sure there is at least one root-level rule that matches .vue or .vue.html files.` | ||
`Make sure there is at least one root-level rule that matches .vue or .vue.html files.` | ||
) | ||
} | ||
// get the normlized "use" for vue files | ||
const vueUse = vueRules.filter(rule => rule.type === 'use').map(rule => rule.value) | ||
// get the normalized "use" for vue files | ||
const vueUse = vueRules | ||
.filter(rule => rule.type === 'use') | ||
.map(rule => rule.value) | ||
@@ -114,3 +107,3 @@ // get vue-loader options | ||
`[VueLoaderPlugin Error] No matching use for vue-loader is found.\n` + | ||
`Make sure the rule matching .vue files include vue-loader in its use.` | ||
`Make sure the rule matching .vue files include vue-loader in its use.` | ||
) | ||
@@ -130,10 +123,41 @@ } | ||
const clonedRules = rules | ||
.filter(r => r !== rawVueRules) | ||
.map((rawRule) => cloneRule(rawRule, refs)) | ||
.filter(r => r !== rawVueRule) | ||
.map(rawRule => | ||
cloneRule(rawRule, refs, langBlockRuleCheck, langBlockRuleResource) | ||
) | ||
// fix conflict with config.loader and config.options when using config.use | ||
delete rawVueRules.loader | ||
delete rawVueRules.options | ||
rawVueRules.use = vueUse | ||
delete rawVueRule.loader | ||
delete rawVueRule.options | ||
rawVueRule.use = vueUse | ||
// rule for template compiler | ||
const templateCompilerRule = { | ||
loader: require.resolve('./loaders/templateLoader'), | ||
resourceQuery: query => { | ||
if (!query) { | ||
return false | ||
} | ||
const parsed = qs.parse(query.slice(1)) | ||
return parsed.vue != null && parsed.type === 'template' | ||
}, | ||
options: vueLoaderUse.options | ||
} | ||
// for each rule that matches plain .js files, also create a clone and | ||
// match it against the compiled template code inside *.vue files, so that | ||
// compiled vue render functions receive the same treatment as user code | ||
// (mostly babel) | ||
const { is27 } = resolveCompiler(compiler.options.context) | ||
let jsRulesForRenderFn = [] | ||
if (is27) { | ||
jsRulesForRenderFn = rules | ||
.filter( | ||
r => | ||
r !== rawVueRule && | ||
(match(r, 'test.js').length > 0 || match(r, 'test.ts').length > 0) | ||
) | ||
.map(rawRule => cloneRule(rawRule, refs, jsRuleCheck, jsRuleResource)) | ||
} | ||
// global pitcher (responsible for injecting template compiler loader & CSS | ||
@@ -144,3 +168,5 @@ // post loader) | ||
resourceQuery: query => { | ||
if (!query) { return false } | ||
if (!query) { | ||
return false | ||
} | ||
const parsed = qs.parse(query.slice(1)) | ||
@@ -158,2 +184,4 @@ return parsed.vue != null | ||
pitcher, | ||
...jsRulesForRenderFn, | ||
...(is27 ? [templateCompilerRule] : []), | ||
...clonedRules, | ||
@@ -165,24 +193,49 @@ ...rules | ||
const matcherCache = new WeakMap() | ||
function match (rule, fakeFile) { | ||
let ruleSet = matcherCache.get(rule) | ||
if (!ruleSet) { | ||
// skip the `include` check when locating the vue rule | ||
const clonedRawRule = { ...rule } | ||
delete clonedRawRule.include | ||
ruleSet = ruleSetCompiler.compile([clonedRawRule]) | ||
matcherCache.set(rule, ruleSet) | ||
} | ||
return ruleSet.exec({ | ||
resource: fakeFile | ||
}) | ||
} | ||
const langBlockRuleCheck = (query, rule) => { | ||
return ( | ||
query.type === 'custom' || !rule.conditions.length || query.lang != null | ||
) | ||
} | ||
const langBlockRuleResource = (query, resource) => `${resource}.${query.lang}` | ||
const jsRuleCheck = query => { | ||
return query.type === 'template' | ||
} | ||
const jsRuleResource = (query, resource) => | ||
`${resource}.${query.ts ? `ts` : `js`}` | ||
let uid = 0 | ||
function cloneRule (rawRule, refs) { | ||
const rules = ruleSetCompiler.compileRules(`clonedRuleSet-${++uid}`, [{ | ||
rules: [rawRule] | ||
}], refs) | ||
let currentResource | ||
const conditions = rules[0].rules | ||
.map(rule => rule.conditions) | ||
// shallow flat | ||
.reduce((prev, next) => prev.concat(next), []) | ||
function cloneRule (rawRule, refs, ruleCheck, ruleResource) { | ||
const compiledRule = ruleSetCompiler.compileRule( | ||
`clonedRuleSet-${++uid}`, | ||
rawRule, | ||
refs | ||
) | ||
// do not process rule with enforce | ||
if (!rawRule.enforce) { | ||
const ruleUse = rules[0].rules | ||
.map(rule => rule.effects | ||
.filter(effect => effect.type === 'use') | ||
.map(effect => effect.value) | ||
) | ||
// shallow flat | ||
.reduce((prev, next) => prev.concat(next), []) | ||
const ruleUse = compiledRule.effects | ||
.filter(effect => effect.type === 'use') | ||
.map(effect => effect.value) | ||
// fix conflict with config.loader and config.options when using config.use | ||
@@ -194,3 +247,5 @@ delete rawRule.loader | ||
const res = Object.assign({}, rawRule, { | ||
let currentResource | ||
const res = { | ||
...rawRule, | ||
resource: resources => { | ||
@@ -201,3 +256,6 @@ currentResource = resources | ||
resourceQuery: query => { | ||
if (!query) { return false } | ||
if (!query) { | ||
return false | ||
} | ||
const parsed = qs.parse(query.slice(1)) | ||
@@ -207,9 +265,10 @@ if (parsed.vue == null) { | ||
} | ||
if (!conditions) { | ||
if (!ruleCheck(parsed, compiledRule)) { | ||
return false | ||
} | ||
const fakeResourcePath = `${currentResource}.${parsed.lang}` | ||
for (const condition of conditions) { | ||
const fakeResourcePath = ruleResource(parsed, currentResource) | ||
for (const condition of compiledRule.conditions) { | ||
// add support for resourceQuery | ||
const request = condition.property === 'resourceQuery' ? query : fakeResourcePath | ||
const request = | ||
condition.property === 'resourceQuery' ? query : fakeResourcePath | ||
if (condition && !condition.fn(request)) { | ||
@@ -221,3 +280,3 @@ return false | ||
} | ||
}) | ||
} | ||
@@ -227,7 +286,11 @@ delete res.test | ||
if (rawRule.rules) { | ||
res.rules = rawRule.rules.map(rule => cloneRule(rule, refs)) | ||
res.rules = rawRule.rules.map(rule => | ||
cloneRule(rule, refs, ruleCheck, ruleResource) | ||
) | ||
} | ||
if (rawRule.oneOf) { | ||
res.oneOf = rawRule.oneOf.map(rule => cloneRule(rule, refs)) | ||
res.oneOf = rawRule.oneOf.map(rule => | ||
cloneRule(rule, refs, ruleCheck, ruleResource) | ||
) | ||
} | ||
@@ -234,0 +297,0 @@ |
@@ -0,3 +1,6 @@ | ||
const { resolveScript } = require('./resolveScript') | ||
module.exports = function selectBlock ( | ||
descriptor, | ||
options, | ||
loaderContext, | ||
@@ -22,10 +25,7 @@ query, | ||
if (query.type === `script`) { | ||
const script = resolveScript(descriptor, options, loaderContext) | ||
if (appendExtension) { | ||
loaderContext.resourcePath += '.' + (descriptor.script.lang || 'js') | ||
loaderContext.resourcePath += '.' + (script.lang || 'js') | ||
} | ||
loaderContext.callback( | ||
null, | ||
descriptor.script.content, | ||
descriptor.script.map | ||
) | ||
loaderContext.callback(null, script.content, script.map) | ||
return | ||
@@ -40,7 +40,3 @@ } | ||
} | ||
loaderContext.callback( | ||
null, | ||
style.content, | ||
style.map | ||
) | ||
loaderContext.callback(null, style.content, style.map) | ||
return | ||
@@ -52,9 +48,5 @@ } | ||
const block = descriptor.customBlocks[query.index] | ||
loaderContext.callback( | ||
null, | ||
block.content, | ||
block.map | ||
) | ||
loaderContext.callback(null, block.content, block.map) | ||
return | ||
} | ||
} |
{ | ||
"name": "vue-loader", | ||
"version": "15.9.8", | ||
"version": "15.10.0-beta.1", | ||
"description": "Vue single-file component loader for Webpack", | ||
@@ -78,3 +78,2 @@ "main": "lib/index.js", | ||
"mini-css-extract-plugin": "^0.4.1", | ||
"node-sass": "^4.7.2", | ||
"normalize-newline": "^3.0.0", | ||
@@ -86,3 +85,2 @@ "null-loader": "^0.1.1", | ||
"raw-loader": "^0.5.1", | ||
"sass-loader": "^6.0.7", | ||
"source-map": "^0.5.0", | ||
@@ -100,3 +98,3 @@ "stylus": "^0.54.5", | ||
"vuepress-theme-vue": "^1.1.0", | ||
"webpack": "^4.1.0", | ||
"webpack": "^4.46.0", | ||
"webpack-cli": "^3.2.0", | ||
@@ -103,0 +101,0 @@ "webpack-dev-server": "^3.1.1", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
505859
42
23
1331
1
5