diff --git a/packages/uni-cli-shared/lib/manifest.js b/packages/uni-cli-shared/lib/manifest.js index cbec364db688833f920011748ec3292c7a8eea53..5b53581abaaaee1c0b30cabeda62a80667f4090f 100644 --- a/packages/uni-cli-shared/lib/manifest.js +++ b/packages/uni-cli-shared/lib/manifest.js @@ -85,8 +85,7 @@ function getH5Options (manifestJson) { } /* eslint-disable no-mixed-operators */ - h5.template = h5.template && path.resolve(process.env.UNI_INPUT_DIR, h5.template) || path.resolve(__dirname, - '../../../../public/index.html') + h5.template = h5.template && path.resolve(process.env.UNI_INPUT_DIR, h5.template) || path.resolve(require('./util').getCLIContext(), 'public/index.html') h5.devServer = h5.devServer || {} @@ -103,4 +102,4 @@ module.exports = { parseManifestJson, getNetworkTimeout, getH5Options -} +} diff --git a/packages/uni-cli-shared/lib/util.js b/packages/uni-cli-shared/lib/util.js index 205634c1ec3fe387a471d6a48efb11c1b18e8f54..26e836fd3e0b6d07ff438abb7682c5856d912688 100644 --- a/packages/uni-cli-shared/lib/util.js +++ b/packages/uni-cli-shared/lib/util.js @@ -14,6 +14,24 @@ try { const isInHBuilderX = !!aboutPkg const isInHBuilderXAlpha = !!(isInHBuilderX && aboutPkg.alpha) +function getCLIContext () { + var context = path.resolve(__dirname, '../../../../') + // const isInHBuilderX = fs.existsSync(path.resolve(context, 'bin/uniapp-cli.js')) + if (isInHBuilderX) { + return context + } + const pnpmFind = __dirname.match(/.+?[\/\\].pnpm[\/\\]/) + if (pnpmFind) { + const pnpm = pnpmFind[0] + context = path.resolve(pnpm, '../../') + } + const isInCLI = fs.existsSync(path.resolve(context, './src')) + if (isInCLI) { + return context + } + return process.cwd() +} + function removeExt (str, ext) { if (ext) { const reg = new RegExp(ext.replace(/\./, '\\.') + '$') @@ -105,6 +123,7 @@ const _hasOwnProperty = Object.prototype.hasOwnProperty module.exports = { isInHBuilderX, isInHBuilderXAlpha, + getCLIContext, normalizeNodeModules, md5, hasOwn (obj, key) { diff --git a/packages/uni-mp-weixin/dist/index.js b/packages/uni-mp-weixin/dist/index.js index 20eadea4c9efa768d1b6c64667bb90bf92cea41d..8e2d425578bd2fbdf72460aee3da7c287783e210 100644 --- a/packages/uni-mp-weixin/dist/index.js +++ b/packages/uni-mp-weixin/dist/index.js @@ -1,82 +1,82 @@ import Vue from 'vue'; import { initVueI18n } from '@dcloudio/uni-i18n'; -let realAtob; - -const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; -const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; - -if (typeof atob !== 'function') { - realAtob = function (str) { - str = String(str).replace(/[\t\n\f\r ]+/g, ''); - if (!b64re.test(str)) { throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.") } - - // Adding the padding if missing, for semplicity - str += '=='.slice(2 - (str.length & 3)); - var bitmap; var result = ''; var r1; var r2; var i = 0; - for (; i < str.length;) { - bitmap = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12 | - (r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++))); - - result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) - : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) - : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255); - } - return result - }; -} else { - // 注意atob只能在全局对象上调用,例如:`const Base64 = {atob};Base64.atob('xxxx')`是错误的用法 - realAtob = atob; -} - -function b64DecodeUnicode (str) { - return decodeURIComponent(realAtob(str).split('').map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) - }).join('')) -} - -function getCurrentUserInfo () { - const token = ( wx).getStorageSync('uni_id_token') || ''; - const tokenArr = token.split('.'); - if (!token || tokenArr.length !== 3) { - return { - uid: null, - role: [], - permission: [], - tokenExpired: 0 - } - } - let userInfo; - try { - userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); - } catch (error) { - throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message) - } - userInfo.tokenExpired = userInfo.exp * 1000; - delete userInfo.exp; - delete userInfo.iat; - return userInfo -} - -function uniIdMixin (Vue) { - Vue.prototype.uniIDHasRole = function (roleId) { - const { - role - } = getCurrentUserInfo(); - return role.indexOf(roleId) > -1 - }; - Vue.prototype.uniIDHasPermission = function (permissionId) { - const { - permission - } = getCurrentUserInfo(); - return this.uniIDHasRole('admin') || permission.indexOf(permissionId) > -1 - }; - Vue.prototype.uniIDTokenValid = function () { - const { - tokenExpired - } = getCurrentUserInfo(); - return tokenExpired > Date.now() - }; +let realAtob; + +const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/; + +if (typeof atob !== 'function') { + realAtob = function (str) { + str = String(str).replace(/[\t\n\f\r ]+/g, ''); + if (!b64re.test(str)) { throw new Error("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.") } + + // Adding the padding if missing, for semplicity + str += '=='.slice(2 - (str.length & 3)); + var bitmap; var result = ''; var r1; var r2; var i = 0; + for (; i < str.length;) { + bitmap = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12 | + (r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++))); + + result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) + : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) + : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255); + } + return result + }; +} else { + // 注意atob只能在全局对象上调用,例如:`const Base64 = {atob};Base64.atob('xxxx')`是错误的用法 + realAtob = atob; +} + +function b64DecodeUnicode (str) { + return decodeURIComponent(realAtob(str).split('').map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) + }).join('')) +} + +function getCurrentUserInfo () { + const token = ( wx).getStorageSync('uni_id_token') || ''; + const tokenArr = token.split('.'); + if (!token || tokenArr.length !== 3) { + return { + uid: null, + role: [], + permission: [], + tokenExpired: 0 + } + } + let userInfo; + try { + userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); + } catch (error) { + throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message) + } + userInfo.tokenExpired = userInfo.exp * 1000; + delete userInfo.exp; + delete userInfo.iat; + return userInfo +} + +function uniIdMixin (Vue) { + Vue.prototype.uniIDHasRole = function (roleId) { + const { + role + } = getCurrentUserInfo(); + return role.indexOf(roleId) > -1 + }; + Vue.prototype.uniIDHasPermission = function (permissionId) { + const { + permission + } = getCurrentUserInfo(); + return this.uniIDHasRole('admin') || permission.indexOf(permissionId) > -1 + }; + Vue.prototype.uniIDTokenValid = function () { + const { + tokenExpired + } = getCurrentUserInfo(); + return tokenExpired > Date.now() + }; } const _toString = Object.prototype.toString; @@ -546,37 +546,37 @@ var previewImage = { } }; -const UUID_KEY = '__DC_STAT_UUID'; -let deviceId; -function addUuid (result) { - deviceId = deviceId || wx.getStorageSync(UUID_KEY); - if (!deviceId) { - deviceId = Date.now() + '' + Math.floor(Math.random() * 1e7); - wx.setStorage({ - key: UUID_KEY, - data: deviceId - }); - } - result.deviceId = deviceId; -} - -function addSafeAreaInsets (result) { - if (result.safeArea) { - const safeArea = result.safeArea; - result.safeAreaInsets = { - top: safeArea.top, - left: safeArea.left, - right: result.windowWidth - safeArea.right, - bottom: result.windowHeight - safeArea.bottom - }; - } -} - -var getSystemInfo = { - returnValue: function (result) { - addUuid(result); - addSafeAreaInsets(result); - } +const UUID_KEY = '__DC_STAT_UUID'; +let deviceId; +function addUuid (result) { + deviceId = deviceId || wx.getStorageSync(UUID_KEY); + if (!deviceId) { + deviceId = Date.now() + '' + Math.floor(Math.random() * 1e7); + wx.setStorage({ + key: UUID_KEY, + data: deviceId + }); + } + result.deviceId = deviceId; +} + +function addSafeAreaInsets (result) { + if (result.safeArea) { + const safeArea = result.safeArea; + result.safeAreaInsets = { + top: safeArea.top, + left: safeArea.left, + right: result.windowWidth - safeArea.right, + bottom: result.windowHeight - safeArea.bottom + }; + } +} + +var getSystemInfo = { + returnValue: function (result) { + addUuid(result); + addSafeAreaInsets(result); + } }; // import navigateTo from 'uni-helpers/navigate-to' @@ -794,11 +794,6 @@ const customize = cached((str) => { }); function initTriggerEvent (mpInstance) { - { - if (!wx.canIUse || !wx.canIUse('nextTick')) { - return - } - } const oldTriggerEvent = mpInstance.triggerEvent; mpInstance.triggerEvent = function (event, ...args) { return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]) @@ -1436,172 +1431,172 @@ function getEventChannel (id) { return eventChannelStack.shift() } -const hooks = [ - 'onShow', - 'onHide', - 'onError', - 'onPageNotFound', - 'onThemeChange', - 'onUnhandledRejection' -]; - -function initEventChannel () { - Vue.prototype.getOpenerEventChannel = function () { - // 微信小程序使用自身getOpenerEventChannel - { - return this.$scope.getOpenerEventChannel() - } - }; - const callHook = Vue.prototype.__call_hook; - Vue.prototype.__call_hook = function (hook, args) { - if (hook === 'onLoad' && args && args.__id__) { - this.__eventChannel__ = getEventChannel(args.__id__); - delete args.__id__; - } - return callHook.call(this, hook, args) - }; -} - -function initScopedSlotsParams () { - const center = {}; - const parents = {}; - - Vue.prototype.$hasScopedSlotsParams = function (vueId) { - const has = center[vueId]; - if (!has) { - parents[vueId] = this; - this.$on('hook:destory', () => { - delete parents[vueId]; - }); - } - return has - }; - - Vue.prototype.$getScopedSlotsParams = function (vueId, name, key) { - const data = center[vueId]; - if (data) { - const object = data[name] || {}; - return key ? object[key] : object - } else { - parents[vueId] = this; - this.$on('hook:destory', () => { - delete parents[vueId]; - }); - } - }; - - Vue.prototype.$setScopedSlotsParams = function (name, value) { - const vueIds = this.$options.propsData.vueId; - if (vueIds) { - const vueId = vueIds.split(',')[0]; - const object = center[vueId] = center[vueId] || {}; - object[name] = value; - if (parents[vueId]) { - parents[vueId].$forceUpdate(); - } - } - }; - - Vue.mixin({ - destroyed () { - const propsData = this.$options.propsData; - const vueId = propsData && propsData.vueId; - if (vueId) { - delete center[vueId]; - delete parents[vueId]; - } - } - }); -} - -function parseBaseApp (vm, { - mocks, - initRefs -}) { - initEventChannel(); - { - initScopedSlotsParams(); - } - if (vm.$options.store) { - Vue.prototype.$store = vm.$options.store; - } - uniIdMixin(Vue); - - Vue.prototype.mpHost = "mp-weixin"; - - Vue.mixin({ - beforeCreate () { - if (!this.$options.mpType) { - return - } - - this.mpType = this.$options.mpType; - - this.$mp = { - data: {}, - [this.mpType]: this.$options.mpInstance - }; - - this.$scope = this.$options.mpInstance; - - delete this.$options.mpType; - delete this.$options.mpInstance; - if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n - const app = getApp(); - if (app.$vm && app.$vm.$i18n) { - this._i18n = app.$vm.$i18n; - } - } - if (this.mpType !== 'app') { - initRefs(this); - initMocks(this, mocks); - } - } - }); - - const appOptions = { - onLaunch (args) { - if (this.$vm) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前 - return - } - { - if (wx.canIUse && !wx.canIUse('nextTick')) { // 事实 上2.2.3 即可,简单使用 2.3.0 的 nextTick 判断 - console.error('当前微信基础库版本过低,请将 微信开发者工具-详情-项目设置-调试基础库版本 更换为`2.3.0`以上'); - } - } - - this.$vm = vm; - - this.$vm.$mp = { - app: this - }; - - this.$vm.$scope = this; - // vm 上也挂载 globalData - this.$vm.globalData = this.globalData; - - this.$vm._isMounted = true; - this.$vm.__call_hook('mounted', args); - - this.$vm.__call_hook('onLaunch', args); - } - }; - - // 兼容旧版本 globalData - appOptions.globalData = vm.$options.globalData || {}; - // 将 methods 中的方法挂在 getApp() 中 - const methods = vm.$options.methods; - if (methods) { - Object.keys(methods).forEach(name => { - appOptions[name] = methods[name]; - }); - } - - initAppLocale(Vue, vm, wx.getSystemInfoSync().language || 'zh-Hans'); - - initHooks(appOptions, hooks); - - return appOptions +const hooks = [ + 'onShow', + 'onHide', + 'onError', + 'onPageNotFound', + 'onThemeChange', + 'onUnhandledRejection' +]; + +function initEventChannel () { + Vue.prototype.getOpenerEventChannel = function () { + // 微信小程序使用自身getOpenerEventChannel + { + return this.$scope.getOpenerEventChannel() + } + }; + const callHook = Vue.prototype.__call_hook; + Vue.prototype.__call_hook = function (hook, args) { + if (hook === 'onLoad' && args && args.__id__) { + this.__eventChannel__ = getEventChannel(args.__id__); + delete args.__id__; + } + return callHook.call(this, hook, args) + }; +} + +function initScopedSlotsParams () { + const center = {}; + const parents = {}; + + Vue.prototype.$hasScopedSlotsParams = function (vueId) { + const has = center[vueId]; + if (!has) { + parents[vueId] = this; + this.$on('hook:destory', () => { + delete parents[vueId]; + }); + } + return has + }; + + Vue.prototype.$getScopedSlotsParams = function (vueId, name, key) { + const data = center[vueId]; + if (data) { + const object = data[name] || {}; + return key ? object[key] : object + } else { + parents[vueId] = this; + this.$on('hook:destory', () => { + delete parents[vueId]; + }); + } + }; + + Vue.prototype.$setScopedSlotsParams = function (name, value) { + const vueIds = this.$options.propsData.vueId; + if (vueIds) { + const vueId = vueIds.split(',')[0]; + const object = center[vueId] = center[vueId] || {}; + object[name] = value; + if (parents[vueId]) { + parents[vueId].$forceUpdate(); + } + } + }; + + Vue.mixin({ + destroyed () { + const propsData = this.$options.propsData; + const vueId = propsData && propsData.vueId; + if (vueId) { + delete center[vueId]; + delete parents[vueId]; + } + } + }); +} + +function parseBaseApp (vm, { + mocks, + initRefs +}) { + initEventChannel(); + { + initScopedSlotsParams(); + } + if (vm.$options.store) { + Vue.prototype.$store = vm.$options.store; + } + uniIdMixin(Vue); + + Vue.prototype.mpHost = "mp-weixin"; + + Vue.mixin({ + beforeCreate () { + if (!this.$options.mpType) { + return + } + + this.mpType = this.$options.mpType; + + this.$mp = { + data: {}, + [this.mpType]: this.$options.mpInstance + }; + + this.$scope = this.$options.mpInstance; + + delete this.$options.mpType; + delete this.$options.mpInstance; + if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n + const app = getApp(); + if (app.$vm && app.$vm.$i18n) { + this._i18n = app.$vm.$i18n; + } + } + if (this.mpType !== 'app') { + initRefs(this); + initMocks(this, mocks); + } + } + }); + + const appOptions = { + onLaunch (args) { + if (this.$vm) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前 + return + } + { + if (wx.canIUse && !wx.canIUse('nextTick')) { // 事实 上2.2.3 即可,简单使用 2.3.0 的 nextTick 判断 + console.error('当前微信基础库版本过低,请将 微信开发者工具-详情-项目设置-调试基础库版本 更换为`2.3.0`以上'); + } + } + + this.$vm = vm; + + this.$vm.$mp = { + app: this + }; + + this.$vm.$scope = this; + // vm 上也挂载 globalData + this.$vm.globalData = this.globalData; + + this.$vm._isMounted = true; + this.$vm.__call_hook('mounted', args); + + this.$vm.__call_hook('onLaunch', args); + } + }; + + // 兼容旧版本 globalData + appOptions.globalData = vm.$options.globalData || {}; + // 将 methods 中的方法挂在 getApp() 中 + const methods = vm.$options.methods; + if (methods) { + Object.keys(methods).forEach(name => { + appOptions[name] = methods[name]; + }); + } + + initAppLocale(Vue, vm, wx.getSystemInfoSync().language || 'zh-Hans'); + + initHooks(appOptions, hooks); + + return appOptions } const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__']; @@ -1937,23 +1932,23 @@ function createSubpackageApp (vm) { return vm } -function createPlugin (vm) { - const appOptions = parseApp(vm); - if (isFn(appOptions.onShow) && wx.onAppShow) { - wx.onAppShow((...args) => { - appOptions.onShow.apply(vm, args); - }); - } - if (isFn(appOptions.onHide) && wx.onAppHide) { - wx.onAppHide((...args) => { - appOptions.onHide.apply(vm, args); - }); - } - if (isFn(appOptions.onLaunch)) { - const args = wx.getLaunchOptionsSync && wx.getLaunchOptionsSync(); - appOptions.onLaunch.call(vm, args); - } - return vm +function createPlugin (vm) { + const appOptions = parseApp(vm); + if (isFn(appOptions.onShow) && wx.onAppShow) { + wx.onAppShow((...args) => { + appOptions.onShow.apply(vm, args); + }); + } + if (isFn(appOptions.onHide) && wx.onAppHide) { + wx.onAppHide((...args) => { + appOptions.onHide.apply(vm, args); + }); + } + if (isFn(appOptions.onLaunch)) { + const args = wx.getLaunchOptionsSync && wx.getLaunchOptionsSync(); + appOptions.onLaunch.call(vm, args); + } + return vm } todos.forEach(todoApi => { diff --git a/packages/vue-cli-plugin-hbuilderx/index.js b/packages/vue-cli-plugin-hbuilderx/index.js index def14c9eee59d5598f091279d38a6e046d17ff94..dece75ddcd3f972a3713c133f251a2aa81f9e892 100644 --- a/packages/vue-cli-plugin-hbuilderx/index.js +++ b/packages/vue-cli-plugin-hbuilderx/index.js @@ -2,7 +2,7 @@ const fs = require('fs') const path = require('path') const uniI18n = require('@dcloudio/uni-cli-i18n') -process.env.UNI_CLI_CONTEXT = path.resolve(__dirname, '../../../') +process.env.UNI_CLI_CONTEXT = require('@dcloudio/uni-cli-shared/lib/util').getCLIContext() process.env.UNI_HBUILDERX_PLUGINS = process.env.UNI_HBUILDERX_PLUGINS || path.resolve(__dirname, '../../../../') diff --git a/packages/vue-cli-plugin-uni/lib/check-update.js b/packages/vue-cli-plugin-uni/lib/check-update.js index 5d327fa72873de0b009f3b53f0a354dd8760d56a..5e0779dfd30d97dbf6628b8440f5cdd7bf6f0e8e 100644 --- a/packages/vue-cli-plugin-uni/lib/check-update.js +++ b/packages/vue-cli-plugin-uni/lib/check-update.js @@ -13,12 +13,14 @@ class Upate { this._isAlpha = false this._uniId = '' this._appId = '' + this._wt = 0 + this._lc = '' + this._lcin = [] } get uniId () { return this._uniId } - set uniId (value) { this._uniId = value } @@ -26,7 +28,6 @@ class Upate { get appId () { return this._appId } - set appId (value) { this._appId = value } @@ -34,7 +35,6 @@ class Upate { get compilerVersion () { return this._compilerVersion } - set compilerVersion (value) { this._compilerVersion = value } @@ -42,11 +42,31 @@ class Upate { get isAlpha () { return this._isAlpha } - set isAlpha (value) { this._isAlpha = value } + get wt () { + return this._wt + } + set wt (value) { + this._wt = value + } + + get lc () { + return this._lc + } + set lc (value) { + this._lc = value + } + + get lcin () { + return this._lcin + } + set lcin (value) { + this._lcin = value + } + get versionType () { return (this.isAlpha ? 'a' : 'r') } @@ -156,6 +176,9 @@ class Upate { data.appid = this.uniId data.vtype = this.versionType data.vcode = this.compilerVersion + data.wt = this._wt + data.lc = this._lc + data.in = this._lcin delete data.lastCheck @@ -234,6 +257,28 @@ Object.assign(Upate.prototype, { DEFAULT_INTERVAL: 1000 * 60 * 60 * 24 }) +function getLc() { + let result = [] + const locale_dir = path.join(process.env.UNI_CLI_CONTEXT, 'src/locale') + if (!fs.existsSync(locale_dir)) { + return result + } + + let files = fs.readdirSync(locale_dir) + for (let i = files.length - 1; i >= 0; i--) { + let filePath = files[i] + let extName = filePath.substring(filePath.lastIndexOf('.') + 1).toLowerCase() + if (extName !== 'json') { + continue + } + + if (files[i].indexOf('uni-app.') < 0) { + result.push(filePath.substring(0, filePath.lastIndexOf('.'))) + } + } + return result +} + module.exports = async function checkUpdate () { const { isInHBuilderX, @@ -255,6 +300,10 @@ module.exports = async function checkUpdate () { update.uniId = manifest.appid const appIdKey = process.env.UNI_PLATFORM.includes('quickapp') ? 'package' : 'appid' update.appId = manifest[process.env.UNI_PLATFORM] ? (manifest[process.env.UNI_PLATFORM][appIdKey] || '') : '' + const cf = manifest['mp-weixin'] ? manifest['mp-weixin']['cloudfunctionRoot'] : '' + update.wt = (cf && cf.length) ? 1 : 0 + update.lc = manifest['locale'] ? manifest['locale'] : '' + update.lcin = getLc().join(',') update.check() } catch (e) { } diff --git a/packages/vue-cli-plugin-uni/lib/configure-webpack.js b/packages/vue-cli-plugin-uni/lib/configure-webpack.js index 8a9af8b25f7a0e0cc37bcaf518955a92e5661250..f972387f1261f52e494af5fad5d43cac9a79471c 100644 --- a/packages/vue-cli-plugin-uni/lib/configure-webpack.js +++ b/packages/vue-cli-plugin-uni/lib/configure-webpack.js @@ -15,7 +15,7 @@ function resolve (dir) { } function resolveModule (dir) { - return path.resolve(__dirname, '../../..', dir) + return path.resolve(process.env.UNI_CLI_CONTEXT, './node_modules', dir) } module.exports = function configureWebpack (platformOptions, manifestPlatformOptions, vueOptions, api) { @@ -184,8 +184,9 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt platformWebpackConfig = platformWebpackConfig(webpackConfig, vueOptions, api) } // 移除 node_modules 目录,避免受路径上的 node_modules 影响 - webpackConfig.resolve.modules = webpackConfig.resolve.modules.filter(module => module !== - 'node_modules') + if (require('@dcloudio/uni-cli-shared/lib/util').isInHBuilderX) { + webpackConfig.resolve.modules = webpackConfig.resolve.modules.filter(module => module !== 'node_modules') + } const plugins = [] @@ -298,6 +299,17 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt } } catch (e) {} + const resolveLoaderAlias = {} + const modules = ['@vue/cli-plugin-babel', '@vue/cli-service'] + modules.forEach(m => { + const { dependencies } = require(`${m}/package.json`) + Object.keys(dependencies).forEach(key => { + if (/-loader$/.test(key)) { + resolveLoaderAlias[key] = require.resolve(key) + } + }) + }) + return merge({ devtool: false, resolve: { @@ -325,6 +337,9 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/, rules }, + resolveLoader: { + alias: resolveLoaderAlias + }, plugins, performance: { assetFilter (assetFilename) { @@ -334,4 +349,4 @@ module.exports = function configureWebpack (platformOptions, manifestPlatformOpt watchOptions: require('./util').getWatchOptions() }, platformWebpackConfig) } -} +} diff --git a/packages/vue-cli-plugin-uni/lib/env.js b/packages/vue-cli-plugin-uni/lib/env.js index d39c383a6db63628b7cbe9be6ae273f0a7f2f2e0..d51237e08673a94cfb1b19b42b43c74cec8ed98c 100644 --- a/packages/vue-cli-plugin-uni/lib/env.js +++ b/packages/vue-cli-plugin-uni/lib/env.js @@ -107,11 +107,13 @@ if (process.env.UNI_CLOUD_SPACES) { } // 初始化环境变量 -const defaultOutputDir = '../../../../dist/' + +process.env.UNI_CLI_CONTEXT = require('@dcloudio/uni-cli-shared/lib/util').getCLIContext() + +const defaultOutputDir = './dist/' + (process.env.NODE_ENV === 'production' ? 'build' : 'dev') + '/' + (process.env.UNI_SUB_PLATFORM || process.env.UNI_PLATFORM) -process.env.UNI_OUTPUT_DEFAULT_DIR = path.resolve(__dirname, defaultOutputDir) +process.env.UNI_OUTPUT_DEFAULT_DIR = path.resolve(process.env.UNI_CLI_CONTEXT, defaultOutputDir) if (process.env.UNI_OUTPUT_DIR && process.env.UNI_OUTPUT_DIR.indexOf('./') === 0) { process.env.UNI_OUTPUT_DIR = path.resolve(process.cwd(), process.env.UNI_OUTPUT_DIR) } @@ -124,8 +126,6 @@ if (process.env.UNI_PLATFORM === 'app-plus') { process.env.UNI_OUTPUT_TMP_DIR = path.resolve(process.env.UNI_OUTPUT_DIR, '../.tmp/app-plus') } -process.env.UNI_CLI_CONTEXT = path.resolve(__dirname, '../../../../') - process.UNI_LIBRARIES = process.UNI_LIBRARIES || ['@dcloudio/uni-ui'] if (process.env.NODE_ENV === 'production') { // 发行模式,不启用 cache diff --git a/src/core/view/components/rich-text/index.vue b/src/core/view/components/rich-text/index.vue index cada876025ac8e9f0b852706ba8ac23c7666ca56..85c1c18543c20f185ef284b25d72b5a21178746d 100644 --- a/src/core/view/components/rich-text/index.vue +++ b/src/core/view/components/rich-text/index.vue @@ -32,13 +32,22 @@ export default { }, methods: { _renderNodes (nodes) { + let scopeId = '' + let $vm = this + while ($vm) { + !scopeId && (scopeId = $vm.$options._scopeId) + $vm = $vm.$parent + } + + const hasItemClick = !!this.$listeners.itemclick + if (!this._isMounted) { return } if (typeof nodes === 'string') { nodes = parseHtml(nodes) } - const nodeList = parseNodes(nodes, document.createDocumentFragment(), this) + const nodeList = parseNodes(nodes, document.createDocumentFragment(), scopeId, hasItemClick && this.triggerItemClick) nodeList.appendChild(this.$refs.sensor.$el) const content = this.$refs.content content.innerHTML = '' @@ -46,6 +55,9 @@ export default { }, _updateView () { window.dispatchEvent(new CustomEvent('updateview')) + }, + triggerItemClick (e, detail = {}) { + this.$trigger('itemclick', e, detail) } } } diff --git a/src/core/view/components/rich-text/nodes-parser.js b/src/core/view/components/rich-text/nodes-parser.js index 57c2d45208e92c25ec33fcecf34137aeba70fc73..e9533aaba907750f625243c55c1c8c17f73d349b 100644 --- a/src/core/view/components/rich-text/nodes-parser.js +++ b/src/core/view/components/rich-text/nodes-parser.js @@ -102,13 +102,7 @@ function normlizeValue (tagName, name, value) { return value } -export default function parseNodes (nodes, parentNode, $vm) { - let scopeId = '' - while ($vm) { - !scopeId && (scopeId = $vm.$options._scopeId) - $vm = $vm.$parent - } - +export default function parseNodes (nodes, parentNode, scopeId, triggerItemClick) { nodes.forEach(function (node) { if (!isPlainObject(node)) { return @@ -146,9 +140,11 @@ export default function parseNodes (nodes, parentNode, $vm) { }) } + processClickEvent(node, elem, triggerItemClick) + const children = node.children if (Array.isArray(children) && children.length) { - parseNodes(node.children, elem) + parseNodes(node.children, elem, scopeId, triggerItemClick) } parentNode.appendChild(elem) @@ -160,3 +156,13 @@ export default function parseNodes (nodes, parentNode, $vm) { }) return parentNode } + +function processClickEvent (node, elem, triggerItemClick) { + if (['a', 'img'].includes(node.name) && triggerItemClick) { + elem.setAttribute('onClick', 'return false;') + elem.addEventListener('click', (e) => { + triggerItemClick(e, { node }) + e.stopPropagation() + }, true) + } +} diff --git a/src/core/view/components/swiper/index.vue b/src/core/view/components/swiper/index.vue index dc2277697b2e92a4ae2dda7171f9bb08cd44e8ac..0f6eb52c3a0de5b89d588ab414717c12b789ff3f 100644 --- a/src/core/view/components/swiper/index.vue +++ b/src/core/view/components/swiper/index.vue @@ -162,7 +162,6 @@ export default { mounted () { this._currentCheck() this.touchtrack(this.$refs.slidesWrapper, '_handleContentTrack', true) - this._resetLayout() this.$watch(() => { return this.autoplay && !this.userTracking }, this._inintAutoplay) diff --git a/src/platforms/mp-weixin/runtime/index.js b/src/platforms/mp-weixin/runtime/index.js index d35d55cf129b104e510cd4b4fc70fc6a2b18aa4c..3a0de61c3dbca18ac425cc9c13c677fd2a846034 100644 --- a/src/platforms/mp-weixin/runtime/index.js +++ b/src/platforms/mp-weixin/runtime/index.js @@ -13,11 +13,6 @@ const customize = cached((str) => { }) function initTriggerEvent (mpInstance) { - if (__PLATFORM__ === 'mp-weixin' || __PLATFORM__ === 'app-plus') { - if (!wx.canIUse || !wx.canIUse('nextTick')) { - return - } - } const oldTriggerEvent = mpInstance.triggerEvent mpInstance.triggerEvent = function (event, ...args) { return oldTriggerEvent.apply(mpInstance, [customize(event), ...args])