diff --git a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js index 1ee21c560a42d63837d40e118fad9006f94dd506..0cbb251167de77fea5d444930ffed4231d55d592 100644 --- a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js +++ b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.service.spec.js @@ -79,10 +79,10 @@ describe('codegen', () => { assertCodegen( `
A{{ d | e | f }}B{{text}}C
`, `with(this){return _c('div',{attrs:{"id":_$s(0,'a-id','a'+b),"_i":0}},[_v((_$s(0,'t0-0',_s(_f("f")(_f("e")(d)))))+(_$s(0,'t0-1',_s(text))))])}` - ) - assertCodegen( - `{{obj.param1}}123123{{obj.param1}}123123{{obj.param1}} -{{obj.param3}}---{{obj.param3}} {{obj.param2}}aaaa{{obj.param2}}aaaa{{obj.param2}}`, - `with(this){return _c('view',[_v((_$s(0,'t0-0',_s(obj.param1)))+(_$s(0,'t0-1',_s(obj.param1)))+(_$s(0,'t0-2',_s(obj.param1)))),_c('text',[_v((_$s(1,'t0-0',_s(obj.param3)))+(_$s(1,'t0-1',_s(obj.param3))))]),_v((_$s(0,'t2-0',_s(obj.param2)))+(_$s(0,'t2-1',_s(obj.param2)))+(_$s(0,'t2-2',_s(obj.param2))))])}` + ) + assertCodegen( + `{{obj.param1}}123123{{obj.param1}}123123{{obj.param1}} -{{obj.param3}}---{{obj.param3}} {{obj.param2}}aaaa{{obj.param2}}aaaa{{obj.param2}}`, + `with(this){return _c('view',[_v((_$s(0,'t0-0',_s(obj.param1)))+(_$s(0,'t0-1',_s(obj.param1)))+(_$s(0,'t0-2',_s(obj.param1)))),_c('text',[_v((_$s(1,'t0-0',_s(obj.param3)))+(_$s(1,'t0-1',_s(obj.param3))))]),_v((_$s(0,'t2-0',_s(obj.param2)))+(_$s(0,'t2-1',_s(obj.param2)))+(_$s(0,'t2-2',_s(obj.param2))))])}` ) }) @@ -140,25 +140,48 @@ describe('codegen', () => { '', `with(this){return _c('view',{attrs:{"data-b":_$s(0,'a-data-b',b),"_i":0}})}` ) - }) - it('generate v-if directive', () => { - assertCodegen( - '123d', - `with(this){return (_$s(0,'i',a))?_c('text'):(_$s(1,'e',b))?_c('text'):(_$s(2,'e',c))?_c('text'):_c('text')}` - ) - }) - it('generate dynamic slot', () => { - assertCodegen( - '', - `with(this){return _c('base-layout',{attrs:{"_i":0},scopedSlots:_u([{key:_$s(1,'st',dynamicSlotName),fn:function(_empty_, _svm, _si){return undefined}}],null,true)})}` - ) - }) - - it('generate ref', () => { - assertCodegen( - '

', - `with(this){return _c('p',{ref:_$s(0,'ref',component1)})}` - ) - }) + }) + it('generate v-if directive', () => { + assertCodegen( + '123d', + `with(this){return (_$s(0,'i',a))?_c('text'):(_$s(1,'e',b))?_c('text'):(_$s(2,'e',c))?_c('text'):_c('text')}` + ) + }) + it('generate dynamic slot', () => { + assertCodegen( + '', + `with(this){return _c('base-layout',{attrs:{"_i":0},scopedSlots:_u([{key:_$s(1,'st',dynamicSlotName),fn:function(_empty_, _svm, _si){return undefined}}],null,true)})}` + ) + }) + + it('generate ref', () => { + assertCodegen( + '

', + `with(this){return _c('p',{ref:_$s(0,'ref',component1)})}` + ) + }) + + it('generate image', () => { + assertCodegen( + '', + `with(this){return _c('image',{attrs:{"src":_$s(0,'a-src',src),"_i":0}})}` + ) + assertCodegen( + '', + `with(this){return _c('image',{attrs:{"_i":0}})}` + ) + assertCodegen( + '', + `with(this){return _c('image',{attrs:{"src":_$s(0,'a-src',"/"+require("../static/logo.png")),"_i":0}})}` + ) + assertCodegen( + '', + `with(this){return _c('image',{attrs:{"_i":0}})}` + ) + assertCodegen( + '', + `with(this){return _c('image',{attrs:{"_i":0}})}` + ) + }) }) /* eslint-enable quotes */ diff --git a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.view.spec.js b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.view.spec.js index 8ffd4da7a788fd280e07397f181ce5b5faf532f9..261a67392a6f3afe385f4c9d2cd3d5d18ae71074 100644 --- a/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.view.spec.js +++ b/packages/uni-template-compiler/__tests__/compiler-app-plus-extra.view.spec.js @@ -40,12 +40,12 @@ describe('codegen', () => { '
{{hi}}
', `with(this){return _c('div',{attrs:{"_i":0}},[_t("default",[_c('div',{attrs:{"_i":2}},[_v((_$g(2,'t0-0')))])],{"_i":1})],2)}` ) - }) - it('generate text with multiple statements', () => { - assertCodegen( - `{{obj.param1}}123123{{obj.param1}}123123{{obj.param1}} -{{obj.param3}}---{{obj.param3}} {{obj.param2}}aaaa{{obj.param2}}aaaa{{obj.param2}}`, - `with(this){return _c('v-uni-view',{attrs:{"_i":0}},[_v((_$g(0,'t0-0'))+"123123"+(_$g(0,'t0-1'))+"123123"+(_$g(0,'t0-2'))),_c('v-uni-text',{attrs:{"_i":1}},[_v("-"+(_$g(1,'t0-0'))+"---"+(_$g(1,'t0-1')))]),_v((_$g(0,'t2-0'))+"aaaa"+(_$g(0,'t2-1'))+"aaaa"+(_$g(0,'t2-2')))],1)}` - ) + }) + it('generate text with multiple statements', () => { + assertCodegen( + `{{obj.param1}}123123{{obj.param1}}123123{{obj.param1}} -{{obj.param3}}---{{obj.param3}} {{obj.param2}}aaaa{{obj.param2}}aaaa{{obj.param2}}`, + `with(this){return _c('v-uni-view',{attrs:{"_i":0}},[_v((_$g(0,'t0-0'))+"123123"+(_$g(0,'t0-1'))+"123123"+(_$g(0,'t0-2'))),_c('v-uni-text',{attrs:{"_i":1}},[_v("-"+(_$g(1,'t0-0'))+"---"+(_$g(1,'t0-1')))]),_v((_$g(0,'t2-0'))+"aaaa"+(_$g(0,'t2-1'))+"aaaa"+(_$g(0,'t2-2')))],1)}` + ) }) it('generate v-slot', () => { assertCodegen( @@ -81,24 +81,46 @@ describe('codegen', () => { '', `with(this){return _c('v-uni-view',{attrs:{"data-a":"1","data-b":_$g(0,'a-data-b'),"_i":0}})}` ) - }) - it('generate v-if directive', () => { - assertCodegen( - '123d', - `with(this){return (_$g(0,'i'))?_c('v-uni-text',{attrs:{"_i":0}},[_v("1")]):(_$g(1,'e'))?_c('v-uni-text',{attrs:{"_i":1}},[_v("2")]):(_$g(2,'e'))?_c('v-uni-text',{attrs:{"_i":2}},[_v("3")]):_c('v-uni-text',{attrs:{"_i":3}},[_v("d")])}` - ) - }) - it('generate dynamic slot', () => { - assertCodegen( - '', - `with(this){return _c('base-layout',{attrs:{"_i":0},scopedSlots:_u([{key:_$g(1,'st'),fn:function(_empty_, _svm, _si){return undefined}}],null,true)})}` - ) - }) - it('generate ref', () => { - assertCodegen( - '

', - `with(this){return _c('p',{ref:_$g(0,'ref'),attrs:{"_i":0}})}` - ) + }) + it('generate v-if directive', () => { + assertCodegen( + '123d', + `with(this){return (_$g(0,'i'))?_c('v-uni-text',{attrs:{"_i":0}},[_v("1")]):(_$g(1,'e'))?_c('v-uni-text',{attrs:{"_i":1}},[_v("2")]):(_$g(2,'e'))?_c('v-uni-text',{attrs:{"_i":2}},[_v("3")]):_c('v-uni-text',{attrs:{"_i":3}},[_v("d")])}` + ) + }) + it('generate dynamic slot', () => { + assertCodegen( + '', + `with(this){return _c('base-layout',{attrs:{"_i":0},scopedSlots:_u([{key:_$g(1,'st'),fn:function(_empty_, _svm, _si){return undefined}}],null,true)})}` + ) + }) + it('generate ref', () => { + assertCodegen( + '

', + `with(this){return _c('p',{ref:_$g(0,'ref'),attrs:{"_i":0}})}` + ) + }) + it('generate image', () => { + assertCodegen( + '', + `with(this){return _c('v-uni-image',{attrs:{"src":_$g(0,'a-src'),"_i":0}})}` + ) + assertCodegen( + '', + `with(this){return _c('v-uni-image',{attrs:{"src":"/static/logo.png","_i":0}})}` + ) + assertCodegen( + '', + `with(this){return _c('v-uni-image',{attrs:{"src":_$g(0,'a-src'),"_i":0}})}` + ) + assertCodegen( + '', + `with(this){return _c('v-uni-image',{attrs:{"src":"/static/logo.png","_i":0}})}` + ) + assertCodegen( + '', + `with(this){return _c('v-uni-image',{attrs:{"src":"/static/logo.png","_i":0}})}` + ) }) }) /* eslint-enable quotes */ diff --git a/packages/uni-template-compiler/lib/asset-url.js b/packages/uni-template-compiler/lib/asset-url.js index 4e7232bfad52ea9444f3784278f1d9686cd7b1ba..d6b28096732b9322f09bb983905368719ac4413f 100644 --- a/packages/uni-template-compiler/lib/asset-url.js +++ b/packages/uni-template-compiler/lib/asset-url.js @@ -1,3 +1,5 @@ +const url = require('url') + const transformAssetUrls = { 'audio': 'src', 'video': ['src', 'poster'], @@ -14,7 +16,47 @@ const transformAssetUrls = { 'u-video': ['src', 'poster'] } -function rewrite (attr, name) { +function urlToRequire (url) { + const returnValue = `"${url}"` + // same logic as in transform-require.js + const firstChar = url.charAt(0) + if (firstChar === '.' || firstChar === '~' || firstChar === '@') { + if (firstChar === '~') { + const secondChar = url.charAt(1) + url = url.slice(secondChar === '/' ? 2 : 1) + } + const uriParts = parseUriParts(url) + if (!uriParts.hash) { // fixed by xxxxxx (v3 template中需要加/) + return `"/"+require("${url}")` + } else { // fixed by xxxxxx (v3 template中需要加/) + // support uri fragment case by excluding it from + // the require and instead appending it as string; + // assuming that the path part is sufficient according to + // the above caseing(t.i. no protocol-auth-host parts expected) + return `"/"+require("${uriParts.path}") + "${uriParts.hash}"` + } + } + return returnValue +} +/** + * vuejs/component-compiler-utils#22 Support uri fragment in transformed require + * @param urlString an url as a string + */ +function parseUriParts (urlString) { + // initialize return value + const returnValue = url.parse('') + if (urlString) { + // A TypeError is thrown if urlString is not a string + // @see https://nodejs.org/api/url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost + if (typeof urlString === 'string') { + // check is an uri + return url.parse(urlString) // take apart the uri + } + } + return returnValue +} + +function rewrite (attr, name, options) { if (attr.name === name) { const value = attr.value // only transform static URLs @@ -22,13 +64,17 @@ function rewrite (attr, name) { attr.value = attr.value .replace('"@/', '"/') .replace('"~@/', '"/') + if (options.service || options.view) { // v3 + attr.value = urlToRequire(attr.value.slice(1, -1)) + } return true } } return false } + module.exports = { - postTransformNode: (node) => { + postTransformNode: (node, options) => { if (!node.attrs) { return } @@ -37,9 +83,19 @@ module.exports = { return } if (typeof attributes === 'string') { - node.attrs.some(attr => rewrite(attr, attributes)) + if (node.attrs.some(attr => rewrite(attr, attributes, options))) { + if (options.service || options.view) { + node.hasBindings = true + } + } } else if (Array.isArray(attributes)) { - attributes.forEach(item => node.attrs.some(attr => rewrite(attr, item))) + attributes.forEach(item => { + if (node.attrs.some(attr => rewrite(attr, item, options))) { + if (options.service || options.view) { + node.hasBindings = true + } + } + }) } } } diff --git a/packages/uni-template-compiler/lib/auto-components.js b/packages/uni-template-compiler/lib/auto-components.js index da2a74f4f5dbb2e472141f3517e4141faab2a5e4..313db0326ed01ad4d32040b2750cc00659c030fe 100644 --- a/packages/uni-template-compiler/lib/auto-components.js +++ b/packages/uni-template-compiler/lib/auto-components.js @@ -61,7 +61,7 @@ function generateAutoComponentsCode (autoComponents, dynamic = false) { source }) => { if (dynamic) { - components.push(`'${name}': ()=>import(/* webpackChunkName: "${getWebpackChunkName(source)}" */'${source}')`) + components.push(`'${name}': function(){return import(/* webpackChunkName: "${getWebpackChunkName(source)}" */'${source}')}`) } else { components.push(`'${name}': require('${source}').default`) } diff --git a/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js b/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js index a23913e9dda6c007cc547ee38f99d1af3216362a..b7389b1b714993c29d42d1e848b05980275d918d 100644 --- a/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js +++ b/packages/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js @@ -154,7 +154,7 @@ const rules = [{ } ].concat(cssLoaders) -if (process.env.UNI_USING_NVUE_COMPILER) { +if (process.env.UNI_USING_NVUE_COMPILER || process.env.UNI_USING_V3_NATIVE) { rules.unshift({ resourceQuery: function (query) { return query.indexOf('vue&type=template') !== -1 && query.indexOf('mpType=page') !== -1 diff --git a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js index 0ed3fbbcca24107fcadf9f5f633e6d664a633139..20d3b9de5a012f9edf571361726fc7a0680b26be 100644 --- a/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js +++ b/packages/vue-cli-plugin-hbuilderx/packages/webpack-uni-nvue-loader/lib/template.js @@ -48,11 +48,18 @@ module.exports = function(content) { } // 暂时实时读取配置信息,查找是否 disableScroll const appJson = getPagesJson() - if (!appJson.nvue || !appJson.nvue.pages) { - return content + + let pageJson + if (appJson.nvue) { //旧版本 + if (!appJson.nvue || !appJson.nvue.pages) { + return content + } + const pagePath = resourcePath + '.html' + pageJson = appJson.nvue.pages.find(page => page.path === pagePath) + } else { + pageJson = appJson.pages.find(page => page.path === resourcePath) } - const pagePath = resourcePath + '.html' - const pageJson = appJson.nvue.pages.find(page => page.path === pagePath) + if (!pageJson) { return content } diff --git a/src/core/helpers/promise.js b/src/core/helpers/promise.js index 3f77edee2a896886c19ffe08262a65f306d83e0e..f36f5a54cc76ac172e88a1c32fea59b248420d08 100644 --- a/src/core/helpers/promise.js +++ b/src/core/helpers/promise.js @@ -16,7 +16,7 @@ const TASK_APIS = ['request', 'downloadFile', 'uploadFile', 'connectSocket'] const ASYNC_API = ['createBLEConnection'] -const CALLBACK_API_RE = /^on/ +const CALLBACK_API_RE = /^on|^off/ export function isContextApi (name) { return CONTEXT_API_RE.test(name) diff --git a/src/platforms/quickapp/README.md b/src/platforms/quickapp/README.md index 29b26004c9e95e99eb7bce72a422d31babf4414c..2f098e8772f4a7db95ddd36a0b4ed58d1958d2b1 100644 --- a/src/platforms/quickapp/README.md +++ b/src/platforms/quickapp/README.md @@ -7,13 +7,19 @@ 2.打开快应用调试器,下载平台(快应用预览版:版本号1060) +3.安装 openssl(windows系统) + #### 搭建 -1.创建 `hello uni-app` 工程 +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/` ``` @@ -37,32 +43,55 @@ npm run serve:quickapp #### 开发调试代码 -1.仓库 `uni-app(quickapp branch)` [https://github.com/dcloudio/uni-app/tree/quickapp](https://github.com/dcloudio/uni-app/tree/quickapp) +1.Fork 仓库 `uni-app` [https://github.com/dcloudio/uni-app](https://github.com/dcloudio/uni-app),切换到 dev 分支 + +2.编译 (输出目录`packages/uni-quickapp`) -2.目录说明: ``` -`src/platforms/quickapp/service/api` 平台的接口实现(方案同h5,app-plus) -`src/platforms/quickapp/view/components` 平台的组件实现(easycom格式,目录名与文件名一致) -`packages/uni-quickapp/lib/compiler-module` 编译阶段标签转换之类逻辑 -`packages/uni-quickapp/lib/polyfill.css` 全局样式差异代码 -`packages/uni-quickapp/lib/manifest` manifest.json的生成逻辑 +npm run build:quickapp ``` -3.编译 (输出目录`packages/uni-quickapp`) +3.手动替换编译输出目录 `packages/uni-quickapp` 到测试工程 `node_modules/@dcloudio/uni-quickapp`,也可以考虑自己npm link本地`uni-quickapp`包(需要考虑三方依赖) + +4.使用 pull request 提交代码 + + +#### `uni-app` 目录说明 + ``` -npm run build:quickapp +packages + ├─uni-quickapp + │ └─lib + │ ├─compiler-module (编译阶段标签转换之类逻辑) + │ ├─polyfill.css (全局样式差异代码) + │ └─manifest (manifest.json的生成逻辑) +src + ├─platforms + │ └─quickapp + │ ├─... + │ ├─service + │ │ └─api 平台的接口实现(方案同h5,app-plus) + │ └─view + │ └─components 平台的组件实现(easycom格式,目录名与文件名一致) + │ └─button ``` -4.可以选择手动替换到自己测试工程的`@dcloudio/uni-quickapp`里边,也可以考虑自己npm link本地`uni-quickapp`包(需要考虑三方依赖) + +#### 开发示例 +- button 组件 [https://github.com/dcloudio/uni-app/tree/master/src/platforms/quickapp/view/components/button](https://github.com/dcloudio/uni-app/tree/master/src/platforms/quickapp/view/components/button) + #### 包名配置 ``` 项目 manifest.json { - "quickapp" : { - "package": "com.example.demo" + "quickapp" : { + "config": { + "package": "com.example.demo", + "designWidth": 360 } + } } ``` diff --git a/src/platforms/quickapp/view/components/button/button.vue b/src/platforms/quickapp/view/components/button/button.vue index 1c88399143d910d5502fd7ab10a8c0325536973c..72d5138a70b8c9a819d5cf2520078086494662b0 100644 --- a/src/platforms/quickapp/view/components/button/button.vue +++ b/src/platforms/quickapp/view/components/button/button.vue @@ -1,14 +1,293 @@ - -