diff --git a/package.json b/package.json
index fd12771f9704061fa694be134751edfd24b0799b..0904f2034303cf11185de9337bb9f9876d04ffc1 100644
--- a/package.json
+++ b/package.json
@@ -75,9 +75,9 @@
"rollup-plugin-uglify": "^6.0.3",
"shell-exec": "^1.0.2",
"strip-json-comments": "^2.0.1",
- "vue": "^2.6.8",
+ "vue": "^2.6.11",
"vue-router": "^3.0.1",
- "vue-template-compiler": "^2.6.8",
+ "vue-template-compiler": "^2.6.11",
"webpack": "^4.18.0",
"webpack-bundle-analyzer": "^3.0.3",
"webpack-virtual-modules": "^0.1.10"
diff --git a/packages/uni-cli-shared/lib/pages.js b/packages/uni-cli-shared/lib/pages.js
index 240734c6b55654b6d94c120ac41be390daa7ee1e..181a4e7a4f83d309a1e790aac4c835c48a7fb84c 100644
--- a/packages/uni-cli-shared/lib/pages.js
+++ b/packages/uni-cli-shared/lib/pages.js
@@ -308,7 +308,7 @@ function getGlobalUsingComponentsCode () {
return ''
}
return generateGlobalUsingComponentsCode(usingComponents)
-}
+}
function getUsingComponentsCode (pagePath) {
const usingComponents = usingComponentsPages[pagePath]
@@ -325,6 +325,35 @@ function addPageUsingComponents (pagePath, usingComponents) {
usingComponentsPages[pagePath] = usingComponents
}
}
+// 存储自动组件
+const autoComponentMap = {}
+
+function addAutoComponent (name) {
+ const options = process.UNI_AUTO_COMPONENTS
+ const opt = options.find(opt => opt.test(name))
+ if (!opt) { // 不匹配
+ return (autoComponentMap[name] = true) // cache
+ }
+ return (autoComponentMap[name] = {
+ name,
+ identifier: capitalize(camelize(name + '-auto-import')),
+ source: name.replace(opt.test, opt.replacement)
+ })
+}
+
+function getAutoComponents (autoComponents) {
+ const components = []
+ autoComponents.forEach(name => {
+ let autoComponent = autoComponentMap[name]
+ if (!autoComponent) {
+ autoComponent = addAutoComponent(name)
+ }
+ if (autoComponent !== true) {
+ components.push(autoComponent)
+ }
+ })
+ return components
+}
module.exports = {
getMainEntry,
@@ -334,7 +363,8 @@ module.exports = {
getPagesJson,
parsePagesJson,
pagesJsonJsFileName,
- addPageUsingComponents,
+ getAutoComponents,
+ addPageUsingComponents,
getUsingComponentsCode,
generateUsingComponentsCode,
getGlobalUsingComponentsCode,
diff --git a/packages/uni-template-compiler/__tests__/demo.js b/packages/uni-template-compiler/__tests__/demo.js
index af51b9ee8ccbcda3e359529952c5be1b4d245004..58352526916c6470885b28ddad8e5702ef184a19 100644
--- a/packages/uni-template-compiler/__tests__/demo.js
+++ b/packages/uni-template-compiler/__tests__/demo.js
@@ -1,7 +1,12 @@
const compiler = require('../lib')
const res = compiler.compile(
`
-
+
+
+
+
+
+
`, {
miniprogram: true,
resourcePath: '/User/fxy/Documents/test.wxml',
@@ -14,9 +19,9 @@ const res = compiler.compile(
mp: {
platform: 'app-plus'
},
- filterModules: ['swipe'],
+ filterModules: ['swipe']
// service: true,
- view: true
+ // view: true
})
console.log(require('util').inspect(res, {
diff --git a/packages/uni-template-compiler/lib/auto-components.js b/packages/uni-template-compiler/lib/auto-components.js
new file mode 100644
index 0000000000000000000000000000000000000000..bb6511847ad65460c58513fd2e341b03dc34acf3
--- /dev/null
+++ b/packages/uni-template-compiler/lib/auto-components.js
@@ -0,0 +1,12 @@
+const {
+ isComponent
+} = require('./util')
+
+module.exports = {
+ preTransformNode (el, options) {
+ if (isComponent(el.tag)) {
+ // 挂在 isReservedTag 上边,可以保证外部访问到
+ (options.isReservedTag.autoComponents || (options.isReservedTag.autoComponents = new Set())).add(el.tag)
+ }
+ }
+}
diff --git a/packages/uni-template-compiler/lib/index.js b/packages/uni-template-compiler/lib/index.js
index 53a0310f5f51cc28c8d3196cbb7dbfa9dec991d5..876abd47056ed89c8dd506f71644cdb50d397a1a 100644
--- a/packages/uni-template-compiler/lib/index.js
+++ b/packages/uni-template-compiler/lib/index.js
@@ -26,8 +26,25 @@ const {
isComponent
} = require('./util')
+function compileTemplate (source, options) {
+ const res = compile(source, options)
+ console.log(options)
+ const {
+ autoComponents
+ } = options.isReservedTag
+ if (autoComponents) {
+ console.log('检测到的自定义组件:' + [...autoComponents])
+ }
+ res.components = `{
+ 'uni-badge': require('@components/uni-badge/uni-badge.vue').default,
+ 'uni-tag': require('@components/uni-tag/uni-tag.vue').default
+ }`
+ return res
+}
+
module.exports = {
compile (source, options = {}) {
+ (options.modules || (options.modules = [])).push(require('./auto-components'))
if (options.service) {
(options.modules || (options.modules = [])).push(require('./app/service'))
options.optimize = false // 启用 staticRenderFns
@@ -37,7 +54,7 @@ module.exports = {
options.getTagNamespace = () => false
try {
- return compile(source, options)
+ return compileTemplate(source, options)
} catch (e) {
console.error(source)
throw e
@@ -47,7 +64,7 @@ module.exports = {
options.optimize = false // 暂不启用 staticRenderFns
options.isReservedTag = (tagName) => false // 均为组件
try {
- return compile(source, options)
+ return compileTemplate(source, options)
} catch (e) {
console.error(source)
throw e
@@ -55,7 +72,7 @@ module.exports = {
}
if (!options.mp) { // h5
- return compile(source, options)
+ return compileTemplate(source, options)
}
(options.modules || (options.modules = [])).push(compilerModule)
@@ -64,7 +81,7 @@ module.exports = {
options.modules.push(compilerAlipayModule)
}
- const res = compile(source, Object.assign(options, {
+ const res = compileTemplate(source, Object.assign(options, {
optimize: false
}))
diff --git a/packages/uni-template-compiler/lib/util.js b/packages/uni-template-compiler/lib/util.js
index bf119e07ee1ef92b62e11529ac089737c60b316f..ef479dd717d93c9118c033f48200d1b66577f585 100644
--- a/packages/uni-template-compiler/lib/util.js
+++ b/packages/uni-template-compiler/lib/util.js
@@ -6,9 +6,9 @@ const {
METHOD_RENDER_LIST
} = require('./constants')
-function cached (fn) {
+function cached(fn) {
const cache = Object.create(null)
- return function cachedFn (str) {
+ return function cachedFn(str) {
const hit = cache[str]
return hit || (cache[str] = fn(str))
}
@@ -21,7 +21,7 @@ const camelize = cached((str) => {
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})
-function getCode (node) {
+function getCode(node) {
return babelGenerate(t.cloneDeep(node), {
compact: true,
jsescOption: {
@@ -31,11 +31,11 @@ function getCode (node) {
}).code
}
-function traverseKey (ast, state) {
+function traverseKey(ast, state) {
let forKey = false
babelTraverse(ast, {
noScope: true,
- ObjectProperty (path) {
+ ObjectProperty(path) {
if (forKey) {
return
}
@@ -44,7 +44,7 @@ function traverseKey (ast, state) {
path.stop()
}
},
- CallExpression (path) {
+ CallExpression(path) {
if (path.node.callee.name === METHOD_RENDER_LIST) {
path.stop()
}
@@ -53,7 +53,7 @@ function traverseKey (ast, state) {
return forKey
}
-function traverseFilter (ast, state) {
+function traverseFilter(ast, state) {
const filterModules = state.options.filterModules
if (!filterModules.length) {
return false
@@ -61,7 +61,7 @@ function traverseFilter (ast, state) {
let isFilter = false
babelTraverse(ast, {
noScope: true,
- Identifier (path) {
+ Identifier(path) {
if (filterModules.includes(path.node.name)) {
const parentNode = path.parent
if ( // t.msg || t['msg']
@@ -81,11 +81,11 @@ function traverseFilter (ast, state) {
return isFilter
}
-function wrapper (code, reverse = false) {
+function wrapper(code, reverse = false) {
return reverse ? `{{!(${code})}}` : `{{${code}}}`
}
-function genCode (node, noWrapper = false, reverse = false, quotes = true) {
+function genCode(node, noWrapper = false, reverse = false, quotes = true) {
if (t.isStringLiteral(node)) {
return reverse ? `!(${node.value})` : node.value
} else if (t.isIdentifier(node)) {
@@ -98,11 +98,11 @@ function genCode (node, noWrapper = false, reverse = false, quotes = true) {
return noWrapper ? code : wrapper(code, reverse)
}
-function getForIndexIdentifier (id) {
+function getForIndexIdentifier(id) {
return `__i${id}__`
}
-function getForKey (forKey, forIndex, state) {
+function getForKey(forKey, forIndex, state) {
if (forKey) {
if (t.isIdentifier(forKey)) {
if (forIndex !== forKey.name) { // 非 forIndex
@@ -121,7 +121,7 @@ function getForKey (forKey, forIndex, state) {
return ''
}
-function processMemberProperty (node, state) {
+function processMemberProperty(node, state) {
if (node.computed) {
const property = node.property
if (t.isNumericLiteral(property)) {
@@ -139,7 +139,7 @@ function processMemberProperty (node, state) {
}
}
-function processMemberExpression (element, state) {
+function processMemberExpression(element, state) {
// item['order']=>item.order
if (t.isMemberExpression(element)) {
element = t.cloneDeep(element)
@@ -152,19 +152,19 @@ function processMemberExpression (element, state) {
babelTraverse(element, {
noScope: true,
- MemberExpression (path) {
+ MemberExpression(path) {
processMemberProperty(path.node, state)
}
})
babelTraverse(element, {
noScope: true,
- MemberExpression (path) {
+ MemberExpression(path) {
if (t.isStringLiteral(path.node.property)) {
path.node.computed = false
}
},
- StringLiteral (path) {
+ StringLiteral(path) {
path.replaceWith(t.identifier(path.node.value))
}
})
@@ -172,7 +172,7 @@ function processMemberExpression (element, state) {
return element
}
-function hasOwn (obj, key) {
+function hasOwn(obj, key) {
return hasOwnProperty.call(obj, key)
}
@@ -182,9 +182,10 @@ const {
getTagName
} = require('./h5')
-function isComponent (tagName) {
+function isComponent(tagName) {
if (
tagName === 'block' ||
+ tagName === 'component' ||
tagName === 'template' ||
tagName === 'keep-alive'
) {
@@ -193,7 +194,21 @@ function isComponent (tagName) {
return !hasOwn(tags, getTagName(tagName.replace('v-uni-', '')))
}
+function makeMap(str, expectsLowerCase) {
+ const map = Object.create(null)
+ const list = str.split(',')
+ for (let i = 0; i < list.length; i++) {
+ map[list[i]] = true
+ }
+ return expectsLowerCase ?
+ val => map[val.toLowerCase()] :
+ val => map[val]
+}
module.exports = {
+ isUnaryTag: makeMap(
+ 'image,area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
+ 'link,meta,param,source,track,wbr'
+ ),
isComponent,
genCode,
getCode,
diff --git a/packages/vue-cli-plugin-hbuilderx/build/vue-loader.conf.js b/packages/vue-cli-plugin-hbuilderx/build/vue-loader.conf.js
index 38cee00a0d09aaeb52cab0ec126508e356e3d24c..2443bced74551b07181db7ba5b393a8f477bf5b5 100644
--- a/packages/vue-cli-plugin-hbuilderx/build/vue-loader.conf.js
+++ b/packages/vue-cli-plugin-hbuilderx/build/vue-loader.conf.js
@@ -1,4 +1,4 @@
-const TAGS = [
+const TAGS = [
'ad',
'text',
'image',
@@ -94,6 +94,7 @@ if (process.env.UNI_USING_NVUE_COMPILER) {
module.exports = {
preserveWhitespace: false,
+ isAppNVue: true,
compiler: require('weex-template-compiler'),
compilerOptions: {
modules
diff --git a/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js b/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js
index cb5dc07cf363e0584355a0d99a7bdc61e01ad208..c45c8d3aff849c2fa4618d82732c0a8dae754f7e 100644
--- a/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js
+++ b/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js
@@ -1,7 +1,7 @@
const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
-const VueLoaderPlugin = require('vue-loader/lib/plugin')
+const VueLoaderPlugin = require('@dcloudio/vue-cli-plugin-uni/packages/vue-loader/lib/plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const {
@@ -36,21 +36,23 @@ const uniPath = process.env.UNI_USING_V8
? '../packages/uni-app-plus-nvue-v8/dist/index.js'
: '../packages/uni-app-plus-nvue/dist/index.js'
-const provide = {}
+const provide = {}
-if (process.env.UNI_USING_V3 || process.env.UNI_USING_NATIVE) {
- provide['uni.getCurrentSubNVue'] = [path.resolve(__dirname, '../packages/uni-app-plus-nvue/dist/get-current-sub-nvue.js'), 'default']
- provide['uni.requireNativePlugin'] = [path.resolve(__dirname, '../packages/uni-app-plus-nvue/dist/require-native-plugin.js'), 'default']
-}
-
-if (!process.env.UNI_USING_V3) {
- if (!process.env.UNI_USING_NATIVE) {
- provide['uni'] = [path.resolve(__dirname, uniPath), 'default']
- }
-
- if (process.env.UNI_USING_V8) {
- provide['plus'] = [path.resolve(__dirname, uniPath), 'weexPlus']
- }
+if (process.env.UNI_USING_V3 || process.env.UNI_USING_NATIVE) {
+ provide['uni.getCurrentSubNVue'] = [path.resolve(__dirname,
+ '../packages/uni-app-plus-nvue/dist/get-current-sub-nvue.js'), 'default']
+ provide['uni.requireNativePlugin'] = [path.resolve(__dirname,
+ '../packages/uni-app-plus-nvue/dist/require-native-plugin.js'), 'default']
+}
+
+if (!process.env.UNI_USING_V3) {
+ if (!process.env.UNI_USING_NATIVE) {
+ provide['uni'] = [path.resolve(__dirname, uniPath), 'default']
+ }
+
+ if (process.env.UNI_USING_V8) {
+ provide['plus'] = [path.resolve(__dirname, uniPath), 'weexPlus']
+ }
}
if (
@@ -110,17 +112,9 @@ const rules = [{
}
},
{
- test: /\.nvue(\?[^?]+)?$/,
- use: [{
- loader: path.resolve(__dirname, '../packages/vue-loader'),
- options: vueLoaderOptions
- }],
- exclude: excludeModuleReg
-},
-{
- test: /\.vue(\?[^?]+)?$/,
+ test: [/\.nvue(\?[^?]+)?$/, /\.vue(\?[^?]+)?$/],
use: [{
- loader: path.resolve(__dirname, '../packages/vue-loader'),
+ loader: require.resolve('@dcloudio/vue-cli-plugin-uni/packages/vue-loader'),
options: vueLoaderOptions
}],
exclude: excludeModuleReg
@@ -322,4 +316,4 @@ module.exports = function () {
zlib: false
}
}
-}
+}
diff --git a/packages/vue-cli-plugin-hbuilderx/module-alias.js b/packages/vue-cli-plugin-hbuilderx/module-alias.js
index f29af64024cec273bda9ac5f9f09ac0eed9a25bb..a9147005d7f6f929777d578bbd2db2eae5b92f9e 100644
--- a/packages/vue-cli-plugin-hbuilderx/module-alias.js
+++ b/packages/vue-cli-plugin-hbuilderx/module-alias.js
@@ -9,16 +9,8 @@ const {
// nvue override
moduleAlias.addAlias('weex-styler', path.resolve(__dirname, 'packages/weex-styler'))
moduleAlias.addAlias('weex-template-compiler', path.resolve(__dirname, 'packages/weex-template-compiler'))
-moduleAlias.addAlias('./compileTemplate', path.resolve(__dirname,
- 'packages/webpack-uni-nvue-loader/lib/compileTemplate'))
-moduleAlias.addAlias('./codegen/styleInjection', path.resolve(__dirname,
- 'packages/webpack-uni-nvue-loader/lib/styleInjection'))
-moduleAlias.addAlias('./templateLoader', (fromPath, request, alias) => {
- if (fromPath.indexOf('vue-loader') !== -1) {
- return path.resolve(__dirname, 'packages/webpack-uni-nvue-loader/lib/templateLoader')
- }
- return request
-})
+moduleAlias.addAlias('./compileTemplate', require.resolve(
+ '@dcloudio/vue-cli-plugin-uni/packages/@vue/component-compiler-utils/dist/compileTemplate'))
if (isInHBuilderX) {
moduleAlias.addAlias('typescript', path.resolve(process.env.UNI_HBUILDERX_PLUGINS,
diff --git a/packages/vue-cli-plugin-hbuilderx/packages/vue-loader/index.js b/packages/vue-cli-plugin-hbuilderx/packages/vue-loader/index.js
deleted file mode 100644
index 532d69ab932a5ad791c3b5461d61214465bf6834..0000000000000000000000000000000000000000
--- a/packages/vue-cli-plugin-hbuilderx/packages/vue-loader/index.js
+++ /dev/null
@@ -1,211 +0,0 @@
-const path = require('path')
-const hash = require('hash-sum')
-const qs = require('querystring')
-const plugin = require('vue-loader/lib/plugin')
-const selectBlock = require('vue-loader/lib/select')
-const loaderUtils = require('loader-utils')
-const { attrsToQuery } = require('vue-loader/lib/codegen/utils')
-const { parse } = require('@vue/component-compiler-utils')
-const genStylesCode = require('../webpack-uni-nvue-loader/lib/styleInjection')
-const { genHotReloadCode } = require('vue-loader/lib/codegen/hotReload')
-const genCustomBlocksCode = require('vue-loader/lib/codegen/customBlocks')
-const componentNormalizerPath = require.resolve('vue-loader/lib/runtime/componentNormalizer')
-const { NS } = require('vue-loader/lib/plugin')
-
-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.`
- ))
- }
- }
-}
-
-function hasRecyclable (template) {
- return !!(template && template.attrs && template.attrs.recyclable)
-}
-
-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.`
- ))
- errorEmitted = true
- }
-
- const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
-
- const {
- target,
- request,
- minimize,
- sourceMap,
- rootContext,
- resourcePath,
- resourceQuery
- } = loaderContext
-
- const rawQuery = resourceQuery.slice(1)
- const inheritQuery = `&${rawQuery}`
- const incomingQuery = qs.parse(rawQuery)
- const options = loaderUtils.getOptions(loaderContext) || {}
-
- const isServer = target === 'node'
- const isShadow = !!options.shadowMode
- const isProduction = 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({
- source,
- compiler: options.compiler || loadTemplateCompiler(loaderContext),
- filename,
- sourceRoot,
- needMap: sourceMap
- })
-
- // 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,
- 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 = (
- !isServer &&
- !isProduction &&
- (descriptor.script || descriptor.template) &&
- options.hotReload !== false
- )
-
- // template
- let templateImport = `var render, staticRenderFns`
- let templateRequest
- const recyclable = hasRecyclable(descriptor.template) // fixed by xxxxxx
- if (descriptor.template) {
- const src = descriptor.template.src || resourcePath
- const idQuery = `&id=${id}`
- const scopedQuery = hasScoped ? `&scoped=true` : ``
- const attrsQuery = attrsToQuery(descriptor.template.attrs)
- const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}${inheritQuery}`
- const request = templateRequest = stringifyRequest(src + query)
- if(recyclable){ // fixed by xxxxxx
- templateImport = `import { render, staticRenderFns, recyclableRender } from ${request}`
- } else {
- 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) {
- stylesCode = genStylesCode(
- loaderContext,
- descriptor.styles,
- id,
- resourcePath,
- stringifyRequest,
- needsHotReload,
- isServer || isShadow // needs explicit injection?
- )
- }
-
- let code = `
-${templateImport}
-${scriptImport}
-${stylesCode}
-
-/* normalize component */
-import normalizer from ${stringifyRequest(`!${componentNormalizerPath}`)}
-var component = normalizer(
- script,
- render,
- staticRenderFns,
- ${hasFunctional ? `true` : `false`},
- ${`null`},
- ${hasScoped ? JSON.stringify(id) : `null`},
- ${isServer ? JSON.stringify(hash(request)) : `null`}
- ${isShadow ? `,true` : ``}
-)
- `.trim() + `\n`
-
- if (descriptor.customBlocks && descriptor.customBlocks.length) {
- code += genCustomBlocksCode(
- descriptor.customBlocks,
- resourcePath,
- resourceQuery,
- stringifyRequest
- )
- }
-
- if (needsHotReload) {
- code += `\n` + genHotReloadCode(id, hasFunctional, templateRequest)
- }
- if(/injectStyles/.test(stylesCode)){// fixed by xxxxxx
- code +=`\ninjectStyles.call(component)`
- }
- // Expose filename. This is used by the devtools and Vue runtime warnings.
- 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, '/'))}`
- } else if (options.exposeFilename) {
- // Libraies can opt-in to expose their components' filenames in production builds.
- // For security reasons, only expose the file's basename in production.
- code += `\ncomponent.options.__file = ${JSON.stringify(filename)}`
- }
- if(recyclable){
- code += `\nrecyclableRender && (component.options["@render"] = recyclableRender)` // fixed by xxxxxx
- }
- code += `\nexport default component.exports`
- // console.log(code)
- return code
-}
-
-module.exports.VueLoaderPlugin = plugin
diff --git a/packages/vue-cli-plugin-hbuilderx/packages/vue-loader/lib/loaders/pitcher.js b/packages/vue-cli-plugin-hbuilderx/packages/vue-loader/lib/loaders/pitcher.js
deleted file mode 100644
index 6af379ba75109d3d97a5e53b8ee5650c1cac28c0..0000000000000000000000000000000000000000
--- a/packages/vue-cli-plugin-hbuilderx/packages/vue-loader/lib/loaders/pitcher.js
+++ /dev/null
@@ -1,160 +0,0 @@
-const qs = require('querystring')
-const loaderUtils = require('loader-utils')
-const hash = require('hash-sum')
-const selfPath = require.resolve('vue-loader/lib/index')
-const templateLoaderPath = require.resolve('vue-loader/lib/loaders/templateLoader')
-const stylePostLoaderPath = require.resolve('vue-loader/lib/loaders/stylePostLoader')
-
-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 res = []
- let seen = false
- loaders.forEach(l => {
- if (!isESLintLoader(l)) {
- res.push(l)
- } else if (!seen) {
- seen = true
- res.push(l)
- }
- })
- return res
-}
-
-const shouldIgnoreCustomBlock = loaders => {
- const actualLoaders = loaders.filter(loader => {
- // vue-loader
- if (loader.path === selfPath) {
- return false
- }
-
- // cache-loader
- if (isCacheLoader(loader)) {
- return false
- }
-
- return true
- })
- return actualLoaders.length === 0
-}
-
-module.exports = code => code
-
-// This pitching loader is responsible for intercepting all vue block requests
-// and transform it into appropriate requests.
-module.exports.pitch = function (remainingRequest) {
- const options = loaderUtils.getOptions(this)
- const { cacheDirectory, cacheIdentifier } = options
- const query = qs.parse(this.resourceQuery.slice(1))
-
- let loaders = this.loaders
-
- // if this is a language block request, eslint-loader may get matched
- // multiple times
- if (query.type) {
- // 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))
- } else {
- // This is a src import. Just make sure there's not more than 1 instance
- // of eslint present.
- loaders = dedupeESLintLoader(loaders)
- }
- }
-
- // remove self
- loaders = loaders.filter(isPitcher)
-
- // do not inject if user uses null-loader to void the type (#1239)
- if (loaders.some(isNullLoader)) {
- return
- }
-
- 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.
- // assumes you'd probably never want to apply the same loader on the same
- // file twice.
- // Exception: in Vue CLI we do need two instances of postcss-loader
- // for user config and inline minification. So we need to dedupe baesd on
- // path AND query to be safe.
- const seen = new Map()
- const loaderStrings = []
-
- 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)
- // loader.request contains both the resolved loader path and its options
- // query (e.g. ??ref-0)
- loaderStrings.push(request)
- }
- })
-
- return loaderUtils.stringifyRequest(this, '-!' + [
- ...loaderStrings,
- this.resourcePath + this.resourceQuery
- ].join('!'))
- }
-
- // Inject style-post-loader before css-loader for scoped CSS and trimming
- if (query.type === `style`) {
- const cssLoaderIndex = loaders.findIndex(isCSSLoader)
- if (cssLoaderIndex > -1) {
- const afterLoaders = loaders.slice(0, cssLoaderIndex + 1)
- const beforeLoaders = loaders.slice(cssLoaderIndex + 1)
- const request = genRequest([
- ...afterLoaders,
- stylePostLoaderPath,
- ...beforeLoaders
- ])
- // console.log(request)
- return `import mod from ${request}; export default mod; export * from ${request}`
- }
- }
-
- // for templates: inject the template compiler & optional cache
- if (query.type === `template`) {
- const path = require('path')
- // fixed by xxxxxx
- const cacheLoader = cacheDirectory && cacheIdentifier
- ? [`${require.resolve('cache-loader')}??uni-cache-loader-template-options`]
- : []
-
- const preLoaders = loaders.filter(isPreLoader)
- const postLoaders = loaders.filter(isPostLoader)
-
- const request = genRequest([
- ...cacheLoader,
- ...postLoaders,
- templateLoaderPath + `??vue-loader-options`,
- ...preLoaders
- ])
- // console.log(request)
- // the template compiler uses esm exports
- return `export * from ${request}`
- }
-
- // if a custom block has no other matching loader other than vue-loader itself
- // or cache-loader, we should ignore it
- if (query.type === `custom` && shouldIgnoreCustomBlock(loaders)) {
- return ``
- }
-
- // When the user defines a rule that has only resourceQuery but no test,
- // both that rule and the cloned rule will match, resulting in duplicated
- // loaders. Therefore it is necessary to perform a dedupe here.
- const request = genRequest(loaders)
- return `import mod from ${request}; export default mod; export * from ${request}`
-}
diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/compileTemplate.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/compileTemplate.js
deleted file mode 100644
index 5e056dc5451e62df8a76d5c77df9e71f0c69cbc6..0000000000000000000000000000000000000000
--- a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/compileTemplate.js
+++ /dev/null
@@ -1,114 +0,0 @@
-"use strict";
-var __importDefault = (this && this.__importDefault) || function (mod) {
- return (mod && mod.__esModule) ? mod : { "default": mod };
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-const assetUrl_1 = __importDefault(require("@vue/component-compiler-utils/dist/templateCompilerModules/assetUrl"));
-const srcset_1 = __importDefault(require("@vue/component-compiler-utils/dist/templateCompilerModules/srcset"));
-const consolidate = require('consolidate');
-const transpile = require('vue-template-es2015-compiler');
-function compileTemplate(options) {
- const { preprocessLang } = options;
- const preprocessor = preprocessLang && consolidate[preprocessLang];
- if (preprocessor) {
- return actuallyCompile(Object.assign({}, options, {
- source: preprocess(options, preprocessor)
- }));
- }
- else if (preprocessLang) {
- return {
- code: `var render = function () {}\n` + `var staticRenderFns = []\n`,
- source: options.source,
- tips: [
- `Component ${options.filename} uses lang ${preprocessLang} for template. Please install the language preprocessor.`
- ],
- errors: [
- `Component ${options.filename} uses lang ${preprocessLang} for template, however it is not installed.`
- ]
- };
- }
- else {
- return actuallyCompile(options);
- }
-}
-exports.compileTemplate = compileTemplate;
-function preprocess(options, preprocessor) {
- const { source, filename, preprocessOptions } = options;
- const finalPreprocessOptions = Object.assign({
- filename
- }, preprocessOptions);
- // Consolidate exposes a callback based API, but the callback is in fact
- // called synchronously for most templating engines. In our case, we have to
- // expose a synchronous API so that it is usable in Jest transforms (which
- // have to be sync because they are applied via Node.js require hooks)
- let res, err;
- preprocessor.render(source, finalPreprocessOptions, (_err, _res) => {
- if (_err)
- err = _err;
- res = _res;
- });
- if (err)
- throw err;
- return res;
-}
-function actuallyCompile(options) {
- const { source, compiler, compilerOptions = {}, transpileOptions = {}, transformAssetUrls, isProduction = process.env.NODE_ENV === 'production', isFunctional = false, optimizeSSR = false, prettify = true } = options;
- const compile = optimizeSSR && compiler.ssrCompile ? compiler.ssrCompile : compiler.compile;
- let finalCompilerOptions = compilerOptions;
- if (transformAssetUrls) {
- const builtInModules = [
- transformAssetUrls === true
- ? assetUrl_1.default()
- : assetUrl_1.default(transformAssetUrls),
- srcset_1.default()
- ];
- finalCompilerOptions = Object.assign({}, compilerOptions, {
- modules: [...builtInModules, ...(compilerOptions.modules || [])]
- });
- }
- const { render, staticRenderFns, tips, errors, '@render': recyclableRender } = compile(source, finalCompilerOptions);
- if (errors && errors.length) {
- return {
- code: `var render = function () {}\n` + `var staticRenderFns = []\n`,
- source,
- tips,
- errors
- };
- }
- else {
- const finalTranspileOptions = Object.assign({}, transpileOptions, {
- transforms: Object.assign({}, transpileOptions.transforms, {
- stripWithFunctional: isFunctional
- })
- });
- const toFunction = (code) => {
- return `function (${isFunctional ? `_h,_vm` : ``}) {${code}}`;
- };
- // transpile code with vue-template-es2015-compiler, which is a forked
- // version of Buble that applies ES2015 transforms + stripping `with` usage
- let code = transpile(`var __render__ = ${toFunction(render)}\n` +
- (recyclableRender ? (`var __recyclableRender__ = ${toFunction(recyclableRender)}\n`) : '') +
- `var __staticRenderFns__ = [${staticRenderFns.map(toFunction)}]`, finalTranspileOptions) + `\n`;
- // #23 we use __render__ to avoid `render` not being prefixed by the
- // transpiler when stripping with, but revert it back to `render` to
- // maintain backwards compat
- code = code.replace(/\s__(render|recyclableRender|staticRenderFns)__\s/g, ' $1 ');
- if (!isProduction) {
- // mark with stripped (this enables Vue to use correct runtime proxy
- // detection)
- code += `render._withStripped = true`;
- if (prettify) {
- code = require('prettier').format(code, {
- semi: false,
- parser: 'babel'
- });
- }
- }
- return {
- code,
- source,
- tips,
- errors
- };
- }
-}
diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/styleInjection.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/styleInjection.js
deleted file mode 100644
index e684809bc2f40dbf41b4ba86ba221fe0448eb116..0000000000000000000000000000000000000000
--- a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/styleInjection.js
+++ /dev/null
@@ -1,134 +0,0 @@
-const { attrsToQuery } = require('vue-loader/lib/codegen/utils')
-const hotReloadAPIPath = JSON.stringify(require.resolve('vue-hot-reload-api'))
-const nonWhitespaceRE = /\S+/
-
-module.exports = function genStyleInjectionCode (
- loaderContext,
- styles,
- id,
- resourcePath,
- stringifyRequest,
- needsHotReload,
- needsExplicitInjection
-) {
- let styleImportsCode = ``
- let styleInjectionCode = ``
- let cssModulesHotReloadCode = ``
-
- let hasCSSModules = false
- const cssModuleNames = new Map()
-
- function genStyleRequest (style, i) {
- const src = style.src || resourcePath
- const attrsQuery = attrsToQuery(style.attrs, 'css')
- const inheritQuery = `&${loaderContext.resourceQuery.slice(1)}`
- // make sure to only pass id when necessary so that we don't inject
- // duplicate tags when multiple components import the same css file
- const idQuery = style.scoped ? `&id=${id}` : ``
- const query = `?vue&type=style&index=${i}${idQuery}${attrsQuery}${inheritQuery}`
- return stringifyRequest(src + query)
- }
-
- function genCSSModulesCode (style, request, i) {
- hasCSSModules = true
-
- const moduleName = style.module === true ? '$style' : style.module
- if (cssModuleNames.has(moduleName)) {
- loaderContext.emitError(`CSS module name ${moduleName} is not unique!`)
- }
- cssModuleNames.set(moduleName, true)
-
- // `(vue-)style-loader` exports the name-to-hash map directly
- // `css-loader` exports it in `.locals`
- const locals = `(style${i}.locals || style${i})`
- const name = JSON.stringify(moduleName)
-
- if (!needsHotReload) {
- styleInjectionCode += `this[${name}] = ${locals}\n`
- } else {
- styleInjectionCode += `
- cssModules[${name}] = ${locals}
- Object.defineProperty(this, ${name}, {
- configurable: true,
- get: function () {
- return cssModules[${name}]
- }
- })
- `
- cssModulesHotReloadCode += `
- module.hot && module.hot.accept([${request}], function () {
- var oldLocals = cssModules[${name}]
- if (oldLocals) {
- var newLocals = require(${request})
- if (JSON.stringify(newLocals) !== JSON.stringify(oldLocals)) {
- cssModules[${name}] = newLocals
- require(${hotReloadAPIPath}).rerender("${id}")
- }
- }
- })
- `
- }
- }
-
- // empty styles: with no `src` specified or only contains whitespaces
- 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__
- // method; otherwise we simply import the styles.
- if (!needsExplicitInjection) {
- styles.forEach((style, i) => {
- // do not generate requests for empty styles
- if (isNotEmptyStyle(style)) {
- const request = genStyleRequest(style, i)
- styleImportsCode += `import style${i} from ${request}\n`
- if (style.module) genCSSModulesCode(style, request, i)
- }
- })
- } else {
- styleInjectionCode = `if(!this.options.style){
- this.options.style = {}
-}
-if(Vue.prototype.__merge_style && Vue.prototype.__$appStyle__){
- Vue.prototype.__merge_style(Vue.prototype.__$appStyle__, this.options.style)
-}
-`
- styles.forEach((style, i) => {
- if (isNotEmptyStyle(style)) {
- const request = genStyleRequest(style, i)
- styleInjectionCode += (
- `if(Vue.prototype.__merge_style){
- Vue.prototype.__merge_style(require(${request}).default, this.options.style)
- }else{
- Object.assign(this.options.style,require(${request}).default)
- }\n`//fixed by xxxxxx 简单处理,与 weex-vue-loader 保持一致
- //`var style${i} = require(${request})\n` +
- //`if (style${i}.__inject__) style${i}.__inject__(context)\n`
- )
- if (style.module) genCSSModulesCode(style, request, i)
- }
- })
- }
-
- if (!needsExplicitInjection && !hasCSSModules) {
- return styleImportsCode
- }
-
- return `
-${styleImportsCode}
-${hasCSSModules && needsHotReload ? `var cssModules = {}` : ``}
-${needsHotReload ? `var disposed = false` : ``}
-
-function injectStyles () {
- ${styleInjectionCode}
-}
-
-${needsHotReload ? `
- module.hot && module.hot.dispose(function (data) {
- disposed = true
- })
-` : ``}
-
-${cssModulesHotReloadCode}
- `.trim()
-}
diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/templateLoader.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/templateLoader.js
deleted file mode 100644
index 249c72115bb0d16bb67b752e82e741a156165726..0000000000000000000000000000000000000000
--- a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/templateLoader.js
+++ /dev/null
@@ -1,93 +0,0 @@
-const qs = require('querystring')
-const loaderUtils = require('loader-utils')
-const { compileTemplate } = require('@vue/component-compiler-utils')
-
-// 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 query = qs.parse(this.resourceQuery.slice(1))
-
- // although this is not the main vue-loader, we can get access to the same
- // vue-loader options because we've set an ident in the plugin and used that
- // ident to create the request for this loader in the pitcher.
- 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 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,
- filename: this.resourcePath // fixed by xxxxxx 传递 filename
- })
-
- // for vue-component-compiler
- const finalOptions = {
- source,
- filename: this.resourcePath,
- compiler,
- compilerOptions,
- // allow customizing behavior of vue-template-es2015-compiler
- transpileOptions: options.transpileOptions,
- transformAssetUrls: options.transformAssetUrls || true,
- isProduction,
- isFunctional,
- optimizeSSR: isServer && options.optimizeSSR !== false,
- prettify: options.prettify
- }
-
- const compiled = compileTemplate(finalOptions)
-
- // tips
- if (compiled.tips && compiled.tips.length) {
- compiled.tips.forEach(tip => {
- loaderContext.emitWarning(typeof tip === 'object' ? tip.msg : tip)
- })
- }
-
- // errors
- if (compiled.errors && compiled.errors.length) {
- // 2.6 compiler outputs errors as objects with range
- if (compiler.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 at ' + finalOptions.filename + ':0' // fixed by xxxxxx
- )
- } else {
- loaderContext.emitError(
- `\n Error compiling template:\n${pad(compiled.source)}\n` +
- compiled.errors.map(e => ` - ${e}`).join('\n') +
- '\n at ' + finalOptions.filename + ':0' // fixed by xxxxxx
- )
- }
- }
-
- const { code } = compiled
-
- if(query.recyclable) {// fixed by xxxxxx
- return code + `\nexport { render, recyclableRender, staticRenderFns }`
- }
- // finish with ESM exports
- return code + `\nexport { render, staticRenderFns }`
-}
-
-function pad (source) {
- return source
- .split(/\r?\n/)
- .map(line => ` ${line}`)
- .join('\n')
-}
diff --git a/packages/vue-cli-plugin-uni/lib/env.js b/packages/vue-cli-plugin-uni/lib/env.js
index 3d0867117b587f2be9103e8298d3c13259c9d89d..b9a840c6e944b752da8de80b59cdddd02aaead8a 100644
--- a/packages/vue-cli-plugin-uni/lib/env.js
+++ b/packages/vue-cli-plugin-uni/lib/env.js
@@ -320,6 +320,13 @@ if (
}
}
+process.UNI_AUTO_COMPONENTS = [{
+ test (str) {
+ return new RegExp('uni-(.*)').test(str)
+ },
+ replacement: '@components/uni-$1/uni-$1.vue'
+}]
+
runByHBuilderX && console.log(`正在编译中...`)
module.exports = {
diff --git a/packages/vue-cli-plugin-uni/lib/h5/compiler-options.js b/packages/vue-cli-plugin-uni/lib/h5/compiler-options.js
index 0ee668b3fb2d5e7e0840d18131ca599a50fb625a..2ccf287395d6f827ad2b8595cdd2b53930baa20f 100644
--- a/packages/vue-cli-plugin-uni/lib/h5/compiler-options.js
+++ b/packages/vue-cli-plugin-uni/lib/h5/compiler-options.js
@@ -4,7 +4,7 @@ const {
const {
isUnaryTag
-} = require('../util')
+} = require('@dcloudio/uni-template-compiler/lib/util')
const simplePathRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/
@@ -69,9 +69,7 @@ module.exports = {
isUnaryTag,
preserveWhitespace: false,
modules: [require('../format-text'), {
- preTransformNode (el, {
- warn
- }) {
+ preTransformNode (el, options) {
fixBooleanAttribute(el)
if (el.tag.indexOf('v-uni-') === 0) {
addTag(el.tag.replace('v-uni-', ''))
diff --git a/packages/vue-cli-plugin-uni/lib/mp-compiler-options.js b/packages/vue-cli-plugin-uni/lib/mp-compiler-options.js
index d5c90f17b921d53cac0239ab1409bac063dfd121..d9593e6a31ebfa048f52e30524d956597f4a6134 100644
--- a/packages/vue-cli-plugin-uni/lib/mp-compiler-options.js
+++ b/packages/vue-cli-plugin-uni/lib/mp-compiler-options.js
@@ -3,10 +3,15 @@ const {
convertStaticStyle
} = require('@dcloudio/uni-cli-shared')
+const {
+ isUnaryTag
+} = require('@dcloudio/uni-template-compiler/lib/util')
+
module.exports = {
+ isUnaryTag,
preserveWhitespace: false,
modules: [require('./format-text'), {
- preTransformNode (el, {
+ preTransformNode(el, {
warn
}) {
if (el.attrsMap) {
@@ -35,7 +40,7 @@ module.exports = {
})
}
},
- postTransformNode (el) {
+ postTransformNode(el) {
if (process.env.UNI_PLATFORM === 'mp-alipay') {
if (el.tag === 'slot') {
if (!el.children.length) {
diff --git a/packages/vue-cli-plugin-uni/lib/util.js b/packages/vue-cli-plugin-uni/lib/util.js
index fd85fa57024c5892c14dd1b42f9515635e1023c1..06bccc219d3683b5052330347af6c9d6271e40e4 100644
--- a/packages/vue-cli-plugin-uni/lib/util.js
+++ b/packages/vue-cli-plugin-uni/lib/util.js
@@ -1,20 +1,5 @@
-function makeMap (str, expectsLowerCase) {
- const map = Object.create(null)
- const list = str.split(',')
- for (let i = 0; i < list.length; i++) {
- map[list[i]] = true
- }
- return expectsLowerCase
- ? val => map[val.toLowerCase()]
- : val => map[val]
-}
-
let partialIdentifier = false
module.exports = {
- isUnaryTag: makeMap(
- 'image,area,base,br,col,embed,frame,hr,img,input,isindex,keygen,' +
- 'link,meta,param,source,track,wbr'
- ),
getPartialIdentifier () {
if (!partialIdentifier) {
partialIdentifier = {
diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/codegen/styleInjection.js b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/codegen/styleInjection.js
index 9a8cfc99aad54271edbaee6a994b5ece208a8beb..0e1cf0e737e38e1692259e9c64b9adc017936514 100644
--- a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/codegen/styleInjection.js
+++ b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/codegen/styleInjection.js
@@ -9,7 +9,7 @@ module.exports = function genStyleInjectionCode (
resourcePath,
stringifyRequest,
needsHotReload,
- needsExplicitInjection
+ needsExplicitInjection // fixed by xxxxxx nvue 时,指定了 target 为 node,激活 needsExplicitInjection
) {
let styleImportsCode = ``
let styleInjectionCode = ``
@@ -85,13 +85,25 @@ module.exports = function genStyleInjectionCode (
if (style.module) genCSSModulesCode(style, request, i)
}
})
- } else {
+ } else { // fixed by xxxxxx nvue style
+ styleInjectionCode = `if(!this.options.style){
+ this.options.style = {}
+}
+if(Vue.prototype.__merge_style && Vue.prototype.__$appStyle__){
+ Vue.prototype.__merge_style(Vue.prototype.__$appStyle__, this.options.style)
+}
+`
styles.forEach((style, i) => {
if (isNotEmptyStyle(style)) {
const request = genStyleRequest(style, i)
styleInjectionCode += (
- `var style${i} = require(${request})\n` +
- `if (style${i}.__inject__) style${i}.__inject__(context)\n`
+ `if(Vue.prototype.__merge_style){
+ Vue.prototype.__merge_style(require(${request}).default, this.options.style)
+ }else{
+ Object.assign(this.options.style,require(${request}).default)
+ }\n`//fixed by xxxxxx 简单处理,与 weex-vue-loader 保持一致
+ //`var style${i} = require(${request})\n` +
+ //`if (style${i}.__inject__) style${i}.__inject__(context)\n`
)
if (style.module) genCSSModulesCode(style, request, i)
}
diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.d.ts b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.d.ts
index b21db5c169b84c5d09be28fdcaafa1b39a23de92..28a4e3c5f28785cac7ac2644c6056e0e35a22b3f 100644
--- a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.d.ts
+++ b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.d.ts
@@ -1,5 +1,5 @@
import { Plugin } from 'webpack'
-import { VueTemplateCompiler } from '@vue/component-compiler-utils/lib/types'
+import { VueTemplateCompiler } from '@vue/component-compiler-utils/dist/types'
import { CompilerOptions } from 'vue-template-compiler'
declare namespace VueLoader {
diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.js b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.js
index 8023f68eb46540d73221c4c4fe10ebf631718220..3b9ac9a4f0dd2cfc1766e01e0d8322e475d84ea5 100644
--- a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.js
+++ b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/index.js
@@ -108,21 +108,26 @@ module.exports = function (source) {
)
// template
- let templateImport = `var render, staticRenderFns`
+ // fixed by xxxxxx (recyclable,auto components)
+ let recyclable
+ let templateImport = `var render, staticRenderFns, recyclableRender, components`
let templateRequest
if (descriptor.template) {
+ // fixed by xxxxxx
+ recyclable = options.isAppNVue && !!(template.attrs && template.attrs.recyclable)
const src = descriptor.template.src || resourcePath
const idQuery = `&id=${id}`
const scopedQuery = hasScoped ? `&scoped=true` : ``
const attrsQuery = attrsToQuery(descriptor.template.attrs)
const query = `?vue&type=template${idQuery}${scopedQuery}${attrsQuery}${inheritQuery}`
const request = templateRequest = stringifyRequest(src + query)
- templateImport = `import { render, staticRenderFns } from ${request}`
+ // fixed by xxxxxx (auto components)
+ templateImport = `import { render, staticRenderFns, recyclableRender, components } from ${request}`
}
// script
let scriptImport = `var script = {}`
- if (descriptor.script) {// fixed by xxxxxx view 层的 script 在 script-loader 中提取自定义组件信息
+ if (descriptor.script) {
const src = descriptor.script.src || resourcePath
const attrsQuery = attrsToQuery(descriptor.script.attrs, 'js')
const query = `?vue&type=script${attrsQuery}${inheritQuery}`
@@ -135,7 +140,8 @@ module.exports = function (source) {
// styles
let stylesCode = ``
- if (options.isAppView && descriptor.styles.length) {// fixed by xxxxxx 仅限 view 层
+ // fixed by xxxxxx 仅限 view 层
+ if (!options.isAppService && descriptor.styles.length) {
stylesCode = genStylesCode(
loaderContext,
descriptor.styles,
@@ -146,7 +152,7 @@ module.exports = function (source) {
isServer || isShadow // needs explicit injection?
)
}
-
+ // fixed by xxxxxx (injectStyles,auto components)
let code = `
${templateImport}
${scriptImport}
@@ -159,10 +165,11 @@ var component = normalizer(
render,
staticRenderFns,
${hasFunctional ? `true` : `false`},
- ${/injectStyles/.test(stylesCode) ? `injectStyles` : `null`},
+ ${options.isAppNVue ? `null`: (/injectStyles/.test(stylesCode) ? `injectStyles` : `null`)},
${hasScoped ? JSON.stringify(id) : `null`},
${isServer ? JSON.stringify(hash(request)) : `null`}
- ${isShadow ? `,true` : ``}
+ ${isShadow ? `,true` : ``},
+ components
)
`.trim() + `\n`
@@ -178,7 +185,10 @@ var component = normalizer(
if (needsHotReload) {
code += `\n` + genHotReloadCode(id, hasFunctional, templateRequest)
}
-
+ // fixed by xxxxxx (app-nvue injectStyles)
+ if (options.isAppNVue && /injectStyles/.test(stylesCode)) {
+ code +=`\ninjectStyles.call(component)`
+ }
// Expose filename. This is used by the devtools and Vue runtime warnings.
if (!isProduction) {
// Expose the file's full path in development, so that it can be opened
@@ -189,7 +199,9 @@ var component = normalizer(
// For security reasons, only expose the file's basename in production.
code += `\ncomponent.options.__file = ${JSON.stringify(filename)}`
}
-
+ if (recyclable) { // fixed by xxxxxx app-plus recyclable
+ code += `\nrecyclableRender && (component.options["@render"] = recyclableRender)` // fixed by xxxxxx
+ }
code += `\nexport default component.exports`
// console.log(code)
return code
diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/pitcher.js b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/pitcher.js
index 5cb3f46e238e56a5df6bf222701d73384af7a95a..35106445ef71d4b7b894f360c91487081fe48ed5 100644
--- a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/pitcher.js
+++ b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/pitcher.js
@@ -127,16 +127,20 @@ module.exports.pitch = function (remainingRequest) {
// 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'
+ // })}`]
+ // : []
+ // fixed by xxxxxx 定制 template cache
const cacheLoader = cacheDirectory && cacheIdentifier
- ? [`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'
- })}`]
+ ? [`${require.resolve('cache-loader')}??uni-cache-loader-template-options`]
: []
const preLoaders = loaders.filter(isPreLoader)
diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js
index 57bab4e97733cb31f3655f90480d05efcb019cca..ada42e96bd480c4765d9d5271394cafacf8803b5 100644
--- a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js
+++ b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/loaders/templateLoader.js
@@ -64,21 +64,21 @@ module.exports = function (source) {
const frame = compiler.generateCodeFrame(source, start, end)
return ` ${msg}\n\n${pad(frame)}`
}).join(`\n\n`) +
- '\n'
+ '\n at ' + finalOptions.filename + ':0' // fixed by xxxxxx
)
} else {
loaderContext.emitError(
`\n Error compiling template:\n${pad(compiled.source)}\n` +
compiled.errors.map(e => ` - ${e}`).join('\n') +
- '\n'
+ '\n at ' + finalOptions.filename + ':0' // fixed by xxxxxx
)
}
}
const { code } = compiled
-
- // finish with ESM exports
- return code + `\nexport { render, staticRenderFns }`
+ // fixed by xxxxxx recyclableRender, components
+ // finish with ESM exports
+ return code + `\nexport { render, staticRenderFns, recyclableRender, components }`
}
function pad (source) {
diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin-webpack4.js b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin-webpack4.js
new file mode 100644
index 0000000000000000000000000000000000000000..77fb6568144fc9f0f0ace0b98d435146555d8b4f
--- /dev/null
+++ b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin-webpack4.js
@@ -0,0 +1,157 @@
+const qs = require('querystring')
+const RuleSet = require('webpack/lib/RuleSet')
+
+const id = 'vue-loader-plugin'
+const NS = 'vue-loader'
+
+class VueLoaderPlugin {
+ 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 => {
+ const normalModuleLoader = compilation.hooks.normalModuleLoader
+ normalModuleLoader.tap(id, loaderContext => {
+ loaderContext[NS] = true
+ })
+ })
+ } else {
+ // webpack < 4
+ compiler.plugin('compilation', compilation => {
+ compilation.plugin('normal-module-loader', loaderContext => {
+ loaderContext[NS] = true
+ })
+ })
+ }
+
+ // use webpack's RuleSet utility to normalize user rules
+ const rawRules = compiler.options.module.rules
+ const { rules } = new RuleSet(rawRules)
+
+ // find the rule that applies to vue files
+ let vueRuleIndex = rawRules.findIndex(createMatcher(`foo.vue`))
+ if (vueRuleIndex < 0) {
+ vueRuleIndex = rawRules.findIndex(createMatcher(`foo.vue.html`))
+ }
+ const vueRule = rules[vueRuleIndex]
+
+ 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.`
+ )
+ }
+
+ if (vueRule.oneOf) {
+ throw new Error(
+ `[VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf.`
+ )
+ }
+
+ // get the normlized "use" for vue files
+ const vueUse = vueRule.use
+ // get vue-loader options
+ 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 vue-loader options has a known ident so that we can share
+ // options by reference in the template-loader by using a ref query like
+ // template-loader??vue-loader-options
+ const vueLoaderUse = vueUse[vueLoaderUseIndex]
+ vueLoaderUse.ident = 'vue-loader-options'
+ vueLoaderUse.options = vueLoaderUse.options || {}
+
+ // for each user rule (expect 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)
+
+ // global pitcher (responsible for injecting template compiler loader & CSS
+ // post loader)
+ const pitcher = {
+ loader: require.resolve('./loaders/pitcher'),
+ resourceQuery: query => {
+ const parsed = qs.parse(query.slice(1))
+ return parsed.vue != null
+ },
+ options: {
+ cacheDirectory: vueLoaderUse.options.cacheDirectory,
+ cacheIdentifier: vueLoaderUse.options.cacheIdentifier
+ }
+ }
+
+ // replace original rules
+ compiler.options.module.rules = [
+ pitcher,
+ ...clonedRules,
+ ...rules
+ ]
+ }
+}
+
+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)
+ )
+ }
+}
+
+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
+ // save the current resource being matched from `test` so that we can access
+ // it in `resourceQuery`. This ensures when we use the normalized rule's
+ // resource check, include/exclude are matched correctly.
+ let currentResource
+ const res = Object.assign({}, rule, {
+ resource: {
+ test: resource => {
+ currentResource = resource
+ return true
+ }
+ },
+ resourceQuery: query => {
+ const parsed = qs.parse(query.slice(1))
+ if (parsed.vue == null) {
+ return false
+ }
+ if (resource && parsed.lang == null) {
+ return false
+ }
+ const fakeResourcePath = `${currentResource}.${parsed.lang}`
+ if (resource && !resource(fakeResourcePath)) {
+ return false
+ }
+ if (resourceQuery && !resourceQuery(query)) {
+ return false
+ }
+ return true
+ }
+ })
+
+ if (rule.oneOf) {
+ res.oneOf = rule.oneOf.map(cloneRule)
+ }
+
+ return res
+}
+
+VueLoaderPlugin.NS = NS
+module.exports = VueLoaderPlugin
diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin-webpack5.js b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin-webpack5.js
new file mode 100644
index 0000000000000000000000000000000000000000..a3ec14dff3d016ca5b6a5960f7703d176a39f58a
--- /dev/null
+++ b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin-webpack5.js
@@ -0,0 +1,193 @@
+const qs = require('querystring')
+const id = 'vue-loader-plugin'
+const NS = 'vue-loader'
+const BasicEffectRulePlugin = require('webpack/lib/rules/BasicEffectRulePlugin')
+const BasicMatcherRulePlugin = require('webpack/lib/rules/BasicMatcherRulePlugin')
+const RuleSetCompiler = require('webpack/lib/rules/RuleSetCompiler')
+const UseEffectRulePlugin = require('webpack/lib/rules/UseEffectRulePlugin')
+
+const ruleSetCompiler = new RuleSetCompiler([
+ new BasicMatcherRulePlugin('test', 'resource'),
+ new BasicMatcherRulePlugin('include', 'resource'),
+ new BasicMatcherRulePlugin('exclude', 'resource', true),
+ new BasicMatcherRulePlugin('resource'),
+ new BasicMatcherRulePlugin('conditions'),
+ new BasicMatcherRulePlugin('resourceQuery'),
+ new BasicMatcherRulePlugin('realResource'),
+ new BasicMatcherRulePlugin('issuer'),
+ new BasicMatcherRulePlugin('compiler'),
+ new BasicEffectRulePlugin('type'),
+ new BasicEffectRulePlugin('sideEffects'),
+ new BasicEffectRulePlugin('parser'),
+ new BasicEffectRulePlugin('resolve'),
+ new UseEffectRulePlugin()
+])
+
+class VueLoaderPlugin {
+ apply (compiler) {
+ // 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 => {
+ loaderContext[NS] = true
+ })
+ })
+
+ const rules = compiler.options.module.rules
+ let rawVueRules
+ let vueRules = []
+
+ for (const rawRule of rules) {
+ // 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'
+ })
+
+ if (!vueRules.length) {
+ vueRules = ruleSet.exec({
+ resource: 'foo.vue.html'
+ })
+ }
+ if (vueRules.length > 0) {
+ if (rawRule.oneOf) {
+ throw new Error(
+ `[VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf.`
+ )
+ }
+ rawVueRules = 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.`
+ )
+ }
+
+ // get the normlized "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 => {
+ 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 vue-loader options has a known ident so that we can share
+ // options by reference in the template-loader by using a ref query like
+ // template-loader??vue-loader-options
+ const vueLoaderUse = vueUse[vueLoaderUseIndex]
+ vueLoaderUse.ident = 'vue-loader-options'
+ vueLoaderUse.options = vueLoaderUse.options || {}
+
+ // for each user rule (expect the vue rule), create a cloned rule
+ // 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))
+
+ // fix conflict with config.loader and config.options when using config.use
+ delete rawVueRules.loader
+ delete rawVueRules.options
+ rawVueRules.use = vueUse
+
+ // global pitcher (responsible for injecting template compiler loader & CSS
+ // post loader)
+ const pitcher = {
+ loader: require.resolve('./loaders/pitcher'),
+ resourceQuery: query => {
+ const parsed = qs.parse(query.slice(1))
+ return parsed.vue != null
+ },
+ options: {
+ cacheDirectory: vueLoaderUse.options.cacheDirectory,
+ cacheIdentifier: vueLoaderUse.options.cacheIdentifier
+ }
+ }
+
+ // replace original rules
+ compiler.options.module.rules = [
+ pitcher,
+ ...clonedRules,
+ ...rules
+ ]
+ }
+}
+
+function cloneRule (rawRule, refs) {
+ const rules = ruleSetCompiler.compileRules('ruleSet', [{
+ rules: [rawRule]
+ }], refs)
+ let currentResource
+
+ const conditions = rules[0].rules
+ .map(rule => rule.conditions)
+ // shallow flat
+ .reduce((prev, next) => prev.concat(next), [])
+
+ // 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), [])
+
+ // 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 => {
+ currentResource = resources
+ return true
+ },
+ resourceQuery: query => {
+ const parsed = qs.parse(query.slice(1))
+ if (parsed.vue == null) {
+ return false
+ }
+ if (!conditions) {
+ return false
+ }
+ const fakeResourcePath = `${currentResource}.${parsed.lang}`
+ for (const condition of conditions) {
+ // add support for resourceQuery
+ const request = condition.property === 'resourceQuery' ? query : fakeResourcePath
+ if (condition && !condition.fn(request)) {
+ return false
+ }
+ }
+ return true
+ }
+ })
+
+ delete res.test
+
+ if (rawRule.oneOf) {
+ res.oneOf = rawRule.oneOf.map(rule => cloneRule(rule, refs))
+ }
+
+ return res
+}
+
+VueLoaderPlugin.NS = NS
+module.exports = VueLoaderPlugin
diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin.js b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin.js
index a5d91a2f289c69a63630576be470836a7f7a3d77..f9bbb0d7d353b70a799c647e9519beb3f41f0b0b 100644
--- a/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin.js
+++ b/packages/vue-cli-plugin-uni/packages/vue-loader/lib/plugin.js
@@ -1,163 +1,12 @@
-const qs = require('querystring')
-const RuleSet = require('webpack/lib/RuleSet')
-
-const id = 'vue-loader-plugin'
-const NS = 'vue-loader'
-
-class VueLoaderPlugin {
- 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 => {
- let normalModuleLoader
- if (Object.isFrozen(compilation.hooks)) {
- // webpack 5
- normalModuleLoader = require('webpack/lib/NormalModule').getCompilationHooks(compilation).loader
- } else {
- normalModuleLoader = compilation.hooks.normalModuleLoader
- }
- normalModuleLoader.tap(id, loaderContext => {
- loaderContext[NS] = true
- })
- })
- } else {
- // webpack < 4
- compiler.plugin('compilation', compilation => {
- compilation.plugin('normal-module-loader', loaderContext => {
- loaderContext[NS] = true
- })
- })
- }
-
- // use webpack's RuleSet utility to normalize user rules
- const rawRules = compiler.options.module.rules
- const { rules } = new RuleSet(rawRules)
-
- // find the rule that applies to vue files
- let vueRuleIndex = rawRules.findIndex(createMatcher(`foo.vue`))
- if (vueRuleIndex < 0) {
- vueRuleIndex = rawRules.findIndex(createMatcher(`foo.vue.html`))
- }
- const vueRule = rules[vueRuleIndex]
-
- 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.`
- )
- }
-
- if (vueRule.oneOf) {
- throw new Error(
- `[VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf.`
- )
- }
-
- // get the normlized "use" for vue files
- const vueUse = vueRule.use
- // get vue-loader options
- 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 vue-loader options has a known ident so that we can share
- // options by reference in the template-loader by using a ref query like
- // template-loader??vue-loader-options
- const vueLoaderUse = vueUse[vueLoaderUseIndex]
- vueLoaderUse.ident = 'vue-loader-options'
- vueLoaderUse.options = vueLoaderUse.options || {}
-
- // for each user rule (expect 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)
-
- // global pitcher (responsible for injecting template compiler loader & CSS
- // post loader)
- const pitcher = {
- loader: require.resolve('./loaders/pitcher'),
- resourceQuery: query => {
- const parsed = qs.parse(query.slice(1))
- return parsed.vue != null
- },
- options: {
- cacheDirectory: vueLoaderUse.options.cacheDirectory,
- cacheIdentifier: vueLoaderUse.options.cacheIdentifier
- }
- }
-
- // replace original rules
- compiler.options.module.rules = [
- pitcher,
- ...clonedRules,
- ...rules
- ]
- }
-}
-
-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)
- )
- }
-}
-
-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
- // save the current resource being matched from `test` so that we can access
- // it in `resourceQuery`. This ensures when we use the normalized rule's
- // resource check, include/exclude are matched correctly.
- let currentResource
- const res = Object.assign({}, rule, {
- resource: {
- test: resource => {
- currentResource = resource
- return true
- }
- },
- resourceQuery: query => {
- const parsed = qs.parse(query.slice(1))
- if (parsed.vue == null) {
- return false
- }
- if (resource && parsed.lang == null) {
- return false
- }
- const fakeResourcePath = `${currentResource}.${parsed.lang}`
- if (resource && !resource(fakeResourcePath)) {
- return false
- }
- if (resourceQuery && !resourceQuery(query)) {
- return false
- }
- return true
- }
- })
-
- if (rule.oneOf) {
- res.oneOf = rule.oneOf.map(cloneRule)
- }
-
- return res
+const webpack = require('webpack')
+let VueLoaderPlugin = null
+
+if (webpack.version && webpack.version[0] > 4) {
+ // webpack5 and upper
+ VueLoaderPlugin = require('./plugin-webpack5')
+} else {
+ // webpack4 and lower
+ VueLoaderPlugin = require('./plugin-webpack4')
}
-VueLoaderPlugin.NS = NS
module.exports = VueLoaderPlugin
diff --git a/packages/vue-cli-plugin-uni/packages/vue-loader/package.json b/packages/vue-cli-plugin-uni/packages/vue-loader/package.json
index 8943087cd63f8f5144a41f648fea66250396bf9d..2ca8e99c3664a9199a923421adc2922e457fc393 100644
--- a/packages/vue-cli-plugin-uni/packages/vue-loader/package.json
+++ b/packages/vue-cli-plugin-uni/packages/vue-loader/package.json
@@ -1,6 +1,6 @@
{
"name": "vue-loader",
- "version": "15.7.1",
+ "version": "15.8.3",
"description": "Vue single-file component loader for Webpack",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
@@ -34,10 +34,15 @@
},
"peerDependencies": {
"css-loader": "*",
- "webpack": "^4.1.0 || ^5.0.0-0"
+ "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "cache-loader": {
+ "optional": true
+ }
},
"dependencies": {
- "@vue/component-compiler-utils": "^3.0.0",
+ "@vue/component-compiler-utils": "^3.1.0",
"hash-sum": "^1.0.2",
"loader-utils": "^1.1.0",
"vue-hot-reload-api": "^2.3.0",
diff --git a/packages/vue-cli-plugin-uni/packages/webpack-uni-app-loader/using-components.js b/packages/vue-cli-plugin-uni/packages/webpack-uni-app-loader/using-components.js
index c3c9139c22f12dc1a6252a807fcc5016c9946172..6a8104b4e746c5d1f7a74c622267fab652f1e620 100644
--- a/packages/vue-cli-plugin-uni/packages/webpack-uni-app-loader/using-components.js
+++ b/packages/vue-cli-plugin-uni/packages/webpack-uni-app-loader/using-components.js
@@ -13,5 +13,10 @@ module.exports = function(content, map) {
const resourcePath = removeExt(
normalizePath(path.relative(process.env.UNI_INPUT_DIR, this.resourcePath))
)
- return content + getUsingComponentsCode(resourcePath)
+ content = content + getUsingComponentsCode(resourcePath)
+ // TODO 自动导入 vue 组件(h5,小程序,app[vue,nvue])
+ // 1. 需要 template-loader 解析出所有自定义组件()
+ // 2. 根据自定义组件信息生成引用代码
+ // 3. node-modules中的组件不提供自动导入
+ return content
}
diff --git a/src/core/runtime/mp/parser/data-parser.bak.js b/src/core/runtime/mp/parser/data-parser.bak.js
deleted file mode 100644
index 82c91b9422aefb072d778dd0378db4154cd6f449..0000000000000000000000000000000000000000
--- a/src/core/runtime/mp/parser/data-parser.bak.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export function parseData (data, vueComponentOptions) {
- if (!data) {
- return
- }
- const dataJson = JSON.stringify(data)
- vueComponentOptions.data = function () {
- return JSON.parse(dataJson)
- }
-}
diff --git a/yarn.lock b/yarn.lock
index df5a5cf2b00584bc255939f6e892c6530ed8a2fb..709b87a9ad35b728d46c598e58f2cf49469fdf1f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8912,9 +8912,9 @@ vue-style-loader@^4.1.0:
hash-sum "^1.0.2"
loader-utils "^1.0.2"
-vue-template-compiler@^2.6.8:
- version "2.6.10"
- resolved "https://registry.npm.taobao.org/vue-template-compiler/download/vue-template-compiler-2.6.10.tgz#323b4f3495f04faa3503337a82f5d6507799c9cc"
+vue-template-compiler@^2.6.11:
+ version "2.6.11"
+ resolved "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080"
dependencies:
de-indent "^1.0.2"
he "^1.1.0"
@@ -8923,9 +8923,9 @@ vue-template-es2015-compiler@^1.9.0:
version "1.9.1"
resolved "https://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
-vue@^2.6.8:
- version "2.6.10"
- resolved "https://registry.npm.taobao.org/vue/download/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
+vue@^2.6.11:
+ version "2.6.11"
+ resolved "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
w3c-hr-time@^1.0.1:
version "1.0.1"