This commit is contained in:
2022-07-18 02:50:52 +00:00
parent befd344ab0
commit 06181b34d6
8569 changed files with 818704 additions and 352705 deletions
+5 -1
View File
@@ -1,4 +1,8 @@
module.exports = {
root: true,
extends: ['plugin:vue-libs/recommended']
extends: ['plugin:vue-libs/recommended'],
rules: {
indent: 'off',
'space-before-function-paren': 'off'
}
}
+119
View File
@@ -1,3 +1,122 @@
<a name="15.10.0"></a>
# [15.10.0](https://github.com/vuejs/vue-loader/compare/v15.10.0-beta.6...v15.10.0) (2022-07-01)
<a name="15.10.0-beta.6"></a>
# [15.10.0-beta.6](https://github.com/vuejs/vue-loader/compare/v15.10.0-beta.5...v15.10.0-beta.6) (2022-06-20)
### Bug Fixes
* always pass id to stylePostLoader when possible ([364ad09](https://github.com/vuejs/vue-loader/commit/364ad09))
<a name="15.10.0-beta.5"></a>
# [15.10.0-beta.5](https://github.com/vuejs/vue-loader/compare/v15.10.0-beta.4...v15.10.0-beta.5) (2022-06-20)
### Bug Fixes
* css v-bind in production mode ([655e5f8](https://github.com/vuejs/vue-loader/commit/655e5f8))
<a name="15.10.0-beta.4"></a>
# [15.10.0-beta.4](https://github.com/vuejs/vue-loader/compare/v15.10.0-beta.3...v15.10.0-beta.4) (2022-06-20)
### Features
* support css v-bind (requires 2.7.0-beta.3) ([d653f3b](https://github.com/vuejs/vue-loader/commit/d653f3b))
<a name="15.10.0-beta.3"></a>
# [15.10.0-beta.3](https://github.com/vuejs/vue-loader/compare/v15.10.0-beta.2...v15.10.0-beta.3) (2022-06-16)
### Bug Fixes
* cache descriptor with correct resource path ([f6c83b5](https://github.com/vuejs/vue-loader/commit/f6c83b5))
<a name="15.10.0-beta.2"></a>
# [15.10.0-beta.2](https://github.com/vuejs/vue-loader/compare/v15.10.0-beta.1...v15.10.0-beta.2) (2022-06-16)
### Features
* use script-analyzed bindings when compiling template ([55de28c](https://github.com/vuejs/vue-loader/commit/55de28c))
<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>
## [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>
## [15.9.7](https://github.com/vuejs/vue-loader/compare/v15.9.6...v15.9.7) (2021-05-11)
### Bug Fixes
* [plugin] Use compiler.webpack when possible ([#1822](https://github.com/vuejs/vue-loader/issues/1822)) ([f7ee30b](https://github.com/vuejs/vue-loader/commit/f7ee30b)), closes [#1781](https://github.com/vuejs/vue-loader/issues/1781)
* check for compiler.webpack existence ([2472b2f](https://github.com/vuejs/vue-loader/commit/2472b2f))
<a name="15.9.6"></a>
## [15.9.6](https://github.com/vuejs/vue-loader/compare/v15.9.5...v15.9.6) (2020-12-17)
### Bug Fixes
* resourceQuery could be undefined in webpack 5 ([a2b89d3](https://github.com/vuejs/vue-loader/commit/a2b89d3)), closes [#1771](https://github.com/vuejs/vue-loader/issues/1771)
<a name="15.9.5"></a>
## [15.9.5](https://github.com/vuejs/vue-loader/compare/v15.9.4...v15.9.5) (2020-11-02)
### Bug Fixes
* add rule plugins to keep up with webpack 5 new features ([7ca8e2c](https://github.com/vuejs/vue-loader/commit/7ca8e2c))
* ensure new webpack5 generator property in rules passes ruleset checks ([#1753](https://github.com/vuejs/vue-loader/issues/1753)) ([f79bb08](https://github.com/vuejs/vue-loader/commit/f79bb08)), closes [#1729](https://github.com/vuejs/vue-loader/issues/1729)
<a name="15.9.4"></a>
## [15.9.4](https://github.com/vuejs/vue-loader/compare/v15.9.3...v15.9.4) (2020-10-27)
### Bug Fixes
* fix id differences between different operating systems ([#1706](https://github.com/vuejs/vue-loader/issues/1706)) ([afe8a0d](https://github.com/vuejs/vue-loader/commit/afe8a0d))
* fix mini-css-extract-plugin missing default export error ([#1748](https://github.com/vuejs/vue-loader/issues/1748)) ([429a284](https://github.com/vuejs/vue-loader/commit/429a284))
<a name="15.9.3"></a>
## [15.9.3](https://github.com/vuejs/vue-loader/compare/v15.9.2...v15.9.3) (2020-06-23)
+3 -3
View File
@@ -107,14 +107,14 @@ In a nutshell, the combination of webpack and `vue-loader` gives you a modern, f
4. For the `<script>` block, this is pretty much it. For `<template>` and `<style>` blocks though, a few extra tasks need to be performed:
- We need to compile the template using the Vue template compiler;
- We need to post-process the CSS in `<style scoped>` blocks, **after** `css-loader` but **before** `style-loader`.
- We need to post-process the CSS in `<style scoped>` blocks, **before** `css-loader`.
Technically, these are additional loaders (`src/templateLoader.ts` and `src/stylePostLoader.ts`) that need to be injected into the expanded loader chain. It would be very complicated if the end users have to configure this themselves, so `VueLoaderPlugin` also injects a global [Pitching Loader](https://webpack.js.org/api/loaders/#pitching-loader) (`src/pitcher.ts`) that intercepts Vue `<template>` and `<style>` requests and injects the necessary loaders. The final requests look like the following:
``` js
// <template lang="pug">
import 'vue-loader/template-loader!pug-loader!source.vue?vue&type=template'
import 'vue-loader/template-loader!pug-loader!vue-loader!source.vue?vue&type=template'
// <style scoped lang="scss">
import 'style-loader!vue-loader/style-post-loader!css-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
import 'style-loader!css-loader!vue-loader/style-post-loader!sass-loader!vue-loader!source.vue?vue&type=style&index=1&scoped&lang=scss'
```
+22 -12
View File
@@ -1,21 +1,31 @@
const qs = require('querystring')
const { attrsToQuery } = require('./utils')
module.exports = function genCustomBlocksCode (
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 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)`
)
}).join(`\n`) + `\n`
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 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)`
)
})
.join(`\n`) +
`\n`
)
}
+18 -12
View File
@@ -2,14 +2,15 @@ const { attrsToQuery } = require('./utils')
const hotReloadAPIPath = JSON.stringify(require.resolve('vue-hot-reload-api'))
const nonWhitespaceRE = /\S+/
module.exports = function genStyleInjectionCode (
module.exports = function genStyleInjectionCode(
loaderContext,
styles,
id,
resourcePath,
stringifyRequest,
needsHotReload,
needsExplicitInjection
needsExplicitInjection,
isProduction
) {
let styleImportsCode = ``
let styleInjectionCode = ``
@@ -18,18 +19,19 @@ module.exports = function genStyleInjectionCode (
let hasCSSModules = false
const cssModuleNames = new Map()
function genStyleRequest (style, i) {
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
// make sure to only pass id not src importing 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}${inheritQuery}`
const idQuery = !style.src || style.scoped ? `&id=${id}` : ``
const prodQuery = isProduction ? `&prod` : ``
const query = `?vue&type=style&index=${i}${idQuery}${prodQuery}${attrsQuery}${inheritQuery}`
return stringifyRequest(src + query)
}
function genCSSModulesCode (style, request, i) {
function genCSSModulesCode(style, request, i) {
hasCSSModules = true
const moduleName = style.module === true ? '$style' : style.module
@@ -71,7 +73,8 @@ module.exports = function genStyleInjectionCode (
}
// empty styles: with no `src` specified or only contains whitespaces
const isNotEmptyStyle = style => style.src || nonWhitespaceRE.test(style.content)
const isNotEmptyStyle = (style) =>
style.src || nonWhitespaceRE.test(style.content)
// explicit injection is needed in SSR (for critical CSS collection)
// or in Shadow Mode (for injection into shadow root)
// In these modes, vue-style-loader exports objects with the __inject__
@@ -89,10 +92,9 @@ module.exports = function genStyleInjectionCode (
styles.forEach((style, i) => {
if (isNotEmptyStyle(style)) {
const request = genStyleRequest(style, i)
styleInjectionCode += (
styleInjectionCode +=
`var style${i} = require(${request})\n` +
`if (style${i}.__inject__) style${i}.__inject__(context)\n`
)
if (style.module) genCSSModulesCode(style, request, i)
}
})
@@ -112,11 +114,15 @@ function injectStyles (context) {
${styleInjectionCode}
}
${needsHotReload ? `
${
needsHotReload
? `
module.hot && module.hot.dispose(function (data) {
disposed = true
})
` : ``}
`
: ``
}
${cssModulesHotReloadCode}
`.trim()
+1 -6
View File
@@ -2,12 +2,7 @@ const qs = require('querystring')
// these are built-in query parameters so should be ignored
// if the user happen to add them as attrs
const ignoreList = [
'id',
'index',
'src',
'type'
]
const ignoreList = ['id', 'index', 'src', 'type']
// transform the attrs on a SFC block descriptor into a resourceQuery string
exports.attrsToQuery = (attrs, langFallback) => {
+54
View File
@@ -0,0 +1,54 @@
// resolve compilers to use.
let cached
exports.resolveCompiler = function (ctx, loaderContext) {
if (cached) {
return cached
}
// check 2.7
try {
const pkg = loadFromContext('vue/package.json', ctx)
const [major, minor] = pkg.version.split('.')
if (major === '2' && Number(minor) >= 7) {
return (cached = {
is27: true,
compiler: loadFromContext('vue/compiler-sfc', ctx),
templateCompiler: undefined
})
}
} catch (e) {}
return (cached = {
compiler: require('@vue/component-compiler-utils'),
templateCompiler: loadTemplateCompiler(ctx, loaderContext)
})
}
function loadFromContext(path, ctx) {
return require(require.resolve(path, {
paths: [ctx]
}))
}
function loadTemplateCompiler(ctx, loaderContext) {
try {
return loadFromContext('vue-template-compiler', ctx)
} catch (e) {
if (loaderContext) {
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.`
)
)
}
} else {
throw e
}
}
}
+47
View File
@@ -0,0 +1,47 @@
const fs = require('fs')
const path = require('path')
const { resolveCompiler } = require('./compiler')
const cache = new Map()
exports.setDescriptor = function setDescriptor(filename, entry) {
cache.set(cleanQuery(filename), entry)
}
exports.getDescriptor = function getDescriptor(
filename,
options,
loaderContext
) {
filename = cleanQuery(filename)
if (cache.has(filename)) {
return cache.get(filename)
}
// This function should only be called after the descriptor has been
// cached by the main loader.
// If this is somehow called without a cache hit, it's probably due to sub
// loaders being run in separate threads. The only way to deal with this is to
// read from disk directly...
const source = fs.readFileSync(filename, 'utf-8')
const sourceRoot = path.dirname(
path.relative(loaderContext.rootContext, loaderContext.resourcePath)
)
const { compiler, templateCompiler } = resolveCompiler(
loaderContext.rootContext
)
const descriptor = compiler.parse({
source,
compiler: options.compiler || templateCompiler,
filename,
sourceRoot,
needMap: loaderContext.sourceMap
})
cache.set(filename, descriptor)
return descriptor
}
function cleanQuery(str) {
const i = str.indexOf('?')
return i > 0 ? str.slice(0, i) : str
}
+67 -60
View File
@@ -5,51 +5,40 @@ const plugin = require('./plugin')
const selectBlock = require('./select')
const loaderUtils = require('loader-utils')
const { attrsToQuery } = require('./codegen/utils')
const { parse } = require('@vue/component-compiler-utils')
const genStylesCode = require('./codegen/styleInjection')
const { genHotReloadCode } = require('./codegen/hotReload')
const genCustomBlocksCode = require('./codegen/customBlocks')
const componentNormalizerPath = require.resolve('./runtime/componentNormalizer')
const { NS } = require('./plugin')
const { resolveCompiler } = require('./compiler')
const { setDescriptor } = require('./descriptorCache')
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) {
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
}
const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
const stringifyRequest = (r) => loaderUtils.stringifyRequest(loaderContext, r)
const {
mode,
target,
request,
minimize,
sourceMap,
rootContext,
resourcePath,
resourceQuery
resourceQuery = ''
} = loaderContext
const rawQuery = resourceQuery.slice(1)
@@ -59,53 +48,78 @@ module.exports = function (source) {
const isServer = target === 'node'
const isShadow = !!options.shadowMode
const isProduction = options.productionMode || minimize || process.env.NODE_ENV === 'production'
const isProduction =
mode === 'production' ||
options.productionMode ||
minimize ||
process.env.NODE_ENV === 'production'
const filename = path.basename(resourcePath)
const context = rootContext || process.cwd()
const sourceRoot = path.dirname(path.relative(context, resourcePath))
const descriptor = parse({
const { compiler, templateCompiler } = resolveCompiler(context, loaderContext)
const descriptor = compiler.parse({
source,
compiler: options.compiler || loadTemplateCompiler(loaderContext),
compiler: options.compiler || templateCompiler,
filename,
sourceRoot,
needMap: sourceMap
})
// cache descriptor
setDescriptor(resourcePath, descriptor)
// module id for scoped CSS & hot-reload
const rawShortFilePath = path
.relative(context, resourcePath)
.replace(/^(\.\.[\/\\])+/, '')
const shortFilePath = rawShortFilePath.replace(/\\/g, '/')
const id = hash(
isProduction
? shortFilePath + '\n' + source.replace(/\r\n/g, '\n')
: shortFilePath
)
// if the query has a type field, this is a language block request
// e.g. foo.vue?type=template&id=xxxxx
// and we will return early
if (incomingQuery.type) {
return selectBlock(
descriptor,
id,
options,
loaderContext,
incomingQuery,
!!options.appendExtension
)
}
// module id for scoped CSS & hot-reload
const rawShortFilePath = path
.relative(context, resourcePath)
.replace(/^(\.\.[\/\\])+/, '')
const shortFilePath = rawShortFilePath.replace(/\\/g, '/') + resourceQuery
const id = hash(
isProduction
? (shortFilePath + '\n' + source)
: shortFilePath
)
// feature information
const hasScoped = descriptor.styles.some(s => s.scoped)
const hasFunctional = descriptor.template && descriptor.template.attrs.functional
const needsHotReload = (
const hasScoped = descriptor.styles.some((s) => s.scoped)
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
let templateImport = `var render, staticRenderFns`
@@ -115,24 +129,13 @@ module.exports = function (source) {
const idQuery = `&id=${id}`
const scopedQuery = hasScoped ? `&scoped=true` : ``
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
let stylesCode = ``
if (descriptor.styles.length) {
@@ -143,11 +146,13 @@ module.exports = function (source) {
resourcePath,
stringifyRequest,
needsHotReload,
isServer || isShadow // needs explicit injection?
isServer || isShadow, // needs explicit injection?
isProduction
)
}
let code = `
let code =
`
${templateImport}
${scriptImport}
${stylesCode}
@@ -183,7 +188,9 @@ var component = normalizer(
if (!isProduction) {
// Expose the file's full path in development, so that it can be opened
// 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) {
// Libraries can opt-in to expose their components' filenames in production builds.
// For security reasons, only expose the file's basename in production.
+44 -36
View File
@@ -4,19 +4,20 @@ const hash = require('hash-sum')
const selfPath = require.resolve('../index')
const templateLoaderPath = require.resolve('./templateLoader')
const stylePostLoaderPath = require.resolve('./stylePostLoader')
const { resolveCompiler } = require('../compiler')
const isESLintLoader = l => /(\/|\\|@)eslint-loader/.test(l.path)
const isNullLoader = l => /(\/|\\|@)null-loader/.test(l.path)
const isCSSLoader = l => /(\/|\\|@)css-loader/.test(l.path)
const isCacheLoader = l => /(\/|\\|@)cache-loader/.test(l.path)
const isPitcher = l => l.path !== __filename
const isPreLoader = l => !l.pitchExecuted
const isPostLoader = l => l.pitchExecuted
const isESLintLoader = (l) => /(\/|\\|@)eslint-loader/.test(l.path)
const isNullLoader = (l) => /(\/|\\|@)null-loader/.test(l.path)
const isCSSLoader = (l) => /(\/|\\|@)css-loader/.test(l.path)
const isCacheLoader = (l) => /(\/|\\|@)cache-loader/.test(l.path)
const isPitcher = (l) => l.path !== __filename
const isPreLoader = (l) => !l.pitchExecuted
const isPostLoader = (l) => l.pitchExecuted
const dedupeESLintLoader = loaders => {
const dedupeESLintLoader = (loaders) => {
const res = []
let seen = false
loaders.forEach(l => {
loaders.forEach((l) => {
if (!isESLintLoader(l)) {
res.push(l)
} else if (!seen) {
@@ -27,8 +28,8 @@ const dedupeESLintLoader = loaders => {
return res
}
const shouldIgnoreCustomBlock = loaders => {
const actualLoaders = loaders.filter(loader => {
const shouldIgnoreCustomBlock = (loaders) => {
const actualLoaders = loaders.filter((loader) => {
// vue-loader
if (loader.path === selfPath) {
return false
@@ -44,7 +45,7 @@ const shouldIgnoreCustomBlock = loaders => {
return actualLoaders.length === 0
}
module.exports = code => code
module.exports = (code) => code
// This pitching loader is responsible for intercepting all vue block requests
// and transform it into appropriate requests.
@@ -61,7 +62,7 @@ module.exports.pitch = function (remainingRequest) {
// if this is an inline block, since the whole file itself is being linted,
// remove eslint-loader to avoid duplicate linting.
if (/\.vue$/.test(this.resourcePath)) {
loaders = loaders.filter(l => !isESLintLoader(l))
loaders = loaders.filter((l) => !isESLintLoader(l))
} else {
// This is a src import. Just make sure there's not more than 1 instance
// of eslint present.
@@ -77,7 +78,7 @@ module.exports.pitch = function (remainingRequest) {
return
}
const genRequest = loaders => {
const genRequest = (loaders) => {
// Important: dedupe since both the original rule
// and the cloned rule would match a source import request.
// also make sure to dedupe based on loader path.
@@ -89,10 +90,9 @@ module.exports.pitch = function (remainingRequest) {
const seen = new Map()
const loaderStrings = []
loaders.forEach(loader => {
const identifier = typeof loader === 'string'
? loader
: (loader.path + loader.query)
loaders.forEach((loader) => {
const identifier =
typeof loader === 'string' ? loader : loader.path + loader.query
const request = typeof loader === 'string' ? loader : loader.request
if (!seen.has(identifier)) {
seen.set(identifier, true)
@@ -102,10 +102,11 @@ module.exports.pitch = function (remainingRequest) {
}
})
return loaderUtils.stringifyRequest(this, '-!' + [
...loaderStrings,
this.resourcePath + this.resourceQuery
].join('!'))
return loaderUtils.stringifyRequest(
this,
'-!' +
[...loaderStrings, this.resourcePath + this.resourceQuery].join('!')
)
}
// Inject style-post-loader before css-loader for scoped CSS and trimming
@@ -120,35 +121,42 @@ module.exports.pitch = function (remainingRequest) {
...beforeLoaders
])
// console.log(request)
return `import mod from ${request}; export default mod; export * from ${request}`
return query.module
? `export { default } from ${request}; export * from ${request}`
: `export * from ${request}`
}
}
// for templates: inject the template compiler & optional cache
if (query.type === `template`) {
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)
const request = genRequest([
...cacheLoader,
...postLoaders,
templateLoaderPath + `??vue-loader-options`,
...(is27 ? [] : [templateLoaderPath + `??vue-loader-options`]),
...preLoaders
])
// console.log(request)
// the template compiler uses esm exports
return `export * from ${request}`
}
+4 -2
View File
@@ -1,17 +1,19 @@
const qs = require('querystring')
const { compileStyle } = require('@vue/component-compiler-utils')
const { resolveCompiler } = require('../compiler')
// This is a post loader that handles scoped CSS transforms.
// Injected right before css-loader by the global pitcher (../pitch.js)
// for any <style scoped> selection requests initiated from within vue files.
module.exports = function (source, inMap) {
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,
filename: this.resourcePath,
id: `data-v-${query.id}`,
map: inMap,
scoped: !!query.scoped,
isProd: query.prod != null,
trim: true
})
+43 -24
View File
@@ -1,12 +1,16 @@
const qs = require('querystring')
const loaderUtils = require('loader-utils')
const { compileTemplate } = require('@vue/component-compiler-utils')
const { resolveCompiler } = require('../compiler')
const { getDescriptor } = require('../descriptorCache')
const { resolveScript } = require('../resolveScript')
// Loader that compiles raw template into JavaScript functions.
// This is injected by the global pitcher (../pitch) for template
// selection requests initiated from vue files.
module.exports = function (source) {
const loaderContext = this
const filename = this.resourcePath
const ctx = this.rootContext
const query = qs.parse(this.resourceQuery.slice(1))
// although this is not the main vue-loader, we can get access to the same
@@ -15,24 +19,33 @@ module.exports = function (source) {
const options = loaderUtils.getOptions(loaderContext) || {}
const { id } = query
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(ctx, loaderContext)
// for vue-component-compiler
const descriptor = getDescriptor(filename, options, loaderContext)
const script = resolveScript(descriptor, id, options, loaderContext)
// for vue/compiler-sfc OR @vue/component-compiler-utils
const finalOptions = {
source,
filename: this.resourcePath,
compiler,
compiler: options.compiler || templateCompiler,
compilerOptions,
// allow customizing behavior of vue-template-es2015-compiler
transpileOptions: options.transpileOptions,
@@ -40,36 +53,42 @@ module.exports = function (source) {
isProduction,
isFunctional,
optimizeSSR: isServer && options.optimizeSSR !== false,
prettify: options.prettify
prettify: options.prettify,
bindings: script ? script.bindings : undefined
}
const compiled = compileTemplate(finalOptions)
const compiled = compiler.compileTemplate(finalOptions)
// tips
if (compiled.tips && compiled.tips.length) {
compiled.tips.forEach(tip => {
compiled.tips.forEach((tip) => {
loaderContext.emitWarning(typeof tip === 'object' ? tip.msg : tip)
})
}
// errors
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
// of the file
loaderContext.emitError(
`\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'
)
} else {
loaderContext.emitError(
`\n Error compiling template:\n${pad(compiled.source)}\n` +
compiled.errors.map(e => ` - ${e}`).join('\n') +
compiled.errors.map((e) => ` - ${e}`).join('\n') +
'\n'
)
}
@@ -81,9 +100,9 @@ module.exports = function (source) {
return code + `\nexport { render, staticRenderFns }`
}
function pad (source) {
function pad(source) {
return source
.split(/\r?\n/)
.map(line => ` ${line}`)
.map((line) => ` ${line}`)
.join('\n')
}
+81 -23
View File
@@ -1,24 +1,25 @@
const qs = require('querystring')
const RuleSet = require('webpack/lib/RuleSet')
const { resolveCompiler } = require('./compiler')
const id = 'vue-loader-plugin'
const NS = 'vue-loader'
class VueLoaderPlugin {
apply (compiler) {
apply(compiler) {
// add NS marker so that the loader can detect and report missing plugin
if (compiler.hooks) {
// webpack 4
compiler.hooks.compilation.tap(id, compilation => {
compiler.hooks.compilation.tap(id, (compilation) => {
const normalModuleLoader = compilation.hooks.normalModuleLoader
normalModuleLoader.tap(id, loaderContext => {
normalModuleLoader.tap(id, (loaderContext) => {
loaderContext[NS] = true
})
})
} else {
// webpack < 4
compiler.plugin('compilation', compilation => {
compilation.plugin('normal-module-loader', loaderContext => {
compiler.plugin('compilation', (compilation) => {
compilation.plugin('normal-module-loader', (loaderContext) => {
loaderContext[NS] = true
})
})
@@ -38,7 +39,7 @@ class VueLoaderPlugin {
if (!vueRule) {
throw new Error(
`[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.`
)
}
@@ -48,17 +49,17 @@ class VueLoaderPlugin {
)
}
// get the normlized "use" for vue files
// get the normalized "use" for vue files
const vueUse = vueRule.use
// get vue-loader options
const vueLoaderUseIndex = vueUse.findIndex(u => {
const vueLoaderUseIndex = vueUse.findIndex((u) => {
return /^vue-loader|(\/|\\|@)vue-loader/.test(u.loader)
})
if (vueLoaderUseIndex < 0) {
throw new Error(
`[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.`
)
}
@@ -69,17 +70,39 @@ class VueLoaderPlugin {
vueLoaderUse.ident = 'vue-loader-options'
vueLoaderUse.options = vueLoaderUse.options || {}
// 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
// post loader)
const pitcher = {
loader: require.resolve('./loaders/pitcher'),
resourceQuery: query => {
resourceQuery: (query) => {
const parsed = qs.parse(query.slice(1))
return parsed.vue != null
},
@@ -92,27 +115,25 @@ class VueLoaderPlugin {
// replace original rules
compiler.options.module.rules = [
pitcher,
...jsRulesForRenderFn,
...(is27 ? [templateCompilerRule] : []),
...clonedRules,
...rules
]
}
}
function createMatcher (fakeFile) {
function createMatcher(fakeFile) {
return (rule, i) => {
// #1201 we need to skip the `include` check when locating the vue rule
const clone = Object.assign({}, rule)
delete clone.include
const normalized = RuleSet.normalizeRule(clone, {}, '')
return (
!rule.enforce &&
normalized.resource &&
normalized.resource(fakeFile)
)
return !rule.enforce && normalized.resource && normalized.resource(fakeFile)
}
}
function cloneRule (rule) {
function cloneRule(rule) {
const { resource, resourceQuery } = rule
// Assuming `test` and `resourceQuery` tests are executed in series and
// synchronously (which is true based on RuleSet's implementation), we can
@@ -122,12 +143,12 @@ function cloneRule (rule) {
let currentResource
const res = Object.assign({}, rule, {
resource: {
test: resource => {
test: (resource) => {
currentResource = resource
return true
}
},
resourceQuery: query => {
resourceQuery: (query) => {
const parsed = qs.parse(query.slice(1))
if (parsed.vue == null) {
return false
@@ -157,5 +178,42 @@ function cloneRule (rule) {
return res
}
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
+145 -60
View File
@@ -1,3 +1,5 @@
const { resolveCompiler } = require('./compiler')
const qs = require('querystring')
const id = 'vue-loader-plugin'
const NS = 'vue-loader'
@@ -6,35 +8,56 @@ const BasicMatcherRulePlugin = require('webpack/lib/rules/BasicMatcherRulePlugin
const RuleSetCompiler = require('webpack/lib/rules/RuleSetCompiler')
const UseEffectRulePlugin = require('webpack/lib/rules/UseEffectRulePlugin')
const objectMatcherRulePlugins = []
try {
const ObjectMatcherRulePlugin = require('webpack/lib/rules/ObjectMatcherRulePlugin')
objectMatcherRulePlugins.push(
new ObjectMatcherRulePlugin('assert', 'assertions'),
new ObjectMatcherRulePlugin('descriptionData')
)
} catch (e) {
const DescriptionDataMatcherRulePlugin = require('webpack/lib/rules/DescriptionDataMatcherRulePlugin')
objectMatcherRulePlugins.push(new DescriptionDataMatcherRulePlugin())
}
const ruleSetCompiler = new RuleSetCompiler([
new BasicMatcherRulePlugin('test', 'resource'),
new BasicMatcherRulePlugin('mimetype'),
new BasicMatcherRulePlugin('dependency'),
new BasicMatcherRulePlugin('include', 'resource'),
new BasicMatcherRulePlugin('exclude', 'resource', true),
new BasicMatcherRulePlugin('resource'),
new BasicMatcherRulePlugin('conditions'),
new BasicMatcherRulePlugin('resource'),
new BasicMatcherRulePlugin('resourceQuery'),
new BasicMatcherRulePlugin('resourceFragment'),
new BasicMatcherRulePlugin('realResource'),
new BasicMatcherRulePlugin('issuer'),
new BasicMatcherRulePlugin('compiler'),
...objectMatcherRulePlugins,
new BasicEffectRulePlugin('type'),
new BasicEffectRulePlugin('sideEffects'),
new BasicEffectRulePlugin('parser'),
new BasicEffectRulePlugin('resolve'),
new BasicEffectRulePlugin('generator'),
new UseEffectRulePlugin()
])
class VueLoaderPlugin {
apply (compiler) {
apply(compiler) {
const normalModule = compiler.webpack
? compiler.webpack.NormalModule
: require('webpack/lib/NormalModule')
// add NS marker so that the loader can detect and report missing plugin
compiler.hooks.compilation.tap(id, compilation => {
const normalModuleLoader = require('webpack/lib/NormalModule').getCompilationHooks(compilation).loader
normalModuleLoader.tap(id, loaderContext => {
compiler.hooks.compilation.tap(id, (compilation) => {
const normalModuleLoader =
normalModule.getCompilationHooks(compilation).loader
normalModuleLoader.tap(id, (loaderContext) => {
loaderContext[NS] = true
})
})
const rules = compiler.options.module.rules
let rawVueRules
let rawVueRule
let vueRules = []
for (const rawRule of rules) {
@@ -42,21 +65,9 @@ class VueLoaderPlugin {
if (rawRule.enforce) {
continue
}
// 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')
}
if (vueRules.length > 0) {
if (rawRule.oneOf) {
@@ -64,29 +75,31 @@ class VueLoaderPlugin {
`[VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf.`
)
}
rawVueRules = rawRule
rawVueRule = rawRule
break
}
}
if (!vueRules.length) {
throw new Error(
`[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)
// get vue-loader options
const vueLoaderUseIndex = vueUse.findIndex(u => {
const vueLoaderUseIndex = vueUse.findIndex((u) => {
return /^vue-loader|(\/|\\|@)vue-loader/.test(u.loader)
})
if (vueLoaderUseIndex < 0) {
throw new Error(
`[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.`
)
}
@@ -101,19 +114,53 @@ class VueLoaderPlugin {
// that targets the corresponding language blocks in *.vue files.
const refs = new Map()
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
// post loader)
const pitcher = {
loader: require.resolve('./loaders/pitcher'),
resourceQuery: query => {
resourceQuery: (query) => {
if (!query) {
return false
}
const parsed = qs.parse(query.slice(1))
return parsed.vue != null
},
@@ -126,73 +173,111 @@ class VueLoaderPlugin {
// replace original rules
compiler.options.module.rules = [
pitcher,
...jsRulesForRenderFn,
...(is27 ? [templateCompilerRule] : []),
...clonedRules,
...rules
]
}
}
let uid = 0
function cloneRule (rawRule, refs) {
const rules = ruleSetCompiler.compileRules(`clonedRuleSet-${++uid}`, [{
rules: [rawRule]
}], refs)
let currentResource
const matcherCache = new WeakMap()
const conditions = rules[0].rules
.map(rule => rule.conditions)
// shallow flat
.reduce((prev, next) => prev.concat(next), [])
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, 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
delete rawRule.loader
delete rawRule.options
rawRule.use = ruleUse
}
const res = Object.assign({}, rawRule, {
resource: resources => {
let currentResource
const res = {
...rawRule,
resource: (resources) => {
currentResource = resources
return true
},
resourceQuery: query => {
resourceQuery: (query) => {
if (!query) {
return false
}
const parsed = qs.parse(query.slice(1))
if (parsed.vue == null) {
return false
}
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)) {
return false
}
}
return true
}
})
}
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)
)
}
return res
+51
View File
@@ -0,0 +1,51 @@
const { resolveCompiler } = require('./compiler')
const clientCache = new WeakMap()
const serverCache = new WeakMap()
exports.resolveScript = function resolveScript(
descriptor,
scopeId,
options,
loaderContext
) {
if (!descriptor.script && !descriptor.scriptSetup) {
return null
}
const { compiler } = resolveCompiler(loaderContext.rootContext, loaderContext)
if (!compiler.compileScript) {
if (descriptor.scriptSetup) {
loaderContext.emitError(
'The version of Vue you are using does not support <script setup>. ' +
'Please upgrade to 2.7 or above.'
)
}
return descriptor.script
}
const isProd =
loaderContext.mode === 'production' || process.env.NODE_ENV === 'production'
const isServer = options.optimizeSSR || loaderContext.target === 'node'
const cacheToUse = isServer ? serverCache : clientCache
const cached = cacheToUse.get(descriptor)
if (cached) {
return cached
}
let resolved = null
try {
resolved = compiler.compileScript(descriptor, {
id: scopeId,
isProd,
babelParserPlugins: options.babelParserPlugins
})
} catch (e) {
loaderContext.emitError(e)
}
cacheToUse.set(descriptor, resolved)
return resolved
}
+13 -15
View File
@@ -4,20 +4,19 @@
// This module is a runtime utility for cleaner component module output and will
// be included in the final webpack user bundle.
export default function normalizeComponent (
export default function normalizeComponent(
scriptExports,
render,
staticRenderFns,
functionalTemplate,
injectStyles,
scopeId,
moduleIdentifier, /* server only */
moduleIdentifier /* server only */,
shadowMode /* vue-cli only */
) {
// Vue.extend constructor export interop
var options = typeof scriptExports === 'function'
? scriptExports.options
: scriptExports
var options =
typeof scriptExports === 'function' ? scriptExports.options : scriptExports
// render functions
if (render) {
@@ -37,7 +36,8 @@ export default function normalizeComponent (
}
var hook
if (moduleIdentifier) { // server build
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
@@ -63,11 +63,11 @@ export default function normalizeComponent (
} else if (injectStyles) {
hook = shadowMode
? function () {
injectStyles.call(
this,
(options.functional ? this.parent : this).$root.$options.shadowRoot
)
}
injectStyles.call(
this,
(options.functional ? this.parent : this).$root.$options.shadowRoot
)
}
: injectStyles
}
@@ -78,16 +78,14 @@ export default function normalizeComponent (
options._injectStyles = hook
// register for functional component in vue file
var originalRender = options.render
options.render = function renderWithStyleInjection (h, context) {
options.render = function renderWithStyleInjection(h, context) {
hook.call(context)
return originalRender(h, context)
}
} else {
// inject component registration as beforeCreate hook
var existing = options.beforeCreate
options.beforeCreate = existing
? [].concat(existing, hook)
: [hook]
options.beforeCreate = existing ? [].concat(existing, hook) : [hook]
}
}
+10 -17
View File
@@ -1,5 +1,9 @@
module.exports = function selectBlock (
const { resolveScript } = require('./resolveScript')
module.exports = function selectBlock(
descriptor,
scopeId,
options,
loaderContext,
query,
appendExtension
@@ -19,14 +23,11 @@ module.exports = function selectBlock (
// script
if (query.type === `script`) {
const script = resolveScript(descriptor, scopeId, 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
}
@@ -36,22 +37,14 @@ module.exports = function selectBlock (
if (appendExtension) {
loaderContext.resourcePath += '.' + (style.lang || 'css')
}
loaderContext.callback(
null,
style.content,
style.map
)
loaderContext.callback(null, style.content, style.map)
return
}
// custom
if (query.type === 'custom' && query.index != null) {
const block = descriptor.customBlocks[query.index]
loaderContext.callback(
null,
block.content,
block.map
)
loaderContext.callback(null, block.content, block.map)
return
}
}
+3 -3
View File
@@ -2,13 +2,13 @@
"_args": [
[
"hash-sum@1.0.2",
"/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series"
"/home/node/nuxt"
]
],
"_from": "hash-sum@1.0.2",
"_id": "hash-sum@1.0.2",
"_inBundle": false,
"_integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
"_integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
"_location": "/vue-loader/hash-sum",
"_phantomChildren": {},
"_requested": {
@@ -26,7 +26,7 @@
],
"_resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
"_spec": "1.0.2",
"_where": "/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series",
"_where": "/home/node/nuxt",
"authors": [
"Nicolas Bevacqua <nicolasbevacqua@gmail.com>"
],
+15 -17
View File
@@ -1,32 +1,32 @@
{
"_args": [
[
"vue-loader@15.9.3",
"/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series"
"vue-loader@15.10.0",
"/home/node/nuxt"
]
],
"_from": "vue-loader@15.9.3",
"_id": "vue-loader@15.9.3",
"_from": "vue-loader@15.10.0",
"_id": "vue-loader@15.10.0",
"_inBundle": false,
"_integrity": "sha512-Y67VnGGgVLH5Voostx8JBZgPQTlDQeOVBLOEsjc2cXbCYBKexSKEpOA56x0YZofoDOTszrLnIShyOX1p9uCEHA==",
"_integrity": "sha512-VU6tuO8eKajrFeBzMssFUP9SvakEeeSi1BxdTH5o3+1yUyrldp8IERkSdXlMI2t4kxF2sqYUDsQY+WJBxzBmZg==",
"_location": "/vue-loader",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "vue-loader@15.9.3",
"raw": "vue-loader@15.10.0",
"name": "vue-loader",
"escapedName": "vue-loader",
"rawSpec": "15.9.3",
"rawSpec": "15.10.0",
"saveSpec": null,
"fetchSpec": "15.9.3"
"fetchSpec": "15.10.0"
},
"_requiredBy": [
"/@nuxt/webpack"
],
"_resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.3.tgz",
"_spec": "15.9.3",
"_where": "/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series",
"_resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.0.tgz",
"_spec": "15.10.0",
"_where": "/home/node/nuxt",
"author": {
"name": "Evan You"
},
@@ -61,14 +61,12 @@
"markdown-loader": "^2.0.2",
"memfs": "^3.1.2",
"mini-css-extract-plugin": "^0.4.1",
"node-sass": "^4.7.2",
"normalize-newline": "^3.0.0",
"null-loader": "^0.1.1",
"postcss-loader": "^2.1.2",
"pug": "^2.0.1",
"pug-plain-loader": "^1.0.0",
"raw-loader": "^0.5.1",
"sass-loader": "^6.0.7",
"source-map": "^0.5.0",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
@@ -81,7 +79,7 @@
"vue-template-compiler": "^2.5.16",
"vuepress": "^0.14.2",
"vuepress-theme-vue": "^1.1.0",
"webpack": "^4.1.0",
"webpack": "^4.46.0",
"webpack-cli": "^3.2.0",
"webpack-dev-server": "^3.1.1",
"webpack-merge": "^4.1.2",
@@ -126,9 +124,9 @@
"docs": "vuepress dev docs",
"docs:build": "vuepress build docs",
"lint": "eslint lib test --fix",
"prepublishOnly": "conventional-changelog -p angular -r 2 -i CHANGELOG.md -s",
"test": "yarn lint && jest --env node"
"prepublishOnly": "conventional-changelog -p angular -r 1 -i CHANGELOG.md -s",
"test": "jest --env node"
},
"typings": "lib/index.d.ts",
"version": "15.9.3"
"version": "15.10.0"
}
+12386
View File
File diff suppressed because it is too large Load Diff