提交 02520e3f 编写于 作者: Q qiang

Merge branch 'dev' of github.com:dcloudio/uni-app into dev

const compiler = require('@dcloudio/uni-template-compiler') const compiler = require('@dcloudio/uni-template-compiler')
// 非 h5 平台禁用,由uni-template-compiler自行实现
const transformAssetUrls = {
audio: false,
video: false,
source: false,
img: false,
image: false,
use: false
}
if (process.env.UNI_PLATFORM === 'h5') {
Object.assign(transformAssetUrls, {
'audio': 'src',
'video': ['src', 'poster'],
'source': 'src',
'img': 'src',
'use': ['xlink:href', 'href'],
'image': 'src',
'cover-image': 'src',
'v-uni-audio': 'src',
'v-uni-video': ['src', 'poster'],
'v-uni-image': 'src',
'v-uni-cover-image': 'src'
})
}
const defaultOptions = { const defaultOptions = {
compiler, compiler,
hotReload: false, hotReload: false,
cacheDirectory: false, cacheDirectory: false,
cacheIdentifier: false, cacheIdentifier: false,
transformAssetUrls transformAssetUrls: false // 禁用,由 uni-template-compiler 自行实现 transformAssetUrls
} }
const defaultCompilerOptions = { const defaultCompilerOptions = {
......
...@@ -27,13 +27,13 @@ function urlToRequire (url) { ...@@ -27,13 +27,13 @@ function urlToRequire (url) {
} }
const uriParts = parseUriParts(url) const uriParts = parseUriParts(url)
if (!uriParts.hash) { // fixed by xxxxxx (v3 template中需要加/) if (!uriParts.hash) { // fixed by xxxxxx (v3 template中需要加/)
return `"/"+require("${url}")` return `require("${url}")`
} else { // fixed by xxxxxx (v3 template中需要加/) } else { // fixed by xxxxxx (v3 template中需要加/)
// support uri fragment case by excluding it from // support uri fragment case by excluding it from
// the require and instead appending it as string; // the require and instead appending it as string;
// assuming that the path part is sufficient according to // assuming that the path part is sufficient according to
// the above caseing(t.i. no protocol-auth-host parts expected) // the above caseing(t.i. no protocol-auth-host parts expected)
return `"/"+require("${uriParts.path}") + "${uriParts.hash}"` return `require("${uriParts.path}") + "${uriParts.hash}"`
} }
} }
return returnValue return returnValue
...@@ -61,11 +61,24 @@ function rewrite (attr, name, options) { ...@@ -61,11 +61,24 @@ function rewrite (attr, name, options) {
const value = attr.value const value = attr.value
// only transform static URLs // only transform static URLs
if (value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') { if (value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') {
if (!options.h5) { // 非 H5 平台
attr.value = attr.value attr.value = attr.value
.replace('"@/', '"/') .replace('"@/', '"/')
.replace('"~@/', '"/') .replace('"~@/', '"/')
if (options.service || options.view) { // v3 }
// v3,h5
const needRequire = options.service || options.view || options.h5
if (needRequire) {
attr.value = urlToRequire(attr.value.slice(1, -1)) attr.value = urlToRequire(attr.value.slice(1, -1))
if (attr.value.startsWith('require("')) { // require
// v3 需要增加前缀 /
if (options.service || options.view) {
attr.value = `"/"+${attr.value}`
} else if (options.h5 && options.publicPath === './') {
// h5 且 publicPath 为 ./ (仅生产模式可能为./)
attr.value = `(${attr.value}).substr(1)`
}
}
} }
return true return true
} }
......
...@@ -46,10 +46,8 @@ module.exports = { ...@@ -46,10 +46,8 @@ module.exports = {
(options.modules || (options.modules = [])).push(autoComponentsModule) (options.modules || (options.modules = [])).push(autoComponentsModule)
} }
// 非h5平台,transformAssetUrls // transformAssetUrls
if (process.env.UNI_PLATFORM !== 'h5') {
(options.modules || (options.modules = [])).push(require('./asset-url')) (options.modules || (options.modules = [])).push(require('./asset-url'))
}
options.isUnaryTag = isUnaryTag options.isUnaryTag = isUnaryTag
// 将 autoComponents 挂在 isUnaryTag 上边 // 将 autoComponents 挂在 isUnaryTag 上边
......
#!/usr/bin/env node #!/usr/bin/env node
const path = require('path')
const {
error
} = require('@vue/cli-shared-utils')
const {
initCustomScript
} = require('@dcloudio/uni-cli-shared/lib/package')
const Service = require('@vue/cli-service')
const yargsParser = require('yargs-parser') const yargsParser = require('yargs-parser')
const argv = yargsParser(process.argv.slice(2)) const argv = yargsParser(process.argv.slice(2))
if (argv._[0] === 'custom') { const action = argv._[0]
const script = argv._[1] if (action === 'custom') {
if (!script) { require('../lib/commands/custom')(argv)
console.error(`请指定 package.json->uni-app->scripts 下的 script 名称`) } else if (action === 'invoke') {
process.exit(0) require('../lib/commands/invoke')(argv)
}
const scriptOptions = initCustomScript(script, path.resolve(process.cwd(), 'package.json'))
if (scriptOptions && scriptOptions.title) {
// console.log('>' + scriptOptions.title)
}
} else { } else {
console.error(`uniapp-cli custom script`)
process.exit(0) process.exit(0)
} }
// @vue/cli-service/lib/Service.js
const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())
const command = (
process.env.NODE_ENV === 'development' &&
process.env.UNI_PLATFORM === 'h5'
) ? 'uni-serve'
: 'uni-build'
service.run(command, {
watch: process.env.NODE_ENV === 'development',
minimize: process.env.UNI_MINIMIZE === 'true',
clean: false
}).catch(err => {
error(err)
process.exit(1)
})
const path = require('path')
const Service = require('@vue/cli-service')
const {
initCustomScript
} = require('@dcloudio/uni-cli-shared/lib/package')
module.exports = function custom (argv) {
const script = argv._[1]
if (!script) {
console.error(`请指定 package.json->uni-app->scripts 下的 script 名称`)
process.exit(0)
}
const scriptOptions = initCustomScript(script, path.resolve(process.cwd(), 'package.json'))
if (scriptOptions && scriptOptions.title) {
// console.log('>' + scriptOptions.title)
}
// @vue/cli-service/lib/Service.js
const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())
const command = (
process.env.NODE_ENV === 'development' &&
process.env.UNI_PLATFORM === 'h5'
) ? 'uni-serve'
: 'uni-build'
service.run(command, {
watch: process.env.NODE_ENV === 'development',
minimize: process.env.UNI_MINIMIZE === 'true',
clean: false
}).catch(err => {
console.error(err)
process.exit(1)
})
}
const fs = require('fs')
const path = require('path')
module.exports = async function add (argv) {
const pluginName = argv._[1]
if (!pluginName) {
console.error(`请指定插件名称`)
process.exit(0)
}
const pluginPkg = require(pluginName + '/package.json')
const options = pluginPkg['uni-app']
if (!options) {
console.error(`插件不合法`)
process.exit(0)
}
const name = options.name
if (!name) {
console.error(`插件名称不存在`)
process.exit(0)
}
const scripts = options.scripts || {
['dev:' + name]: `cross-env NODE_ENV=development UNI_PLATFORM=${name} vue-cli-service uni-build --watch`,
['build:' + name]: `cross-env NODE_ENV=production UNI_PLATFORM=${name} vue-cli-service uni-build`
}
const pkgPath = path.resolve(process.cwd(), 'package.json')
const pkg = require(pkgPath)
if (!pkg.scripts) {
pkg.scripts = {}
}
let changed = false
Object.keys(scripts).forEach(script => {
if (!pkg.scripts[script]) {
changed = true
pkg.scripts[script] = scripts[script]
}
})
if (changed) {
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2))
}
}
...@@ -62,6 +62,7 @@ function fixBooleanAttribute (el) { ...@@ -62,6 +62,7 @@ function fixBooleanAttribute (el) {
} }
module.exports = { module.exports = {
h5: true,
modules: [require('../format-text'), { modules: [require('../format-text'), {
preTransformNode (el, options) { preTransformNode (el, options) {
fixBooleanAttribute(el) fixBooleanAttribute(el)
......
...@@ -167,10 +167,14 @@ module.exports = { ...@@ -167,10 +167,14 @@ module.exports = {
webpackConfig.plugins.delete('preload-index') webpackConfig.plugins.delete('preload-index')
} }
const compilerOptions = require('./compiler-options')
if (publicPath === './') {
compilerOptions.publicPath = publicPath
}
modifyVueLoader(webpackConfig, { modifyVueLoader(webpackConfig, {
isH5: true, isH5: true,
hotReload: true hotReload: true
}, require('./compiler-options'), api) }, compilerOptions, api)
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === 'production') {
require('./cssnano-options')(webpackConfig) require('./cssnano-options')(webpackConfig)
......
...@@ -133,7 +133,7 @@ module.exports = function getSplitChunks () { ...@@ -133,7 +133,7 @@ module.exports = function getSplitChunks () {
return chunks.find(item => !subPackageRoots.find(root => item.name.indexOf(root) === 0)) return chunks.find(item => !subPackageRoots.find(root => item.name.indexOf(root) === 0))
} }
const subPackageRoots = Object.keys(process.UNI_SUBPACKAGES) const subPackageRoots = Object.keys(process.UNI_SUBPACKAGES).map(root => root + '/')
Object.keys(process.UNI_SUBPACKAGES).forEach(root => { Object.keys(process.UNI_SUBPACKAGES).forEach(root => {
(function (root) { (function (root) {
...@@ -145,7 +145,7 @@ module.exports = function getSplitChunks () { ...@@ -145,7 +145,7 @@ module.exports = function getSplitChunks () {
const matchSubPackages = findSubPackages(chunks) const matchSubPackages = findSubPackages(chunks)
if ( if (
matchSubPackages.size === 1 && matchSubPackages.size === 1 &&
matchSubPackages.has(root) && matchSubPackages.has(root + '/') &&
!hasMainPackage(chunks) !hasMainPackage(chunks)
) { ) {
if (process.env.UNI_OPT_TRACE) { if (process.env.UNI_OPT_TRACE) {
......
...@@ -80,6 +80,8 @@ function assertType (value, type) { ...@@ -80,6 +80,8 @@ function assertType (value, type) {
if (!valid && t === 'object') { if (!valid && t === 'object') {
valid = value instanceof type valid = value instanceof type
} }
} else if (value.byteLength >= 0) {
valid = true
} else if (expectedType === 'Object') { } else if (expectedType === 'Object') {
valid = isPlainObject(value) valid = isPlainObject(value)
} else if (expectedType === 'Array') { } else if (expectedType === 'Array') {
......
...@@ -59,7 +59,7 @@ export const request = { ...@@ -59,7 +59,7 @@ export const request = {
} }
}, },
data: { data: {
type: [Object, String, ArrayBuffer], type: [Object, String, Array, ArrayBuffer],
validator (value, params) { validator (value, params) {
params.data = value || '' params.data = value || ''
} }
......
...@@ -4,11 +4,11 @@ import { ...@@ -4,11 +4,11 @@ import {
} from '../../platform' } from '../../platform'
const callbacks = { const callbacks = {
pause: [], pause: null,
resume: [], resume: null,
start: [], start: null,
stop: [], stop: null,
error: [] error: null
} }
class RecorderManager { class RecorderManager {
...@@ -17,15 +17,13 @@ class RecorderManager { ...@@ -17,15 +17,13 @@ class RecorderManager {
const state = res.state const state = res.state
delete res.state delete res.state
delete res.errMsg delete res.errMsg
callbacks[state].forEach(callback => { if (typeof callbacks[state] === 'function') {
if (typeof callback === 'function') { callbacks[state](res)
callback(res)
} }
}) })
})
} }
onError (callback) { onError (callback) {
callbacks.error.push(callback) callbacks.error = callback
} }
onFrameRecorded (callback) { onFrameRecorded (callback) {
...@@ -37,16 +35,16 @@ class RecorderManager { ...@@ -37,16 +35,16 @@ class RecorderManager {
} }
onPause (callback) { onPause (callback) {
callbacks.pause.push(callback) callbacks.pause = callback
} }
onResume (callback) { onResume (callback) {
callbacks.resume.push(callback) callbacks.resume = callback
} }
onStart (callback) { onStart (callback) {
callbacks.start.push(callback) callbacks.start = callback
} }
onStop (callback) { onStop (callback) {
callbacks.stop.push(callback) callbacks.stop = callback
} }
pause () { pause () {
invokeMethod('operateRecorder', { invokeMethod('operateRecorder', {
......
...@@ -33,6 +33,14 @@ const handleData = { ...@@ -33,6 +33,14 @@ const handleData = {
[PAGE_CREATE]: function onPageCreate (data) { [PAGE_CREATE]: function onPageCreate (data) {
const [pageId, pagePath, pageOptions] = data const [pageId, pagePath, pageOptions] = data
document.title = `${pagePath}[${pageId}]` document.title = `${pagePath}[${pageId}]`
// 页面存在横竖屏切换时,预加载的 webview 的 fontSize 需要再次校正一下
const oldFontSize = document.documentElement.style.fontSize
const newFontSize = document.documentElement.clientWidth / 20 + 'px'
if (oldFontSize !== newFontSize) {
document.documentElement.style.fontSize = newFontSize
}
// 设置当前页面伪对象,方便其他地方使用 getCurrentPages 获取当前页面 id,route // 设置当前页面伪对象,方便其他地方使用 getCurrentPages 获取当前页面 id,route
setCurrentPage(pageId, pagePath) setCurrentPage(pageId, pagePath)
// 通知页面创建,根据当前页面配置信息,初始化部分事件 // 通知页面创建,根据当前页面配置信息,初始化部分事件
......
...@@ -212,6 +212,11 @@ const protocols = { // 需要做转换的 API 列表 ...@@ -212,6 +212,11 @@ const protocols = { // 需要做转换的 API 列表
apFilePath: 'tempFilePath' apFilePath: 'tempFilePath'
} }
}, },
getFileInfo: {
args: {
filePath: 'apFilePath'
}
},
chooseVideo: { chooseVideo: {
// 支付宝小程序文档中未找到(仅在getSetting处提及),但实际可用 // 支付宝小程序文档中未找到(仅在getSetting处提及),但实际可用
returnValue: { returnValue: {
......
### 快应用适配教程 ## 快应用适配教程
使用 uni-app 规范适配快应用
#### 准备 - uni-app文档 [https://uniapp.dcloud.io/](https://uniapp.dcloud.io/)
- 快应用文档 [https://doc.quickapp.cn/](https://doc.quickapp.cn/)
1.安装 [快应用调试器](https://statres.quickapp.cn/quickapp/quickapp/201806/file/quickapp_debugger.apk)
2.打开快应用调试器,下载平台(快应用预览版:版本号1060)
3.安装 openssl(windows系统)
#### 搭建
1.创建 `hello uni-app` 测试工程
```
vue create -p dcloudio/uni-preset-vue#alpha my-qa-project -n
```
目前手动安装依赖库: 根目录执行
```
yarn add @dcloudio/uni-quickapp@alpha -D
```
2.生成证书 `certificate.pem``private.pem`:到目录 `src/sign/debug/` ### 开发
```
openssl req -newkey rsa:2048 -nodes -keyout private.pem -x509 -days 3650 -out certificate.pem
```
3.编译快应用 `rpk` 1.Fork 仓库 `uni-app` [https://github.com/dcloudio/uni-app](https://github.com/dcloudio/uni-app),切换到 dev 分支
```
npm run dev:quickapp
```
4.开启debug在线更新服务 2.使用 Vue 规范开发组件,参考 `Button` 组件及 `clipboard` 示例
``` ```
npm run serve:quickapp - button `src/platforms/quickapp/view/components/button`
- clipboard `src/platforms/quickapp/service/api/device/clipboard`
``` ```
5.打开快应用调试器,扫码安装或右上角设置服务器地址(注意带上`http://`,关闭USB调试可看到扫码)
6.修改代码后,会主动通知调试器更新,或者手动点击在线更新(调试可以点击右下角开始调试)
#### 开发调试代码
1.Fork 仓库 `uni-app` [https://github.com/dcloudio/uni-app](https://github.com/dcloudio/uni-app),切换到 dev 分支
2.编译 (输出目录`packages/uni-quickapp`) 2.编译 (输出目录`packages/uni-quickapp`)
``` ```
npm run build:quickapp npm run build:quickapp
``` ```
3.手动替换编译输出目录 `packages/uni-quickapp` 到测试工程 `node_modules/@dcloudio/uni-quickapp`,也可以考虑自己npm link本地`uni-quickapp`包(需要考虑三方依赖)
4.使用 pull request 提交代码
#### `uni-app` 目录说明 #### `uni-app` 目录说明
``` ```
...@@ -76,10 +41,63 @@ src ...@@ -76,10 +41,63 @@ src
│ └─button │ └─button
``` ```
### 测试
#### 开发示例 #### 搭建测试环境
- button 组件 `src/platforms/quickapp/view/components/button`
- clipboard API `src/platforms/quickapp/service/api/device/clipboard` 1.安装 [快应用调试器](https://statres.quickapp.cn/quickapp/quickapp/201806/file/quickapp_debugger.apk)
2.打开快应用调试器,下载平台(快应用预览版:版本号1060)
#### 搭建测试工程
1.创建测试工程 (推荐使用空项目,可选 `hello uni-app` 工程,包含组件及API示例,工程较复杂编译比较耗时)
```
vue create -p dcloudio/uni-preset-vue#alpha my-qa-project -n
```
```
<!--button 示例-->
<template>
<view>
<button>Button</button>
</view>
</template>
<script>
export default {
data() {
return {
}
},
onLoad() {
},
methods: {
}
}
</script>
<style>
</style>
```
2.编译快应用 `rpk`
```
npm run dev:quickapp
```
3.开启debug在线更新服务
```
npm run serve:quickapp
```
4.打开快应用调试器,扫码安装或右上角设置服务器地址(注意带上`http://`,关闭USB调试可看到扫码)
5.修改代码后,会主动通知调试器更新,或者手动点击在线更新(调试可以点击右下角开始调试)
6.手动替换编译输出目录 `packages/uni-quickapp` 到测试工程 `node_modules/@dcloudio/uni-quickapp`, 可以考虑 `npm link`
### 提交代码
使用 `pull request` 提交代码
...@@ -96,6 +114,14 @@ src ...@@ -96,6 +114,14 @@ src
} }
``` ```
### 生成证书 `certificate.pem` 和 `private.pem`
安装 openssl(windows系统)
```
openssl req -newkey rsa:2048 -nodes -keyout private.pem -x509 -days 3650 -out certificate.pem
```
- 发布快应用时需要使用自己的证书,开发期间为debug证书
注意: 注意:
hello uni-app使用了px单位,在快应用里等同于rpx,故页面显示异常,非调试ui阶段, hello uni-app使用了px单位,在快应用里等同于rpx,故页面显示异常,非调试ui阶段,
可以自己修改manifest.json->quickapp->config->designWidth=自己手头设备的逻辑像素,如360 可以自己修改manifest.json->quickapp->config->designWidth=自己手头设备的逻辑像素,如360
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册