first commit

This commit is contained in:
2026-09-08 20:28:54 +08:00
commit 2ada8d3d5a
37380 changed files with 4886169 additions and 0 deletions
+311
View File
@@ -0,0 +1,311 @@
const base = [
'base64ToArrayBuffer',
'arrayBufferToBase64',
'addInterceptor',
'removeInterceptor',
'interceptors'
]
const network = [
'request',
'uploadFile',
'downloadFile',
'connectSocket',
'onSocketOpen',
'onSocketError',
'sendSocketMessage',
'onSocketMessage',
'closeSocket',
'onSocketClose',
'getUpdateManager',
'configMTLS'
]
const route = [
'navigateTo',
'redirectTo',
'reLaunch',
'switchTab',
'navigateBack'
]
const storage = [
'setStorage',
'setStorageSync',
'getStorage',
'getStorageSync',
'getStorageInfo',
'getStorageInfoSync',
'removeStorage',
'removeStorageSync',
'clearStorage',
'clearStorageSync'
]
const location = [
'getLocation',
'chooseLocation',
'openLocation',
'createMapContext',
'onLocationChange',
'onLocationChangeError',
'startLocationUpdate',
'stopLocationUpdate',
'offLocationChange',
'offLocationChangeError'
]
const media = [
'chooseImage',
'chooseFile',
'previewImage',
'closePreviewImage',
'getImageInfo',
'getVideoInfo',
'saveImageToPhotosAlbum',
'compressImage',
'compressVideo',
'getRecorderManager',
'getBackgroundAudioManager',
'createAudioContext',
'createInnerAudioContext',
'chooseVideo',
'saveVideoToPhotosAlbum',
'createVideoContext',
'createCameraContext',
'createLivePlayerContext',
'createLivePusherContext'
]
const device = [
'getSystemInfo',
'getSystemInfoSync',
'getWindowInfo',
'getDeviceInfo',
'getAppBaseInfo',
'canIUse',
'onMemoryWarning',
'getNetworkType',
'onNetworkStatusChange',
'offNetworkStatusChange',
'onAccelerometerChange',
'offAccelerometerChange',
'startAccelerometer',
'stopAccelerometer',
'onCompassChange',
'offCompassChange',
'startCompass',
'stopCompass',
'onGyroscopeChange',
'startGyroscope',
'stopGyroscope',
'makePhoneCall',
'scanCode',
'setClipboardData',
'getClipboardData',
'setScreenBrightness',
'getScreenBrightness',
'setKeepScreenOn',
'onUserCaptureScreen',
'vibrateLong',
'vibrateShort',
'addPhoneContact',
'openBluetoothAdapter',
'startBluetoothDevicesDiscovery',
'onBluetoothDeviceFound',
'stopBluetoothDevicesDiscovery',
'onBluetoothAdapterStateChange',
'getConnectedBluetoothDevices',
'getBluetoothDevices',
'getBluetoothAdapterState',
'closeBluetoothAdapter',
'writeBLECharacteristicValue',
'readBLECharacteristicValue',
'onBLEConnectionStateChange',
'onBLECharacteristicValueChange',
'notifyBLECharacteristicValueChange',
'getBLEDeviceServices',
'getBLEDeviceCharacteristics',
'createBLEConnection',
'closeBLEConnection',
'setBLEMTU',
'getBLEDeviceRSSI',
'onBeaconServiceChange',
'onBeaconUpdate',
'getBeacons',
'startBeaconDiscovery',
'stopBeaconDiscovery',
'checkIsSupportSoterAuthentication',
'checkIsSoterEnrolledInDevice',
'startSoterAuthentication',
'onThemeChange',
'offThemeChange',
'onUIStyleChange',
'getSystemSetting',
'getAppAuthorizeSetting',
'openAppAuthorizeSetting'
]
const keyboard = [
'hideKeyboard',
'onKeyboardHeightChange',
'offKeyboardHeightChange',
'getSelectedTextRange'
]
const ui = [
'showToast',
'hideToast',
'showLoading',
'hideLoading',
'showModal',
'showActionSheet',
'setNavigationBarTitle',
'setNavigationBarColor',
'showNavigationBarLoading',
'hideNavigationBarLoading',
'setTabBarItem',
'setTabBarStyle',
'hideTabBar',
'showTabBar',
'setTabBarBadge',
'removeTabBarBadge',
'showTabBarRedDot',
'hideTabBarRedDot',
'onTabBarMidButtonTap',
'setBackgroundColor',
'setBackgroundTextStyle',
'createAnimation',
'pageScrollTo',
'onWindowResize',
'offWindowResize',
'loadFontFace',
'startPullDownRefresh',
'stopPullDownRefresh',
'createSelectorQuery',
'createIntersectionObserver',
'createMediaQueryObserver',
'getMenuButtonBoundingClientRect',
'showTopWindow',
'showLeftWindow',
'showRightWindow',
'hideTopWindow',
'hideLeftWindow',
'hideRightWindow',
'getTopWindowStyle',
'getLeftWindowStyle',
'getRightWindowStyle',
'setTopWindowStyle',
'setLeftWindowStyle',
'setRightWindowStyle',
'getLocale',
'setLocale',
'onLocaleChange'
]
const event = [
'$emit',
'$on',
'$once',
'$off'
]
const file = [
'saveFile',
'getSavedFileList',
'getSavedFileInfo',
'removeSavedFile',
'getFileInfo',
'openDocument',
'getFileSystemManager'
]
const canvas = [
'createOffscreenCanvas',
'createCanvasContext',
'canvasToTempFilePath',
'canvasPutImageData',
'canvasGetImageData'
]
const third = [
'getProvider',
'login',
'checkSession',
'getUserInfo',
'getUserProfile',
'preLogin',
'closeAuthView',
'getCheckBoxState',
'getUniverifyManager',
'share',
'shareWithSystem',
'showShareMenu',
'hideShareMenu',
'requestPayment',
'subscribePush',
'unsubscribePush',
'onPush',
'offPush',
'requireNativePlugin',
'upx2px',
'restoreGlobal',
'requireGlobal',
'getSubNVueById',
'getCurrentSubNVue',
'setPageMeta',
'onHostEventReceive',
'onNativeEventReceive',
'sendNativeEvent',
'preloadPage',
'unPreloadPage',
'loadSubPackage',
'sendHostEvent',
'navigateToMiniProgram',
'getLaunchOptionsSync',
'getEnterOptionsSync',
'initUTSProxyClass',
'initUTSProxyFunction',
'initUTSIndexClassName',
'initUTSClassName',
'initUTSPackageName',
'requireUTSPlugin',
'registerUTSPlugin',
'registerUTSInterface'
]
const ad = [
'createRewardedVideoAd',
'createFullScreenVideoAd',
'createInterstitialAd',
'createInteractiveAd'
]
const plugin = [
'invokePushCallback',
'getPushClientId',
'onPushMessage',
'offPushMessage',
'createPushMessage',
'getChannelManager'
]
const apis = [
...base,
...network,
...route,
...storage,
...location,
...media,
...device,
...keyboard,
...ui,
...event,
...file,
...canvas,
...third,
...ad,
...plugin
]
module.exports = apis
+18
View File
@@ -0,0 +1,18 @@
export {
upx2px
}
from 'uni-core/service/api/base/upx2px'
export * from 'uni-platform/view/api'
export {
getSystemInfoSync
}
from '../../src/platforms/h5/service/api/device/get-system-info'
export function canIUse (schema) {
if (schema === 'css.var') {
return window.CSS && window.CSS.supports && window.CSS.supports('--a:0')
}
return true
}
+32
View File
@@ -0,0 +1,32 @@
import Vue from 'vue'
import 'uni-platform/view/index.css'
import {
definePage
} from 'uni-platform/page-factory'
import {
getCurrentPages
} from 'uni-platform/view/framework/page'
import ViewPlugin from 'uni-platform/view/framework/plugins/index'
global.UniViewJSBridge = {
subscribe: UniViewJSBridge.subscribe,
publishHandler: UniViewJSBridge.publishHandler,
subscribeHandler: UniViewJSBridge.subscribeHandler
}
global.getCurrentPages = getCurrentPages
global.__definePage = definePage
global.Vue = Vue
Vue.use(ViewPlugin)
require('uni-components')
export * from './view-api.js'
+144
View File
@@ -0,0 +1,144 @@
const path = require('path')
const isWin = /^win/.test(process.platform)
const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
function resolve(...args) {
return normalizePath(path.resolve.apply(path, [__dirname, ...args]))
}
const srcPath = resolve('../../src/')
const protocolPath = resolve('../../src/core/helpers/protocol')
const coreApiPath = resolve('../../src/core/service/api')
const platformApiPath = resolve('../../src/platforms/' + process.env.UNI_PLATFORM + '/service/api')
const apis = require('../apis')
process.UNI_SERVICE_API_MANIFEST = Object.create(null)
process.UNI_SERVICE_API_PROTOCOL = Object.create(null)
function parseProtocolExport({
file,
exports
}) {
const filepath = file.replace(srcPath, '')
exports.forEach(exportName => {
if (process.UNI_SERVICE_API_PROTOCOL[exportName]) {
console.warn(`API[${exportName}] 冲突:`)
console.warn(process.UNI_SERVICE_API_PROTOCOL[exportName])
console.warn(filepath)
} else {
process.UNI_SERVICE_API_PROTOCOL[exportName] = filepath
}
})
}
function parseApiExport({
file,
methods,
exports,
isPlatform
}) {
const deps = []
methods && methods.forEach(method => {
deps.push(['', method])
})
const filepath = file.replace(srcPath, '')
exports.forEach(exportName => {
if (process.UNI_SERVICE_API_MANIFEST[exportName]) {
console.warn('\n')
console.warn(`API[${exportName}] 冲突:`)
console.warn(process.UNI_SERVICE_API_MANIFEST[exportName][0])
console.warn(filepath)
if (isPlatform) { // 优先使用 platform
process.UNI_SERVICE_API_MANIFEST[exportName] = [filepath, deps]
console.warn(`优先使用` + filepath)
}
} else {
process.UNI_SERVICE_API_MANIFEST[exportName] = [filepath, deps]
}
})
}
const CONTEXTS = ['VideoContext', 'MapContext', 'EditorContext', 'CanvasContext']
function parseExports(node, t, file) {
if (t.isFunctionDeclaration(node)) {
return [node.id.name]
} else if (
t.isVariableDeclaration(node) &&
node.declarations.length === 1
) {
return [node.declarations[0].id.name]
} else if (Array.isArray(node) && node.length) {
return node.map(specifier => {
return specifier.exported.name
})
} else {
if (t.isClassDeclaration(node) && CONTEXTS.includes(node.id.name)) {
// ignore
return
}
console.warn('\n')
console.warn(`${file} 解析 export 失败`, node)
}
}
module.exports = function({
types: t
}) {
return {
visitor: {
Program: {
enter(path, state) {
state.file.opts.file = normalizePath(state.file.opts.filename)
state.file.opts.isCore = state.file.opts.file.indexOf(coreApiPath) === 0
state.file.opts.isPlatform = state.file.opts.file.indexOf(platformApiPath) === 0
state.file.opts.isProtocol = state.file.opts.file.indexOf(protocolPath) === 0
},
exit(path, state) {
const {
exports,
isProtocol
} = state.file.opts
if (exports && exports.length) {
if (isProtocol) {
parseProtocolExport(state.file.opts)
} else {
parseApiExport(state.file.opts)
}
}
}
},
ExportNamedDeclaration(path, state) {
const {
file,
isCore,
isPlatform,
isProtocol
} = state.file.opts
if (isCore || isPlatform || isProtocol) {
const exports = parseExports(path.node.declaration || path.node.specifiers, t, file)
if (Array.isArray(exports)) {
(state.file.opts.exports || (state.file.opts.exports = [])).push(...exports)
}
}
},
CallExpression(path, state) {
const {
file,
isCore,
isPlatform
} = state.file.opts
if (
isCore &&
path.node.callee.name === 'invokeMethod'
) {
(state.file.opts.methods || (state.file.opts.methods = new Set())).add(path.node.arguments[0].value)
}
}
}
}
}
+40
View File
@@ -0,0 +1,40 @@
const fs = require('fs')
const path = require('path')
const glob = require('glob')
const loaderUtils = require('loader-utils')
const isWin = /^win/.test(process.platform)
const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
module.exports = function loader(source) {
const options = loaderUtils.getOptions(this)
const baseDir = options['base']
const extendsDir = options['extends']
const exportCode = []
const extendsFiles = []
// extends目录均导出
glob.sync('**/*.js', {
cwd: extendsDir
}).forEach(file => {
if (file === 'index.js') {
return
}
extendsFiles.push(file)
exportCode.push(`export * from 'uni-sub-platform-api/${normalizePath(file)}'`)
})
//base目录中有,extends无的导出
glob.sync('**/*.js', {
cwd: baseDir
}).forEach(file => {
if (file === 'index.js') {
return
}
if (!extendsFiles.includes(file)) {
exportCode.push(`export * from 'uni-platform-api/${normalizePath(file)}'`)
}
})
// console.log(exportCode.join('\n'))
return exportCode.join('\n')
}
+58
View File
@@ -0,0 +1,58 @@
const fs = require('fs')
const path = require('path')
const glob = require('glob')
const loaderUtils = require('loader-utils')
const isWin = /^win/.test(process.platform)
const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
module.exports = function loader(source) {
const options = loaderUtils.getOptions(this)
const baseDir = options['base']
const platformDir = options['platform']
const extendsDir = options['extends']
const components = []
const extendsFiles = []
// extends目录均导出
glob.sync('**/index.vue', {
cwd: extendsDir
}).forEach(file => {
extendsFiles.push(file)
components.push(normalizePath(path.join(extendsDir, file)))
})
//base目录中有,extends无的导出
glob.sync('**/index.vue', {
cwd: baseDir
}).forEach(file => {
if (!extendsFiles.includes(file)) {
components.push(normalizePath(path.join(baseDir, file)))
}
})
//platform目录中有,extends无的导出
glob.sync('**/index.vue', {
cwd: platformDir
}).forEach(file => {
if (!extendsFiles.includes(file)) {
components.push(normalizePath(path.join(platformDir, file)))
}
})
const componentsCode = components.map(component => {
return `require('${component}').default`
}).join(',')
return `
import Vue from 'vue'
import baseMixin from 'uni-mixins/base'
import animation from 'uni-mixins/animation'
[${componentsCode}].forEach(component=>{
component.mixins = component.mixins ? [].concat(baseMixin, component.mixins) : [baseMixin]
component.mixins.push(animation)
component.name = 'VUni' + component.name
component.isReserved = true
Vue.component(component.name, component)
})
`
}
+3
View File
@@ -0,0 +1,3 @@
import 'uni-sub-platform/service/index'
import * as api from 'uni-platform/service/api/index'
export default api
+66
View File
@@ -0,0 +1,66 @@
/**
* 1.导出全局对象(UniViewJSBridge,UniServiceJSBridge,uni,getApp,getCurrentPages)
* 2.引入 Vue 插件(uniVueServicePlugin,uniVueServicePlugin)
* 3.引入 Vue 组件
*/
import Vue from 'vue'
// import 'uni-platform/view/index.css'
import initVue from 'uni-core/vue'
class UniApp {
constructor () {
this._init()
}
_init () {
global.UniViewJSBridge = {
subscribe: UniViewJSBridge.subscribe,
publishHandler: UniViewJSBridge.publishHandler,
subscribeHandler: UniViewJSBridge.subscribeHandler
}
global.UniServiceJSBridge = {
subscribe: UniServiceJSBridge.subscribe,
publishHandler: UniServiceJSBridge.publishHandler,
subscribeHandler: UniServiceJSBridge.subscribeHandler
}
const {
default: uni,
getApp,
getCurrentPages
} = require('uni-platform/service/index')
// 与微信JS-SDK同名的方法
// const sameNameApis = ['setClipboardData', 'getClipboardData', 'onUserCaptureScreen', 'openBluetoothAdapter', 'startBluetoothDevicesDiscovery', 'onBluetoothDeviceFound', 'stopBluetoothDevicesDiscovery', 'onBluetoothAdapterStateChange', 'getConnectedBluetoothDevices', 'getBluetoothDevices', 'getBluetoothAdapterState', 'closeBluetoothAdapter', 'writeBLECharacteristicValue', 'readBLECharacteristicValue', 'onBLEConnectionStateChange', 'onBLECharacteristicValueChange', 'notifyBLECharacteristicValueChange', 'getBLEDeviceServices', 'getBLEDeviceCharacteristics', 'createBLEConnection', 'closeBLEConnection', 'onBeaconServiceChange', 'onBeaconUpdate', 'getBeacons', 'startBeaconDiscovery', 'stopBeaconDiscovery', 'chooseImage', 'previewImage', 'getNetworkType', 'onNetworkStatusChange', 'openLocation', 'getLocation']
// 默认会被iOS企业微信替换的方法
const sameNameApis = ['chooseImage']
sameNameApis.forEach(item => {
Object.defineProperty(uni, item, {
writable: false,
configurable: false
})
})
global.uni = uni
global.wx = global.uni
global.getApp = getApp
global.getCurrentPages = getCurrentPages
Vue.use(require('uni-service/plugins').default, {
routes: __uniRoutes
})
Vue.use(require('uni-view/plugins').default, {
routes: __uniRoutes
})
initVue(Vue)
require('uni-platform/components')
require('uni-components')
}
}
global.UniApp = UniApp
global.__uniConfig && new UniApp()
+27
View File
@@ -0,0 +1,27 @@
import {
canIUse
} from 'uni-core/service/api/base/can-i-use'
import {
upx2px
} from 'uni-core/service/api/base/upx2px'
import {
getLocation
} from 'uni-platform/service/api/location/get-location'
import {
onCompassChange,
stopCompass
} from 'uni-platform/service/api/device/compass'
import {
getSystemInfoSync
} from 'uni-platform/service/api/device/get-system-info'
// TODO route
export default {
canIUse,
upx2px,
getLocation,
onCompassChange,
stopCompass,
getSystemInfoSync
}
+54
View File
@@ -0,0 +1,54 @@
import Vue from 'vue'
// 使用白名单过滤(前期有一批自定义组件使用了 uni-)
import tags from 'uni-helpers/tags'
import 'uni-core/view/index.css'
import uni from './ui-api.js'
import {
processEvent
} from 'uni-core/view/plugins/events'
const oldIsReservedTag = Vue.config.isReservedTag
global.uni = uni
Vue.config.isReservedTag = function (tag) {
return tags.indexOf(tag) !== -1 || oldIsReservedTag(tag)
}
Vue.config.ignoredElements = tags
const oldGetTagNamespace = Vue.config.getTagNamespace
const conflictTags = ['switch', 'image', 'text', 'view']
Vue.config.getTagNamespace = function (tag) {
if (~conflictTags.indexOf(tag)) { // svg 部分标签名称与 uni 标签冲突
return false
}
return oldGetTagNamespace(tag) || false
}
const findUniTarget = function ($event, $el) {
let target = $event.target
for (; target && target !== $el; target = target.parentNode) {
if (target.tagName && target.tagName.indexOf('UNI-') === 0) {
break
}
}
return target
}
Vue.prototype.$handleEvent = function ($event) {
if ($event instanceof Event) { // 未处理的 event 对象 需要对 target 校正及包装
// 查找 uniTarget
const target = findUniTarget($event, this.$el)
$event = processEvent.call(this, $event.type, $event, {}, target || $event.target, $event.currentTarget)
}
return $event
}
require('uni-components')
+1
View File
@@ -0,0 +1 @@
"use strict";var e=require("debug"),t=require("postcss-selector-parser"),o=require("fs");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=a(e),n=a(t),s=a(o);const i=r.default("automator:devtool");function c(e){e.walk((e=>{if("tag"===e.type){const t=e.value;e.value="page"===t?"uni-page-body":"uni-"+t}}))}const l=["Page.getElement","Page.getElements","Element.getElement","Element.getElements"];function p(e){try{return require(e)}catch(t){return require(require.resolve(e,{paths:[process.cwd()]}))}}/^win/.test(process.platform);const u=["chromium","firefox","webkit"];let w=!1;try{w=!!p("playwright")}catch(e){}const d=new Map;function f(e="chromium"){const t=e&&u.includes(e)?e:u[0];let o=d.get(t);return o||(o=function(e){if("webkit"===e)return h("webkit");if("firefox"===e)return h("firefox");if(w)return h("chromium");throw new Error("Playwright dependency not found, please install playwright!")}(t),d.set(t,o)),o}function h(e){const t=p("playwright");let o,a;return{type:e,provider:"playwright",async open(r,n,s){o=await t[e].launch(n.options),"firefox"===e&&(n.contextOptions.isMobile=!1),i(`browser.newContext ${JSON.stringify(n.contextOptions)}`);const c=await o.newContext(n.contextOptions);a=await c.newPage(),a.on("console",(e=>{s.emit("App.logAdded",{type:e.type(),args:[e.text()]})})),a.on("pageerror",(e=>{s.emit("App.exceptionThrown",e)})),await a.goto(n.url||r),await a.waitForTimeout(1e3)},close:()=>o.close(),screenshot(e=!1){let t={fullPage:e};return"true"===process.env.UNI_AUTOMATOR_WEB_SCREENSHOT_NO_NAVIGATION_BAR&&(t={fullPage:e,clip:{x:0,y:44,width:Number.MAX_VALUE,height:Number.MAX_VALUE}}),a.screenshot(t).then((e=>e.toString("base64")))},swipe:e=>new Promise((async t=>{const{startPoint:o,endPoint:r}=e;await a.evaluate((([e,t])=>{window.scrollBy({left:e.x-t.x,top:e.y-t.y,behavior:"smooth"})}),[o,r]),t("swipe success")})),tap:e=>new Promise((async t=>{const{x:o,y:r,duration:n}=e;await a.mouse.move(o,r),await a.mouse.down(),await a.waitForTimeout(n||0),await a.mouse.up(),t("tap success")})),keyboardInput:e=>new Promise((async t=>{await a.keyboard.type(e.text),t("keyboardInput success")}))}}let y;const m={"Tool.close":{reflect:async()=>{await y.close()}},"App.start":{reflect:async()=>{}},"App.exit":{reflect:async()=>{}},"App.enableLog":{reflect:()=>Promise.resolve()},"App.captureScreenshot":{reflect:async(e,t)=>{const o=await y.screenshot(!!t.fullPage);return i(`App.captureScreenshot ${o.length}`),{data:o}}},"App.swipe":{reflect:async(e,t)=>{const o=await y.swipe(t);return i(`App.swipe ${o.length}`),{data:o}}},"App.tap":{reflect:async(e,t)=>{const o=await y.tap(t);return i(`App.tap ${o.length}`),{data:o}}},"App.keyboardInput":{reflect:async(e,t)=>{const o=await y.keyboardInput(t);return i(`App.keyboardInput ${o.length}`),{data:o}}}};!function(e){l.forEach((t=>{e[t]=function(e){return{reflect:async(t,o)=>t(e,o,!1),params:e=>(e.selector&&(e.selector=n.default(c).processSync(e.selector)),e)}}(t)}))}(m);const g={devtools:{name:"browser",paths:[],validate:async function(e){var t;return e.options=e.options||{},e.executablePath&&!e.options.executablePath&&(e.options.executablePath=e.executablePath),e.contextOptions={viewport:Object.assign({width:375,height:667},e.options.defaultViewport||{}),hasTouch:!0,isMobile:!0,deviceScaleFactor:(null===(t=e.options.defaultViewport)||void 0===t?void 0:t.deviceScaleFactor)||2},e.options.defaultViewport=Object.assign({width:375,height:667,deviceScaleFactor:2,hasTouch:!0,isMobile:!0},e.options.defaultViewport||{}),e.teardown||(e.teardown=!1===e.options.headless?"disconnect":"close"),e},create:async function(e,t,o){t.executablePath?await new Promise(((o,a)=>{const{exec:r}=require("node:child_process");if(/^win/.test(process.platform)){const a="C:\\Users\\Public\\AppData\\Local\\chrome";s.default.existsSync(a)||s.default.mkdirSync(a,{recursive:!0}),r(`start ${t.executablePath} --user-data-dir=${a} ${e}`,(e=>{if(e)throw console.error(`open ${t.executablePath} fail, ${e}`),Error(e)})),setTimeout((()=>{o(null)}),1e3)}else r(`open -a "${t.executablePath}" ${e}`,(e=>{e&&(console.error(`open ${t.executablePath} fail, ${e}`),a(e)),o(null)}))})):(y=f(process.env.BROWSER),i("createDevtools "+(y.provider+" "+y.type+" "+JSON.stringify(t))),await y.open(e,t,o))}},shouldCompile:(e,t)=>!t.url,adapter:m};module.exports=g;
+65
View File
@@ -0,0 +1,65 @@
const fs = require('fs')
const path = require('path')
function getTemplatePath (template) {
if (template) {
const userTemplate = path.resolve(process.env.UNI_INPUT_DIR, template)
if (fs.existsSync(userTemplate)) { return userTemplate }
}
return path.resolve(process.env.UNI_CLI_CONTEXT, 'public/index.html')
}
function transform (content, platformOptions) {
if (platformOptions.darkmode === true) {
// darkmode
try {
content += fs.readFileSync(require.resolve('@dcloudio/uni-h5/dist/index.dark.css'))
} catch (error) { }
}
if (process.env.NODE_ENV === 'production') {
return content + // shadow
'body::after{position:fixed;content:\'\';left:-1000px;top:-1000px;-webkit-animation:shadow-preload .1s;-webkit-animation-delay:3s;animation:shadow-preload .1s;animation-delay:3s}@-webkit-keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}@keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}'
}
return content
}
function getIndexCssPath (assetsDir, template, hashKey) {
const CopyWebpackPluginVersion = Number(require('copy-webpack-plugin/package.json').version.split('.')[0])
const VUE_APP_INDEX_CSS_HASH = process.env[hashKey]
if (VUE_APP_INDEX_CSS_HASH) {
try {
const templateContent = fs.readFileSync(getTemplatePath(template))
if (new RegExp('\\b' + hashKey + '\\b').test(templateContent)) {
return path.join(assetsDir, `[name].${VUE_APP_INDEX_CSS_HASH}${CopyWebpackPluginVersion > 7 ? '' : '.'}[ext]`)
}
} catch (e) { }
}
return assetsDir
}
module.exports = {
options: {
cssVars: {
'--status-bar-height': '0px'
},
filterTag: 'wxs',
vue: '@dcloudio/vue-cli-plugin-uni/packages/h5-vue'
},
copyWebpackOptions (platformOptions, vueOptions) {
const copyOptions = [
{
from: require.resolve('@dcloudio/uni-h5/dist/index.css'),
to: getIndexCssPath(vueOptions.assetsDir, platformOptions.template, 'VUE_APP_INDEX_CSS_HASH'),
transform (content) {
return transform(content, platformOptions)
}
},
'hybrid/html'
]
global.uniModules.forEach(module => {
copyOptions.push('uni_modules/' + module + '/hybrid/html')
})
return copyOptions
}
}
+237
View File
@@ -0,0 +1,237 @@
[{
"name": "base",
"title": "基础",
"apiList": {
"uni.getSystemInfo": true,
"uni.getSystemInfoSync": true,
"uni.canIUse": true,
"uni.upx2px": true,
"uni.navigateTo": true,
"uni.redirectTo": true,
"uni.switchTab": true,
"uni.reLaunch": true,
"uni.navigateBack": true
}
}, {
"name": "network",
"title": "网络",
"apiList": {
"uni.request": true,
"uni.connectSocket": true,
"uni.sendSocketMessage": true,
"uni.closeSocket": true,
"uni.onSocketOpen": true,
"uni.onSocketError": true,
"uni.onSocketMessage": true,
"uni.onSocketClose": true,
"uni.downloadFile": true,
"uni.uploadFile": true
}
}, {
"name": "storage",
"title": "数据缓存",
"apiList": {
"uni.setStorage": true,
"uni.setStorageSync": true,
"uni.getStorage": true,
"uni.getStorageSync": true,
"uni.removeStorage": true,
"uni.removeStorageSync": true,
"uni.clearStorage": true,
"uni.clearStorageSync": true,
"uni.getStorageInfo": true,
"uni.getStorageInfoSync": true
}
}, {
"name": "location",
"title": "位置",
"apiList": {
"uni.getLocation": true,
"uni.openLocation": true,
"uni.chooseLocation": true,
"uni.onLocationChange": true,
"uni.onLocationChangeError": true,
"uni.startLocationUpdate": true,
"uni.stopLocationUpdate": true,
"uni.offLocationChange": true,
"uni.offLocationChangeError": true
}
}, {
"name": "media",
"title": "媒体",
"apiList": {
"uni.chooseImage": true,
"uni.chooseFile": true,
"uni.previewImage": true,
"uni.getImageInfo": true,
"uni.getVideoInfo": true,
"uni.saveImageToPhotosAlbum": true,
"uni.compressImage": true,
"uni.compressVideo": true,
"uni.getRecorderManager": true,
"uni.getBackgroundAudioManager": true,
"uni.createInnerAudioContext": true,
"uni.chooseVideo": true,
"uni.saveVideoToPhotosAlbum": true,
"uni.createVideoContext": true,
"uni.createCameraContext": true,
"uni.createLivePlayerContext": true,
"uni.createLivePusherContext": true
}
}, {
"name": "device",
"title": "设备",
"apiList": {
"uni.onMemoryWarning": true,
"uni.getNetworkType": true,
"uni.onNetworkStatusChange": true,
"uni.offNetworkStatusChange": true,
"uni.onAccelerometerChange": true,
"uni.startAccelerometer": true,
"uni.stopAccelerometer": true,
"uni.onCompassChange": true,
"uni.offCompassChange": true,
"uni.startCompass": true,
"uni.stopCompass": true,
"uni.onGyroscopeChange": true,
"uni.startGyroscope": true,
"uni.stopGyroscope": true,
"uni.makePhoneCall": true,
"uni.scanCode": true,
"uni.setClipboardData": true,
"uni.getClipboardData": true,
"uni.setScreenBrightness": true,
"uni.getScreenBrightness": true,
"uni.setKeepScreenOn": true,
"uni.onUserCaptureScreen": true,
"uni.vibrateLong": true,
"uni.vibrateShort": true,
"uni.addPhoneContact": true,
"uni.openBluetoothAdapter": true,
"uni.startBluetoothDevicesDiscovery": true,
"uni.onBluetoothDeviceFound": true,
"uni.stopBluetoothDevicesDiscovery": true,
"uni.onBluetoothAdapterStateChange": true,
"uni.getConnectedBluetoothDevices": true,
"uni.getBluetoothDevices": true,
"uni.getBluetoothAdapterState": true,
"uni.closeBluetoothAdapter": true,
"uni.writeBLECharacteristicValue": true,
"uni.readBLECharacteristicValue": true,
"uni.onBLEConnectionStateChange": true,
"uni.onBLECharacteristicValueChange": true,
"uni.notifyBLECharacteristicValueChange": true,
"uni.getBLEDeviceServices": true,
"uni.getBLEDeviceCharacteristics": true,
"uni.createBLEConnection": true,
"uni.closeBLEConnection": true,
"uni.setBLEMTU": true,
"uni.getBLEDeviceRSSI": true,
"uni.onBeaconServiceChange": true,
"uni.onBeaconUpdate": true,
"uni.getBeacons": true,
"uni.startBeaconDiscovery": true,
"uni.stopBeaconDiscovery": true,
"uni.onThemeChange": true,
"uni.onUIStyleChange": true
}
}, {
"name": "ui",
"title": "界面",
"apiList": {
"uni.showToast": true,
"uni.hideToast": true,
"uni.showLoading": true,
"uni.hideLoading": true,
"uni.showModal": true,
"uni.showActionSheet": true,
"uni.setNavigationBarTitle": true,
"uni.setNavigationBarColor": true,
"uni.showNavigationBarLoading": true,
"uni.hideNavigationBarLoading": true,
"uni.setTabBarItem": true,
"uni.setTabBarStyle": true,
"uni.hideTabBar": true,
"uni.showTabBar": true,
"uni.setTabBarBadge": true,
"uni.removeTabBarBadge": true,
"uni.showTabBarRedDot": true,
"uni.hideTabBarRedDot": true,
"uni.setBackgroundColor": true,
"uni.setBackgroundTextStyle": true,
"uni.createAnimation": true,
"uni.pageScrollTo": true,
"uni.onWindowResize": true,
"uni.offWindowResize": true,
"uni.loadFontFace": true,
"uni.startPullDownRefresh": true,
"uni.stopPullDownRefresh": true,
"uni.createSelectorQuery": true,
"uni.createIntersectionObserver": true,
"uni.createMediaQueryObserver": true,
"uni.hideKeyboard": true,
"uni.onKeyboardHeightChange": true,
"uni.offKeyboardHeightChange": true
}
}, {
"name": "event",
"title": "页面通讯",
"apiList": {
"uni.$emit": true,
"uni.$on": true,
"uni.$once": true,
"uni.$off": true
}
}, {
"name": "file",
"title": "文件",
"apiList": {
"uni.saveFile": true,
"uni.getSavedFileList": true,
"uni.getSavedFileInfo": true,
"uni.removeSavedFile": true,
"uni.getFileInfo": true,
"uni.openDocument": true,
"uni.getFileSystemManager": true
}
}, {
"name": "canvas",
"title": "绘画",
"apiList": {
"uni.createOffscreenCanvas": true,
"uni.createCanvasContext": true,
"uni.canvasToTempFilePath": true,
"uni.canvasPutImageData": true,
"uni.canvasGetImageData": true
}
}, {
"name": "third",
"title": "第三方服务",
"apiList": {
"uni.getProvider": true,
"uni.login": true,
"uni.checkSession": true,
"uni.getUserInfo": true,
"uni.getUserProfile": true,
"uni.share": true,
"uni.showShareMenu": true,
"uni.hideShareMenu": true,
"uni.requestPayment": true,
"uni.subscribePush": true,
"uni.unsubscribePush": true,
"uni.onPush": true,
"uni.offPush": true,
"uni.requireNativePlugin": true,
"uni.base64ToArrayBuffer": true,
"uni.arrayBufferToBase64": true
}
}, {
"name": "ad",
"title": "广告",
"apiList": {
"uni.createRewardedVideoAd": true,
"uni.createFullScreenVideoAd": true,
"uni.'createInterstitialAd'": true,
"uni.'createInteractiveAd'": true
}
}]
@@ -0,0 +1,20 @@
# rollup-plugin-require-context
rollup plugin for resovling webpack require-context.
## usage
```javascript
import requireContext from 'rollup-plugin-require-context';
export default {
input: 'main.js',
output: {
file: 'bundle.js',
format: 'iife'
},
plugins: [
requireContext()
]
};
```
@@ -0,0 +1,38 @@
{
"name": "rollup-plugin-require-context",
"version": "1.0.0",
"description": "rollup-plugin for webpack requrie-context",
"main": "src/index.js",
"scripts": {
"brk": "node --inspect-brk example/run.js",
"example": "rollup -c example/rollup.config.js",
"test:dev": "jest --watchAll"
},
"repository": {
"type": "git",
"url": "git+https://github.com/elcarim5efil/rollup-plugin-require-context.git"
},
"keywords": [
"rollup",
"plugin",
"require-context",
"webpack-context"
],
"author": "elcarim5efil",
"license": "MIT",
"bugs": {
"url": "https://github.com/elcarim5efil/rollup-plugin-require-context/issues"
},
"homepage": "https://github.com/elcarim5efil/rollup-plugin-require-context#readme",
"dependencies": {
"acorn": "^6.1.1",
"acorn-dynamic-import": "^4.0.0",
"acorn-walk": "^6.1.1",
"rollup-pluginutils": "^2.5.0"
},
"devDependencies": {
"jest": "^24.5.0",
"rollup": "^1.7.4",
"rollup-plugin-virtual": "^1.0.1"
}
}
@@ -0,0 +1,66 @@
const Path = require('path')
const { parse } = require('acorn')
const walk = require('acorn-walk')
function stripHeadAndTailChar (str) {
return str.substring(1, str.length - 1)
}
function extract (code) {
return new Promise((resolve, reject) => {
const ast = parse(code, {
sourceType: 'module'
})
const res = []
walk.simple(ast, {
CallExpression (node) {
const {
start,
end,
callee,
arguments: argNodes
} = node
let args = []
if (
callee.type === 'MemberExpression' &&
callee.object.name === 'require' &&
callee.property.name === 'context'
) {
args = argNodes.map(a => a.value)
res.push({
start,
end,
args
})
}
}
})
resolve(res)
})
}
module.exports = async function extractArgs (code, baseDirname) {
const data = await extract(code)
return data.map(r => {
const { start, end, args } = r
const [
rawDirname = '',
rawRecursive,
rawRegexp
] = args
const dirname = Path.join(baseDirname, rawDirname)
const recursive = rawRecursive
const regexp = rawRegexp
return {
dirname,
recursive,
regexp,
start,
end
}
})
}
@@ -0,0 +1,36 @@
const Path = require('path')
const extractArgs = require('./extract-args')
const resolveRequireModules = require('./resolve-reqquire-modules')
const resolveRequireCode = require('./resolve-require-code')
module.exports = async function gernerateRequireContextCode (id, code) {
const currentCodeDirname = Path.dirname(id)
const data = await extractArgs(code, currentCodeDirname)
let head = ''
const body = data.reduceRight((res, r) => {
const {
start, end,
dirname, recursive, regexp
} = r
const modules = resolveRequireModules(dirname, recursive, regexp)
const moduleCode = resolveRequireCode(dirname, modules)
const {
importCode,
requireFnCode
} = moduleCode
head += importCode
res = [
res.slice(0, start),
requireFnCode,
res.slice(end)
].join('')
return res
}, code)
return [
head,
body
].join('\n')
}
@@ -0,0 +1,3 @@
module.exports = function hasRequireContext (code) {
return /require\.context/g.test(code)
}
@@ -0,0 +1,36 @@
const fs = require('fs')
const Path = require('path')
function readDirRecursive (dir) {
return fs.statSync(dir).isDirectory()
? Array.prototype.concat(
...fs.readdirSync(dir).map(f => readDirRecursive(Path.join(dir, f)))
)
: dir
}
function readDir (dir, recursive) {
const isDirectory = fs.statSync(dir).isDirectory()
if (recursive) {
return readDirRecursive(dir)
} else if (isDirectory) {
const files = fs.readdirSync(dir)
if (files) {
return files.map(file => Path.resolve(dir, file))
}
} else {
return [ dir ]
}
}
module.exports = function resolveRequireModules (baseDirname = './', recursive = false, regexp = /^\.\//) {
let files = readDir(baseDirname, recursive)
if (!Array.isArray(files)) {
files = [files]
}
files = files.map(file => {
const fileAbsolutePath = `./${Path.relative(baseDirname, file)}`
return fileAbsolutePath
})
return files.filter(file => regexp.test(file.replace(/\\/g, '/')))
}
@@ -0,0 +1,48 @@
const Path = require('path')
let uid = 0
function getUID () {
return uid++
}
function genImportCode (name, path) {
return `import * as ${name} from '${path}';\n`
}
function genPropsCode (key, value) {
return `'${key}': ${value},\n`
}
module.exports = function genRequireCode (baseDirname, modules) {
const uid = getUID()
let importCode = ''
let moduleProps = ''
modules.forEach((file, index) => {
const moduleName = `require_context_module_${uid}_${index}`
const moduleAbsolutePath = Path.resolve(baseDirname, file).replace(/\\/g, '/')
importCode += genImportCode(moduleName, moduleAbsolutePath)
moduleProps += genPropsCode(file.replace(/\\/g, '/'), moduleName)
})
const requireFnCode = (`
(function() {
var map = {
${moduleProps}
};
var req = function req(key) {
return map[key] || (function() { throw new Error("Cannot find module '" + key + "'.") }());
}
req.keys = function() {
return Object.keys(map);
}
return req;
})()
`)
return {
importCode,
requireFnCode
}
}
@@ -0,0 +1,17 @@
const _ = require('rollup-pluginutils')
const hasRequireContext = require('./helper/has-require-context')
const gernerateRequireContextCode = require('./helper/generate-require-context-code')
module.exports = function plugin (options = {}) {
const filter = _.createFilter(options.include || ['**/*.js'], options.exclude || 'node_modules/**')
return {
name: 'require_content',
async transform (code, id) {
if (!filter(id) || !hasRequireContext(code)) {
return
}
code = await gernerateRequireContextCode(id, code)
return code
}
}
}