提交 2231d5df 编写于 作者: fxy060608's avatar fxy060608

refactor(app-plus-nvue)

上级 74b6eb55
src/core/helpers/html-parser.js
\ No newline at end of file
src/core/helpers/html-parser.js
build/rollup-plugin-require-context
# 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()
]
};
```
{
"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"
}
}
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
}
})
}
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')
}
module.exports = function hasRequireContext (code) {
return /require\.context/g.test(code)
}
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, '/')))
}
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(moduleAbsolutePath, 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
}
}
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
}
}
}
......@@ -6,10 +6,10 @@ const PLATFORMS = {
'mp-weixin': {
prefix: 'wx',
title: '微信小程序'
},
'mp-qq': {
prefix: 'wx',
title: 'QQ小程序'
},
'mp-qq': {
prefix: 'wx',
title: 'QQ小程序'
},
'mp-alipay': {
prefix: 'my',
......@@ -40,8 +40,8 @@ module.exports = {
plugins: [
alias({
'uni-shared': path.resolve(__dirname, '../src/shared/util.js'),
'uni-platform': path.resolve(__dirname, '../src/platforms/' + process.env.UNI_PLATFORM),
'uni-wrapper': path.resolve(__dirname, '../src/core/runtime/wrapper'),
'uni-platform': path.resolve(__dirname, '../src/platforms/' + process.env.UNI_PLATFORM),
'uni-wrapper': path.resolve(__dirname, '../src/core/runtime/wrapper'),
'uni-helpers': path.resolve(__dirname, '../src/core/helpers')
}),
replace({
......
const path = require('path')
const alias = require('rollup-plugin-alias')
const replace = require('rollup-plugin-replace')
const replace = require('rollup-plugin-replace')
const requireContext = require('./rollup-plugin-require-context')
let input = 'src/platforms/app-plus-nvue/service/index.js'
const output = {
file: 'packages/uni-app-plus-nvue/dist/index.js',
format: 'es'
}
if (process.env.UNI_SERVICE === 'legacy') {
input = 'src/platforms/app-plus-nvue/service/index.legacy.js'
output.file = 'packages/uni-app-plus-nvue/dist/index.legacy.js'
} else if (process.env.UNI_SERVICE === 'uni') {
input = 'src/platforms/app-plus/service/uni.js'
output.file = 'packages/uni-app-plus-nvue/dist/uni.js'
output.banner = 'export function createUniInstance(plus){\n'
output.footer = '\n return uni$1 \n}'
}
module.exports = {
input: 'src/platforms/app-plus-nvue/services/index.legacy.js',
output: {
file: `packages/uni-app-plus-nvue/dist/service.legacy.js`,
format: 'es'
},
plugins: [
input,
output,
plugins: [
requireContext(),
alias({
'uni-core': path.resolve(__dirname, '../src/core'),
'uni-shared': path.resolve(__dirname, '../src/shared/util.js')
'uni-core': path.resolve(__dirname, '../src/core'),
'uni-platform': path.resolve(__dirname, '../src/platforms/app-plus'),
'uni-platforms': path.resolve(__dirname, '../src/platforms'),
'uni-shared': path.resolve(__dirname, '../src/shared/util.js'),
'uni-helpers': path.resolve(__dirname, '../src/core/helpers')
}),
replace({
__GLOBAL__: 'getGlobalUni()',
__PLATFORM_TITLE__: 'app-plus-nvue'
})
]
],
external: ['./uni']
}
......@@ -6,7 +6,7 @@
"dev:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=true UNI_PLATFORM=h5 node build/build.js",
"build:h5": "npm run lint && cross-env NODE_ENV=production UNI_WATCH=false UNI_PLATFORM=h5 node build/build.js",
"build:app-plus": "cross-env UNI_PLATFORM=app-plus rollup -c build/rollup.config.js",
"build:service:legacy": "npm run lint && rollup -c build/rollup.config.service.js",
"build:service": "npm run lint && UNI_SERVICE=uni rollup -c build/rollup.config.service.js && rollup -c build/rollup.config.service.js && UNI_SERVICE=legacy rollup -c build/rollup.config.service.js",
"build:mp-qq": "cross-env UNI_PLATFORM=mp-qq rollup -c build/rollup.config.js",
"build:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin rollup -c build/rollup.config.js",
"build:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu rollup -c build/rollup.config.js",
......
var weexPlus = new WeexPlus(weex)
export default getUni(weex)
export {
weexPlus
import { createUniInstance } from './uni';
function getWebviewStyle () {
return {
titleNView: {
autoBackButton: true,
titleText: 'titleText'
}
}
}
class Router {
constructor (routes, plus) {
this.routes = routes;
this.plus = plus;
this.id = 0;
this.aniShow = plus.os.name === 'Android' ? 'slide-in-right' : 'pop-in';
this.aniClose = 'pop-out';
this.aniDuration = 300;
}
push ({
type,
path
} = {}) {
this.plus.webview.open(
'',
String(this.id++),
getWebviewStyle(),
this.aniShow,
this.aniDuration,
() => {
console.log('show.callback');
});
}
replace ({
type,
path
} = {}) {
}
go (delta) {
}
}
let appCtx;
function getApp () {
return appCtx
}
function registerApp (appVm, routes, plus) {
appCtx = appVm;
appCtx.$router = new Router(routes, plus);
}
const pageVms = [];
function getCurrentPages () {
return pageVms
}
const __uniConfig = Object.create(null);
const __uniRoutes = [];
function createInstanceContext ({
weex,
WeexPlus
}) {
const plus = new WeexPlus(weex);
return {
__uniConfig,
__uniRoutes,
__registerApp (appVm, {
uniConfig,
uniRoutes
}) {
Object.assign(__uniConfig, uniConfig);
uniRoutes.forEach(route => __uniRoutes.push(route));
registerApp(appVm, __uniRoutes, plus);
},
uni: createUniInstance(plus),
getApp,
getCurrentPages
}
}
export { createInstanceContext };
......@@ -8,7 +8,109 @@ function hasOwn (obj, key) {
return hasOwnProperty.call(obj, key)
}
const SYNC_API_RE = /^\$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/;
const globalInterceptors = {};
const scopedInterceptors = {};
function wrapperHook (hook) {
return function (data) {
return hook(data) || data
}
}
function isPromise (obj) {
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'
}
function queue (hooks, data) {
let promise = false;
for (let i = 0; i < hooks.length; i++) {
const hook = hooks[i];
if (promise) {
promise = Promise.then(wrapperHook(hook));
} else {
const res = hook(data);
if (isPromise(res)) {
promise = Promise.resolve(res);
}
if (res === false) {
return {
then () {}
}
}
}
}
return promise || {
then (callback) {
return callback(data)
}
}
}
function wrapperOptions (interceptor, options = {}) {
['success', 'fail', 'complete'].forEach(name => {
if (Array.isArray(interceptor[name])) {
const oldCallback = options[name];
options[name] = function callbackInterceptor (res) {
queue(interceptor[name], res).then((res) => {
/* eslint-disable no-mixed-operators */
return isFn(oldCallback) && oldCallback(res) || res
});
};
}
});
return options
}
function wrapperReturnValue (method, returnValue) {
const returnValueHooks = [];
if (Array.isArray(globalInterceptors.returnValue)) {
returnValueHooks.push(...globalInterceptors.returnValue);
}
const interceptor = scopedInterceptors[method];
if (interceptor && Array.isArray(interceptor.returnValue)) {
returnValueHooks.push(...interceptor.returnValue);
}
returnValueHooks.forEach(hook => {
returnValue = hook(returnValue) || returnValue;
});
return returnValue
}
function getApiInterceptorHooks (method) {
const interceptor = Object.create(null);
Object.keys(globalInterceptors).forEach(hook => {
if (hook !== 'returnValue') {
interceptor[hook] = globalInterceptors[hook].slice();
}
});
const scopedInterceptor = scopedInterceptors[method];
if (scopedInterceptor) {
Object.keys(scopedInterceptor).forEach(hook => {
if (hook !== 'returnValue') {
interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]);
}
});
}
return interceptor
}
function invokeApi (method, api, options, ...params) {
const interceptor = getApiInterceptorHooks(method);
if (interceptor && Object.keys(interceptor).length) {
if (Array.isArray(interceptor.invoke)) {
const res = queue(interceptor.invoke, options);
return res.then((options) => {
return api(wrapperOptions(interceptor, options), ...params)
})
} else {
return api(wrapperOptions(interceptor, options), ...params)
}
}
return api(options, ...params)
}
const SYNC_API_RE =
/^\$|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/;
const CONTEXT_API_RE = /^create|Manager$/;
......@@ -49,10 +151,10 @@ function promisify (name, api) {
}
return function promiseApi (options = {}, ...params) {
if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) {
return api(options, ...params)
return wrapperReturnValue(name, invokeApi(name, api, options, ...params))
}
return handlePromise(new Promise((resolve, reject) => {
api(Object.assign({}, options, {
return wrapperReturnValue(name, handlePromise(new Promise((resolve, reject) => {
invokeApi(name, api, Object.assign({}, options, {
success: resolve,
fail: reject
}), ...params);
......@@ -68,7 +170,7 @@ function promisify (name, api) {
)
};
}
}))
})))
}
}
......@@ -609,48 +711,36 @@ let getGlobalApp;
let getGlobalUniEmitter;
let getGlobalCurrentPages;
var index_legacy = {
create (id, env, config) {
return {
initUniApp ({
nvue,
getUni,
getApp,
getUniEmitter,
getCurrentPages
}) {
getGlobalUni = getUni;
getGlobalApp = getApp;
getGlobalUniEmitter = getUniEmitter;
getGlobalCurrentPages = getCurrentPages;
initUpx2px(nvue);
initEventBus(getUniEmitter);
},
instance: {
getUni (nvue, plus, BroadcastChannel) {
return initUni(getGlobalUni(), nvue, plus, BroadcastChannel)
},
getApp () {
return getGlobalApp()
},
getUniEmitter () {
return getGlobalUniEmitter()
},
getCurrentPages () {
return getGlobalCurrentPages()
}
}
function createInstanceContext () {
return {
initUniApp ({
nvue,
getUni,
getApp,
getUniEmitter,
getCurrentPages
}) {
getGlobalUni = getUni;
getGlobalApp = getApp;
getGlobalUniEmitter = getUniEmitter;
getGlobalCurrentPages = getCurrentPages;
initUpx2px(nvue);
initEventBus(getUniEmitter);
},
getUni (nvue, plus, BroadcastChannel) {
return initUni(getGlobalUni(), nvue, plus, BroadcastChannel)
},
getApp () {
return getGlobalApp()
},
getUniEmitter () {
return getGlobalUniEmitter()
},
getCurrentPages () {
return getGlobalCurrentPages()
}
},
refresh: function (id, env, config) {
},
destroy: function (id, env) {
}
};
}
export default index_legacy;
export { createInstanceContext };
此差异已折叠。
此差异已折叠。
......@@ -10,6 +10,7 @@
"license": "Apache-2.0",
"dependencies": {
"base64-arraybuffer": "^0.2.0",
"intersection-observer": "^0.7.0"
"intersection-observer": "^0.7.0",
"rollup-plugin-require-context": "^1.0.0"
}
}
......@@ -14,7 +14,7 @@ import {
isCallbackApi
} from './promise'
import protocol from './protocol/index'
import protocol from './protocol'
import validateParam from './params'
......
const protocol = Object.create(null)
const modules = require.context('./', true, /\.js$/)
const modules = require.context('./protocol', true, /\.js$/)
modules.keys().forEach(function (key) {
if (key !== './index.js') {
Object.assign(protocol, modules(key))
}
Object.assign(protocol, modules(key))
})
export default protocol
uni.navigateTo(plus.webview.open)
旧页面通过 viewdisappear 触发 onHide
新页面通过 beforeCreate 触发 onShow
uni.redirectTo(page.webview.close,plus.webview.show)
旧页面通过 beforeDestroy 触发 onUnload
新页面通过 beforeCreate 触发 onShow
uni.switchTab
旧非 Tab 页面通过 beforeDestroy 触发 onUnload
旧 Tab 页面通过 viewdisappear 触发 onHide
新创建 Tab 页面通过 beforeCreate 触发 onShow
新显示 Tab 页面通过 viewdisappear 触发 onShow
uni.reLaunch
旧页面通过 beforeDestroy 触发 onUnload
新页面通过 beforeCreate 触发 onShow
\ No newline at end of file
import Router from './router'
let appCtx
export function getApp () {
return appCtx
}
export function registerApp (appVm, routes, plus) {
appCtx = appVm
appCtx.$router = new Router(routes, plus)
}
export const SHOW_ANISHOW = 'slide-in-right'
import {
getApp,
registerApp
} from './app'
import {
getCurrentPages
} from './page'
import {
createUniInstance
} from './uni'
const __uniConfig = Object.create(null)
const __uniRoutes = []
export function createInstanceContext ({
weex,
WeexPlus
}) {
const plus = new WeexPlus(weex)
return {
__uniConfig,
__uniRoutes,
__registerApp (appVm, {
uniConfig,
uniRoutes
}) {
Object.assign(__uniConfig, uniConfig)
uniRoutes.forEach(route => __uniRoutes.push(route))
registerApp(appVm, __uniRoutes, plus)
},
uni: createUniInstance(plus),
getApp,
getCurrentPages
}
}
import initUni from './api/legacy/index'
import initUpx2px from './api/upx2px'
import initEventBus from './api/event-bus'
let getGlobalUni
let getGlobalApp
let getGlobalUniEmitter
let getGlobalCurrentPages
export function createInstanceContext () {
return {
initUniApp ({
nvue,
getUni,
getApp,
getUniEmitter,
getCurrentPages
}) {
getGlobalUni = getUni
getGlobalApp = getApp
getGlobalUniEmitter = getUniEmitter
getGlobalCurrentPages = getCurrentPages
initUpx2px(nvue)
initEventBus(getUniEmitter)
},
getUni (nvue, plus, BroadcastChannel) {
return initUni(getGlobalUni(), nvue, plus, BroadcastChannel)
},
getApp () {
return getGlobalApp()
},
getUniEmitter () {
return getGlobalUniEmitter()
},
getCurrentPages () {
return getGlobalCurrentPages()
}
}
}
const pageVms = []
export function getCurrentPages () {
return pageVms
}
/**
* @param {Object} pageVm
*
* page.beforeCreate 时添加 page
* page.beforeDestroy 时移出 page
*
* page.viewappear onShow
* page.viewdisappear onHide
*
* navigateTo
* redirectTo
*
*
*
*
*
*
*/
export function registerPage (pageVm) {
}
function getWebviewStyle () {
return {
titleNView: {
autoBackButton: true,
titleText: 'titleText'
}
}
}
export default class Router {
constructor (routes, plus) {
this.routes = routes
this.plus = plus
this.id = 0
this.aniShow = plus.os.name === 'Android' ? 'slide-in-right' : 'pop-in'
this.aniClose = 'pop-out'
this.aniDuration = 300
}
push ({
type,
path
} = {}) {
this.plus.webview.open(
'',
String(this.id++),
getWebviewStyle(),
this.aniShow,
this.aniDuration,
() => {
console.log('show.callback')
})
}
replace ({
type,
path
} = {}) {
}
go (delta) {
}
}
import initUni from './api/legacy/index'
import initUpx2px from './api/upx2px'
import initEventBus from './api/event-bus'
let getGlobalUni
let getGlobalApp
let getGlobalUniEmitter
let getGlobalCurrentPages
export default {
create (id, env, config) {
return {
initUniApp ({
nvue,
getUni,
getApp,
getUniEmitter,
getCurrentPages
}) {
getGlobalUni = getUni
getGlobalApp = getApp
getGlobalUniEmitter = getUniEmitter
getGlobalCurrentPages = getCurrentPages
initUpx2px(nvue)
initEventBus(getUniEmitter)
},
instance: {
getUni (nvue, plus, BroadcastChannel) {
return initUni(getGlobalUni(), nvue, plus, BroadcastChannel)
},
getApp () {
return getGlobalApp()
},
getUniEmitter () {
return getGlobalUniEmitter()
},
getCurrentPages () {
return getGlobalCurrentPages()
}
}
}
},
refresh: function (id, env, config) {
},
destroy: function (id, env) {
}
}
import getRealRoute from 'uni-helpers/get-real-route'
const SCHEME_RE = /^([a-z-]+:)?\/\//i
const BASE64_RE = /^data:[a-z-]+\/[a-z-]+;base64,/
function addBase (filePath) {
return filePath
}
export default function getRealPath (filePath) {
if (filePath.indexOf('/') === 0) {
if (filePath.indexOf('//') === 0) {
filePath = 'https:' + filePath
} else {
return addBase(filePath.substr(1))
}
}
// 网络资源或base64
if (SCHEME_RE.test(filePath) || BASE64_RE.test(filePath) || filePath.indexOf('blob:') === 0) {
return filePath
}
const pages = getCurrentPages()
if (pages.length) {
return addBase(getRealRoute(pages[pages.length - 1].$page.route, filePath).substr(1))
}
return filePath
}
export * from 'uni-core/service/api/route'
import {
wrapper
} from 'uni-helpers/api'
import {
promisify
} from 'uni-helpers/promise'
import * as api from './api'
const uni = Object.create(null)
/* eslint-disable no-undef */
uni.version = __VERSION__
Object.keys(api).forEach(name => {
uni[name] = promisify(name, wrapper(name, api[name]))
})
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册