diff --git a/babel.config.js b/babel.config.js index 93da2851e2caa24b311720a025d19253f97660b3..ae2321892d65920d6e5ec9ef3bc95a75359765a5 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,10 +1,11 @@ module.exports = { - ignore: [ - "./packages", - ], - presets: [ - ["@vue/app", { - useBuiltIns: "entry" - }] - ] + ignore: [ + "./packages", + ], + presets: [ + ["@vue/app", { + useBuiltIns: "entry" + }] + ], + plugins: [require('./lib/babel-plugin-uni-api/index.js')] } diff --git a/build/build.js b/build/build.js index 93a838fc920b50eb05602b11db05217287d537ff..59d4eead5dca755ad90a0db2b38080b4315d742c 100644 --- a/build/build.js +++ b/build/build.js @@ -9,9 +9,15 @@ const copy = require('copy') const path = require('path') const jsonfile = require('jsonfile') +const { + generateApiManifest +} = require('./manifest') + const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd(), { inlineOptions: require('./vue.config.js') }) +// 删除 cache 目录 +del.sync(['node_modules/.cache']) service.run('build', { name: 'index', @@ -19,6 +25,8 @@ service.run('build', { target: 'lib', formats: process.env.UNI_WATCH === 'true' ? 'umd' : 'umd-min', entry: './lib/' + process.env.UNI_PLATFORM + '/main.js' +}).then(function () { + generateApiManifest(process.UNI_SERVICE_API_MANIFEST) }).catch(err => { error(err) process.exit(1) @@ -44,9 +52,11 @@ if (process.env.UNI_WATCH === 'false') { }) }) .then(obj => { - return jsonfile.writeFile(packageJsonPath, obj, { spaces: 2 }) + return jsonfile.writeFile(packageJsonPath, obj, { + spaces: 2 + }) }) .catch(err => { throw err }) -} +} diff --git a/build/manifest.js b/build/manifest.js new file mode 100644 index 0000000000000000000000000000000000000000..eaa266c364b2b5549c484fc10e02b54dc13fccc2 --- /dev/null +++ b/build/manifest.js @@ -0,0 +1,46 @@ +const fs = require('fs') +const path = require('path') + +const apis = require('../src/core/helpers/apis') + +function parseApiManifestDeps (manifest) { + Object.keys(manifest).forEach(name => { + const deps = manifest[name][1] + if (deps && deps.length) { + deps.forEach(dep => { + if (manifest[dep[1]]) { + dep[0] = manifest[dep[1]][0] + } else { + console.warn(`依赖模块[${dep[1]}]不存在`) + } + }) + } + }) +} + +module.exports = { + generateApiManifest (manifest) { + parseApiManifestDeps(manifest) + + const manifestJson = Object.create(null) + const todoApis = [] + apis.forEach(name => { + if (manifest[name]) { + manifestJson[name] = manifest[name] + } else { + todoApis.push(name) + } + }) + + if (todoApis.length) { + console.warn(`${process.env.UNI_PLATFORM} 平台缺少以下 API 实现`) + todoApis.forEach(name => { + console.warn(name) + }) + } + + fs.writeFileSync(path.resolve(__dirname, '../packages/uni-h5/manifest.json'), + JSON.stringify(manifestJson, null, 4) + ) + } +} diff --git a/lib/babel-plugin-uni-api/index.js b/lib/babel-plugin-uni-api/index.js new file mode 100644 index 0000000000000000000000000000000000000000..f1bfd768c1af8b6490046c128a115a81e4e494f9 --- /dev/null +++ b/lib/babel-plugin-uni-api/index.js @@ -0,0 +1,85 @@ +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 coreApiPath = resolve('../../src/core/service/api') +const platformApiPath = resolve('../../src/platforms/' + process.env.UNI_PLATFORM + '/service/api') + +const apis = require('../../src/core/helpers/apis') + +process.UNI_SERVICE_API_MANIFEST = Object.create(null) + +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 + }, + exit(path, state) { + const { + file, + methods, + exports, + isPlatform + } = state.file.opts + if (exports && exports.length) { + 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(`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] + } + }) + } + } + }, + ExportNamedDeclaration(path, state) { + const { + file, + isCore, + isPlatform + } = state.file.opts + if ((isCore || isPlatform) && t.isFunctionDeclaration(path.node.declaration)) { + (state.file.opts.exports || (state.file.opts.exports = [])).push(path.node.declaration.id.name) + } + }, + 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) + } + } + } + } +} diff --git a/packages/uni-app-plus-nvue/dist/index.js b/packages/uni-app-plus-nvue/dist/index.js index af414546c4976343bf48dc5d31d7516763854c28..05cec377160f5945bb49cf23d920c486bb891cce 100644 --- a/packages/uni-app-plus-nvue/dist/index.js +++ b/packages/uni-app-plus-nvue/dist/index.js @@ -1556,9 +1556,9 @@ var serviceContext = (function () { 'unsubscribePush', 'onPush', 'offPush', - 'requireNativePlugin', + 'requireNativePlugin', 'upx2px' - ]; + ]; const apis = [ ...base, @@ -1570,11 +1570,13 @@ var serviceContext = (function () { ...device, ...keyboard, ...ui, - ...event, - ...file, + ...event, + ...file, ...canvas, ...third - ]; + ]; + + var apis_1 = apis; /** * 框架内 try-catch @@ -1938,7 +1940,7 @@ var serviceContext = (function () { const upx2px = [{ name: 'upx', - type: Number, + type: [Number, String], required: true }]; @@ -3423,6 +3425,15 @@ var serviceContext = (function () { const invokeCallback = function (res) { res.errMsg = res.errMsg || apiName + ':ok'; + // 部分 api 可能返回的 errMsg 的 api 名称部分不一致,格式化为正确的 + if (res.errMsg.indexOf(':ok') !== -1) { + res.errMsg = apiName + ':ok'; + } else if (res.errMsg.indexOf(':cancel') !== -1) { + res.errMsg = apiName + ':cancel'; + } else if (res.errMsg.indexOf(':fail') !== -1) { + res.errMsg = apiName + ':fail'; + } + const errMsg = res.errMsg; if (errMsg.indexOf(apiName + ':ok') === 0) { @@ -7685,6 +7696,52 @@ var serviceContext = (function () { return UniServiceJSBridge.on('api.' + name, callback) } + const callbacks$1 = []; + + onMethod('onAccelerometerChange', function (res) { + callbacks$1.forEach(callbackId => { + invoke(callbackId, res); + }); + }); + + let isEnable = false; + /** + * 监听加速度 + * @param {*} callbackId + */ + function onAccelerometerChange (callbackId) { + // TODO 当没有 start 时,添加 on 需要主动 start? + callbacks$1.push(callbackId); + if (!isEnable) { + startAccelerometer(); + } + } + + function startAccelerometer ({ + interval // TODO + } = {}) { + if (isEnable) { + return + } + isEnable = true; + return invokeMethod('enableAccelerometer', { + enable: true + }) + } + + function stopAccelerometer () { + isEnable = false; + return invokeMethod('enableAccelerometer', { + enable: false + }) + } + + var require_context_module_1_4 = /*#__PURE__*/Object.freeze({ + onAccelerometerChange: onAccelerometerChange, + startAccelerometer: startAccelerometer, + stopAccelerometer: stopAccelerometer + }); + const requestTasks$1 = Object.create(null); function formatResponse (res, args) { @@ -7786,7 +7843,7 @@ var serviceContext = (function () { return new RequestTask(requestTaskId) } - var require_context_module_1_4 = /*#__PURE__*/Object.freeze({ + var require_context_module_1_5 = /*#__PURE__*/Object.freeze({ request: request$1 }); @@ -7895,7 +7952,7 @@ var serviceContext = (function () { return res } - var require_context_module_1_5 = /*#__PURE__*/Object.freeze({ + var require_context_module_1_6 = /*#__PURE__*/Object.freeze({ setStorage: setStorage$1, setStorageSync: setStorageSync$1, getStorage: getStorage$1, @@ -7916,7 +7973,7 @@ var serviceContext = (function () { return {} } - var require_context_module_1_6 = /*#__PURE__*/Object.freeze({ + var require_context_module_1_7 = /*#__PURE__*/Object.freeze({ pageScrollTo: pageScrollTo$1 }); @@ -7929,9 +7986,10 @@ var serviceContext = (function () { './base/can-i-use.js': require_context_module_1_1, './base/interceptor.js': require_context_module_1_2, './base/upx2px.js': require_context_module_1_3, - './network/request.js': require_context_module_1_4, - './storage/storage.js': require_context_module_1_5, - './ui/page-scroll-to.js': require_context_module_1_6, + './device/accelerometer.js': require_context_module_1_4, + './network/request.js': require_context_module_1_5, + './storage/storage.js': require_context_module_1_6, + './ui/page-scroll-to.js': require_context_module_1_7, }; var req = function req(key) { @@ -7952,7 +8010,7 @@ var serviceContext = (function () { const uni$1 = Object.create(null); - apis.forEach(name => { + apis_1.forEach(name => { if (api$1[name]) { uni$1[name] = promisify(name, wrapper(name, api$1[name])); } else { diff --git a/src/core/service/api/base/base64.js b/src/core/service/api/base/base64.js index 3164fe4c187e52a57f347594c9af24890fab8c22..a04c7af691a3aeb60219a063c6c9d851adba5d68 100644 --- a/src/core/service/api/base/base64.js +++ b/src/core/service/api/base/base64.js @@ -1,4 +1,12 @@ -import { encode, decode } from 'base64-arraybuffer' - -export const base64ToArrayBuffer = decode -export const arrayBufferToBase64 = encode +import { + encode, + decode +} from 'base64-arraybuffer' + +export function base64ToArrayBuffer (str) { + return decode(str) +} + +export function arrayBufferToBase64 (buffer) { + return encode(buffer) +}