forked from daren.hsu/line_push
update
This commit is contained in:
+5
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user