diff --git a/CHANGELOG.md b/CHANGELOG.md index db6008eac..fa00ca2ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,34 @@ +## [1.0.4-alpha.1] + + - 解决分包内组件js分包不彻底,优化包体积40%左右 + - 支持原生小程序组件的导入也是函数式的 + - 支持公用样式以文件的形式 @import + - 支持模板多态语法 + +## [1.0.3] + +- 发布1.0.3-alpha.0的正式版 + +## [1.0.3-alpha.0] +- Bugfixes + - 区分web端click和tap事件,由原来的click和tap统一处理成tap,改为tap和click区别对待,如果要在pc端生效click事件,那么必须绑定click而非tap + - 修复windows 上 app.json 中分包页面没有删除 + - 修复windows 上初始化项目无法运行 +- Features + - 扩展新端命令支持集成到chameleon-tool中 +## [1.0.2] + + - 修改project tododemo的package.lock.json + +## [1.0.0] + +### Bugfixes + - 修复alipay baidu qq 端引用原生组件的问题 + +## [0.4.1] +### Bugfixes + - 修复内联事件对象 $event的匹配问题 + - 修复chameleon.config.js内部配置公用miniappConfig一个对象导致的对象合并不准确问题 ## [0.4.1-alpha.1] ### Bugfixes - 修复window下分包加载的bug diff --git a/lerna.json b/lerna.json index a34f510d9..5a604d488 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/*" ], - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "command": { "publish": { "allowBranch": "master", diff --git a/packages/babel-plugin-chameleon-import/package.json b/packages/babel-plugin-chameleon-import/package.json index 29660f8a5..ac3334b4a 100644 --- a/packages/babel-plugin-chameleon-import/package.json +++ b/packages/babel-plugin-chameleon-import/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-chameleon-import", - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "description": "Component modular import plugin for babel.", "repository": { "type": "git", diff --git a/packages/chameleon-css-loader/package.json b/packages/chameleon-css-loader/package.json index a5a34cc77..bdc547d6d 100644 --- a/packages/chameleon-css-loader/package.json +++ b/packages/chameleon-css-loader/package.json @@ -1,6 +1,6 @@ { "name": "chameleon-css-loader", - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "description": "chameleon样式处理", "main": "index.js", "scripts": { diff --git a/packages/chameleon-css-loader/parser/miniapp.js b/packages/chameleon-css-loader/parser/miniapp.js index c0ac1f1be..8c2068283 100644 --- a/packages/chameleon-css-loader/parser/miniapp.js +++ b/packages/chameleon-css-loader/parser/miniapp.js @@ -6,8 +6,10 @@ const postcss = require('postcss'); module.exports = function(source, options = {}) { options.cpxType = 'rpx'; - let {cmlType} = options; - if (cmlType === 'alipay') { + let {cmlType, filePath} = options; + let globalCssPath = [`chameleon-runtime/src/platform/${cmlType}/style/index.css`, `chameleon-runtime/src/platform/${cmlType}/style/page.css`]; + let isGlobalCss = globalCssPath.some((item) => filePath.includes(item)) + if (cmlType === 'alipay' && !isGlobalCss) { //对于全局样式不能经过 addAlipayClassPlugin 这个插件进行样式唯一性的处理;比如这样的 .cml-57b5135a.scroller-wrap return postcss([cpx(options), weexPlus(), addAlipayClassPlugin(options)]).process(source).css; } else { return postcss([cpx(options), weexPlus()]).process(source).css; diff --git a/packages/chameleon-css-loader/test/parser-test/miniapp.test.js b/packages/chameleon-css-loader/test/parser-test/miniapp.test.js index d9a1ea63d..9c925d911 100644 --- a/packages/chameleon-css-loader/test/parser-test/miniapp.test.js +++ b/packages/chameleon-css-loader/test/parser-test/miniapp.test.js @@ -4,7 +4,17 @@ const expect = require('chai').expect; let source = `body {width:100cpx;font-size:26px;/* height:200px; */}`; describe('parse/miniapp', function() { it('parse cssstyle px to rpx but leave comment in style alone', function() { - let result = parseCss(source); + let result = parseCss(source,{ + cmlType:'alipay', + filePath:"chameleon-runtime/src/platform/alipay/style/index.css" + }); + expect(/100rpx/.test(result)).to.be.ok; + }) + it('parse cssstyle px to rpx but leave comment in style alone', function() { + let result = parseCss(source,{ + cmlType:'wx', + filePath:"chameleon-runtime/src/platform/alipay/style/index.css" + }); expect(/100rpx/.test(result)).to.be.ok; }) }) diff --git a/packages/chameleon-dev-proxy/package.json b/packages/chameleon-dev-proxy/package.json index e4cf93062..20b07cf92 100644 --- a/packages/chameleon-dev-proxy/package.json +++ b/packages/chameleon-dev-proxy/package.json @@ -1,6 +1,6 @@ { "name": "chameleon-dev-proxy", - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "description": "cml开发环境代理服务模块", "main": "index.js", "author": "Chameleon-Team", diff --git a/packages/chameleon-errors-webpack-plugin/package.json b/packages/chameleon-errors-webpack-plugin/package.json index 78dab689e..838ac55fe 100644 --- a/packages/chameleon-errors-webpack-plugin/package.json +++ b/packages/chameleon-errors-webpack-plugin/package.json @@ -1,5 +1,5 @@ { - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "name": "chameleon-errors-webpack-plugin", "main": "index.js", "author": "Chameleon-Team", diff --git a/packages/chameleon-linter/checkers/template/lib/json-ast-parser.js b/packages/chameleon-linter/checkers/template/lib/json-ast-parser.js index f9d2f302d..0397805b6 100644 --- a/packages/chameleon-linter/checkers/template/lib/json-ast-parser.js +++ b/packages/chameleon-linter/checkers/template/lib/json-ast-parser.js @@ -5,7 +5,8 @@ const config = require('../../../config'); function getUsingComponents(jsonAst, filePath = '') { let results = {}; - let interfaceParser = new Parser(null, config.getParserConfig().script); + let currentWorkspace = config.getCurrentWorkspace(); + let interfaceParser = new Parser(null, config.getParserConfig().script, currentWorkspace); if (jsonAst && jsonAst.base && jsonAst.base.usingComponents) { Object @@ -20,7 +21,6 @@ function getUsingComponents(jsonAst, filePath = '') { return !(infoPair.path.indexOf('plugin://') === 0); }) .forEach((infoPair) => { - let currentWorkspace = config.getCurrentWorkspace(); // filePath: is a full absolute path of the target template file // inforPair.path: is the original path of base: {usingComponents: 'path/to/referenced component'} let interfaceInfo = cmlUtils.findInterfaceFile(currentWorkspace, filePath, infoPair.path); diff --git a/packages/chameleon-linter/package.json b/packages/chameleon-linter/package.json index 1b0de8bd9..bdc930df1 100644 --- a/packages/chameleon-linter/package.json +++ b/packages/chameleon-linter/package.json @@ -1,6 +1,6 @@ { "name": "chameleon-linter", - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "description": "cml规范校验工具", "main": "index.js", "scripts": { @@ -24,10 +24,10 @@ "@babel/traverse": "^7.1.4", "bulk-require": "^1.0.1", "chalk": "^2.4.1", - "chameleon-tool-utils": "0.4.1-alpha.1", - "cml-component-parser": "0.4.1-alpha.1", - "cml-htmllint": "0.4.1-alpha.1", - "cml-js-parser": "0.4.1-alpha.1", + "chameleon-tool-utils": "1.0.4-alpha.1", + "cml-component-parser": "1.0.4-alpha.1", + "cml-htmllint": "1.0.4-alpha.1", + "cml-js-parser": "1.0.4-alpha.1", "commander": "^2.19.0", "glob": "^7.1.3", "json-lint": "^0.1.0", diff --git a/packages/chameleon-loader/package.json b/packages/chameleon-loader/package.json index 8454d2d9d..d97a3e44e 100644 --- a/packages/chameleon-loader/package.json +++ b/packages/chameleon-loader/package.json @@ -1,6 +1,6 @@ { "name": "chameleon-loader", - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "description": "chameleon cml文件处理loader", "main": "src/index.js", "directories": { @@ -18,8 +18,8 @@ "@babel/types": "^7.3.4", "babel-generator": "6.26.1", "babel-traverse": "6.26.0", - "chameleon-template-parse": "0.4.1-alpha.1", - "chameleon-tool-utils": "0.4.1-alpha.1", + "chameleon-template-parse": "1.0.4-alpha.1", + "chameleon-tool-utils": "1.0.4-alpha.1", "consolidate": "0.14.0", "de-indent": "1.0.2", "fs-extra": "^7.0.1", @@ -27,9 +27,9 @@ "he": "1.1.0", "loader-utils": "1.1.0", "lru-cache": "4.1.1", - "mvvm-interface-parser": "0.4.1-alpha.1", + "mvvm-interface-parser": "1.0.4-alpha.1", "resolve": "1.4.0", - "runtime-check": "0.4.1-alpha.1", + "runtime-check": "1.0.4-alpha.1", "source-map": "0.6.1", "vue-style-loader": "4.0.1" }, diff --git a/packages/chameleon-loader/src/cml-compile/runtime/app.js b/packages/chameleon-loader/src/cml-compile/runtime/app.js index a9d466a8c..cb312c240 100644 --- a/packages/chameleon-loader/src/cml-compile/runtime/app.js +++ b/packages/chameleon-loader/src/cml-compile/runtime/app.js @@ -1,3 +1,4 @@ import _cml_ from 'chameleon-runtime'; - -exports.default = _cml_.createApp(exports.default).getOptions() +module.exports = function(){ + _cml_.createApp(exports.default).getOptions(); +} diff --git a/packages/chameleon-loader/src/cml-compile/runtime/component.js b/packages/chameleon-loader/src/cml-compile/runtime/component.js index 99dc733a1..67000b0ab 100644 --- a/packages/chameleon-loader/src/cml-compile/runtime/component.js +++ b/packages/chameleon-loader/src/cml-compile/runtime/component.js @@ -1,3 +1,5 @@ import _cml_ from 'chameleon-runtime'; -exports.default = _cml_.createComponent(exports.default).getOptions() \ No newline at end of file +module.exports = function(){ + _cml_.createComponent(exports.default).getOptions(); +} \ No newline at end of file diff --git a/packages/chameleon-loader/src/cml-compile/runtime/index.js b/packages/chameleon-loader/src/cml-compile/runtime/index.js index a83b6a4d0..6b651a89b 100644 --- a/packages/chameleon-loader/src/cml-compile/runtime/index.js +++ b/packages/chameleon-loader/src/cml-compile/runtime/index.js @@ -1,7 +1,11 @@ const fs = require('fs'); const path = require('path'); - -module.exports = function getRunTimeSnippet(platform, type) { +const _ = module.exports = {} ; +_.getMiniAppRunTimeSnippet = function (platform, type) { return fs.readFileSync(path.join(__dirname, `./${type}.js`)) } +_.getVueRunTimeSnippet = function (platform, type) { + return fs.readFileSync(path.join(__dirname, `./web/${type}.js`)) +} + diff --git a/packages/chameleon-loader/src/cml-compile/runtime/page.js b/packages/chameleon-loader/src/cml-compile/runtime/page.js index a3755062d..245a69c06 100644 --- a/packages/chameleon-loader/src/cml-compile/runtime/page.js +++ b/packages/chameleon-loader/src/cml-compile/runtime/page.js @@ -1,3 +1,5 @@ import _cml_ from 'chameleon-runtime'; -exports.default = _cml_.createPage(exports.default).getOptions() \ No newline at end of file +module.exports = function(){ + _cml_.createPage(exports.default).getOptions(); +} \ No newline at end of file diff --git a/packages/chameleon-loader/src/cml-compile/runtime/web/app.js b/packages/chameleon-loader/src/cml-compile/runtime/web/app.js new file mode 100644 index 000000000..118fb45ba --- /dev/null +++ b/packages/chameleon-loader/src/cml-compile/runtime/web/app.js @@ -0,0 +1,2 @@ +import _cml_ from 'chameleon-runtime'; +exports.default = _cml_.createApp(exports.default).getOptions() \ No newline at end of file diff --git a/packages/chameleon-loader/src/cml-compile/runtime/web/component.js b/packages/chameleon-loader/src/cml-compile/runtime/web/component.js new file mode 100644 index 000000000..99dc733a1 --- /dev/null +++ b/packages/chameleon-loader/src/cml-compile/runtime/web/component.js @@ -0,0 +1,3 @@ +import _cml_ from 'chameleon-runtime'; + +exports.default = _cml_.createComponent(exports.default).getOptions() \ No newline at end of file diff --git a/packages/chameleon-loader/src/cml-compile/runtime/web/page.js b/packages/chameleon-loader/src/cml-compile/runtime/web/page.js new file mode 100644 index 000000000..a3755062d --- /dev/null +++ b/packages/chameleon-loader/src/cml-compile/runtime/web/page.js @@ -0,0 +1,3 @@ +import _cml_ from 'chameleon-runtime'; + +exports.default = _cml_.createPage(exports.default).getOptions() \ No newline at end of file diff --git a/packages/chameleon-loader/src/cml-compile/wxml-selector.js b/packages/chameleon-loader/src/cml-compile/wxml-selector.js index 733fc5257..5af80602d 100644 --- a/packages/chameleon-loader/src/cml-compile/wxml-selector.js +++ b/packages/chameleon-loader/src/cml-compile/wxml-selector.js @@ -1,27 +1,43 @@ - +/*这个文件用来处理原生小程序组件*/ const loaderUtils = require('loader-utils'); const fs = require('fs'); const cmlUtils = require('chameleon-tool-utils'); +const path = require('path'); module.exports = function(content) { const self = this; const resource = this.resourcePath; + const extName = path.extname(resource); + const cssExt = { + '.wxml': '.wxss', + '.axml': '.acss', + '.swan': '.css', + '.qml': '.qss' + } + const styles = cssExt[extName]; const query = loaderUtils.getOptions(this) || {} const type = query.type; let targetFilePath = ''; let output = ''; let extMap = { script: '.js', - styles: '.wxss' + styles } - targetFilePath = resource.replace(/\.wxml/, extMap[type]); + // targetFilePath = resource.replace(/\.wxml/, extMap[type]); + targetFilePath = resource.replace(new RegExp(`${extName}$`), extMap[type]); if (!cmlUtils.isFile(targetFilePath)) { throw new Error(`can't find ${targetFilePath}`) } else { self.addDependency(targetFilePath); output = fs.readFileSync(targetFilePath, {encoding: 'utf-8'}) } + if(type === 'script'){ + return `module.exports = function(){\n + ${output} + }` + } + return output; } diff --git a/packages/chameleon-loader/src/loader.js b/packages/chameleon-loader/src/loader.js index 3bd3a454d..a19f7fde5 100644 --- a/packages/chameleon-loader/src/loader.js +++ b/packages/chameleon-loader/src/loader.js @@ -7,7 +7,7 @@ const loaderUtils = require('loader-utils') const normalize = require('./utils/normalize') const componentNormalizerPath = normalize.lib('runtime/component-normalizer') const fs = require('fs'); -const getRunTimeSnippet = require('./cml-compile/runtime/index.js'); +const {getVueRunTimeSnippet} = require('./cml-compile/runtime/index.js'); var compileTemplate = require('chameleon-template-parse'); @@ -97,7 +97,8 @@ module.exports = function (content) { const isWxmlComponent = extName === '.wxml'; const isAxmlComponent = extName === '.axml'; const isSwanComponent = extName === '.swan'; - const isMiniAppRawComponent = isWxmlComponent || isAxmlComponent || isSwanComponent; + const isQmlComponent = extName === '.qml'; + const isMiniAppRawComponent = isWxmlComponent || isAxmlComponent || isSwanComponent || isQmlComponent; if(!isMiniAppRawComponent) { //处理script cml-type为json的内容 content = cmlUtils.deleteScript({content, cmlType: 'json'}); @@ -164,7 +165,7 @@ module.exports = function (content) { qq: 'qml' } //小程序模板后缀正则 - const miniTplExtReg = /(\.wxml|\.axml)$/; + const miniTplExtReg = /(\.wxml|\.axml|\.swan|\.qml)$/; const miniCmlReg = /(\.cml|\.wx\.cml|\.alipay\.cml|\.qq\.cml|\.baidu\.cml)$/; if(isMiniAppRawComponent) { @@ -208,7 +209,6 @@ module.exports = function (content) { // 引用微信小程序组件处理 function miniAppRawComponentHandler() { - if((cmlType === 'wx' && extName === '.wxml') || (cmlType === 'alipay' && extName === '.axml') || (cmlType === 'baidu' && extName === '.swan') || (cmlType === 'qq' && extName === '.qml')) { //生成json文件 let jsonFile = filePath.replace(miniTplExtReg,'.json'); @@ -223,8 +223,10 @@ module.exports = function (content) { miniAppScript.addMiniAppScript(self,filePath,context,cmlType) var styleString = getWxmlRequest('styles'); var scriptString = getWxmlRequest('script'); + var entryBasePath = entryPath.replace(miniTplExtReg, ''); output += `var __cml__style = ${styleString};\n` - output += `var __cml__script = ${scriptString};\n` + output += `var __cml__script = ${scriptString};\n + __CML__GLOBAL.__CMLCOMPONNETS__['${entryBasePath}'] = __cml__script;\n` //采用分离的方式,入口js会放到static/js下,需要再生成入口js去require该js var jsFileName = entryPath.replace(miniTplExtReg, '.js'); @@ -240,7 +242,6 @@ module.exports = function (content) { npmComponents.forEach(item=>{ componentDeps.push(item.filePath); }) - let newJsonObj = jsonHandler(self, jsonObject, cmlType, componentDeps) || {}; newJsonObj.usingComponents = newJsonObj.usingComponents || {}; let usingComponents ={} ; @@ -310,9 +311,9 @@ module.exports = function (content) { var scriptRequireString = script.src ? getRequireForImport('script', script) : getRequire('script', script) - - output += `var __cml__script = ${scriptRequireString};\n` - + var entryBasePath = entryPath.replace(miniCmlReg, ''); + output += `var __cml__script = ${scriptRequireString};\n + __CML__GLOBAL.__CMLCOMPONNETS__['${entryBasePath}'] = __cml__script;\n` //采用分离的方式,入口js会放到static/js下,需要再生成入口js去require该js var jsFileName = entryPath.replace(miniCmlReg, '.js'); @@ -349,7 +350,7 @@ module.exports = function (content) { entryContent += "__CML__GLOBAL.Page = Page;\n" } entryContent += `require('${relativePath}/static/js/common.js')\n`; - entryContent += `require('${relativePath}/static/js/${jsFileName}')\n`; + entryContent += `require('${relativePath}/static/js/${jsFileName}')()\n`; self.emitFile(jsFileName, entryContent); @@ -427,7 +428,7 @@ module.exports = function (content) { function handleVueScript() { let { defineComponets, componetsStr } = getComponents(); - let runtimeSnippet = getRunTimeSnippet(cmlType, type); + let runtimeSnippet = getVueRunTimeSnippet(cmlType, type); let scriptCode = getScriptCode(self, cmlType, scriptContent, media, options.check); return ` ${defineComponets} diff --git a/packages/chameleon-loader/src/selector.js b/packages/chameleon-loader/src/selector.js index a89a34025..4563a6893 100644 --- a/packages/chameleon-loader/src/selector.js +++ b/packages/chameleon-loader/src/selector.js @@ -4,7 +4,7 @@ const path = require('path') const parse = require('./parser') -const getRunTimeSnippet = require('./cml-compile/runtime/index.js'); +const {getMiniAppRunTimeSnippet} = require('./cml-compile/runtime/index.js'); const {getScriptCode} = require('./interface-check/getScriptCode.js'); const cmlUtils = require('chameleon-tool-utils'); @@ -33,13 +33,19 @@ module.exports = function (content) { let pageCssPath = path.join(cml.projectRoot, 'node_modules', `chameleon-runtime/src/platform/${query.cmlType}/style/page.css`) let hasPageCss = cmlUtils.isFile(pageCssPath) if (query.fileType === 'page' && hasPageCss) { + // output = ` + // @import 'chameleon-runtime/src/platform/${query.cmlType}/style/page.css'; + // ${output} + // ` output = ` - @import 'chameleon-runtime/src/platform/${query.cmlType}/style/page.css'; ${output} ` } else { + // output = ` + // @import 'chameleon-runtime/src/platform/${query.cmlType}/style/index.css'; + // ${output} + // ` output = ` - @import 'chameleon-runtime/src/platform/${query.cmlType}/style/index.css'; ${output} ` } @@ -47,7 +53,7 @@ module.exports = function (content) { } if (query.type == 'script') { // 拼接wx所需要的运行时代码,如果在loader中拼接,拼接的代码将不会过loader了 - let runtimeScript = getRunTimeSnippet(query.cmlType, query.fileType); + let runtimeScript = getMiniAppRunTimeSnippet(query.cmlType, query.fileType); output = getScriptCode(loaderContext, query.cmlType, output, query.media, query.check); output = ` ${output}\n diff --git a/packages/chameleon-miniapp-target/package.json b/packages/chameleon-miniapp-target/package.json index 908b82f7c..7653da53d 100644 --- a/packages/chameleon-miniapp-target/package.json +++ b/packages/chameleon-miniapp-target/package.json @@ -1,6 +1,6 @@ { "name": "chameleon-miniapp-target", - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "description": "chameleon 小程序webpack的target", "main": "src/index.js", "scripts": { @@ -14,7 +14,7 @@ "webpack": "^3.12.0" }, "dependencies": { - "chameleon-tool-utils": "0.4.1-alpha.1" + "chameleon-tool-utils": "1.0.4-alpha.1" }, "mail": "ChameleonCore@didiglobal.com", "gitHead": "5ddcde4330774710f7646559446e008f7785ce00" diff --git a/packages/chameleon-miniapp-target/src/JsonpChunkTemplatePlugin.js b/packages/chameleon-miniapp-target/src/JsonpChunkTemplatePlugin.js index 166975205..e7f5843e6 100644 --- a/packages/chameleon-miniapp-target/src/JsonpChunkTemplatePlugin.js +++ b/packages/chameleon-miniapp-target/src/JsonpChunkTemplatePlugin.js @@ -30,7 +30,11 @@ class JsonpChunkTemplatePlugin { if(entries.length > 0) { source.add(`,${JSON.stringify(entries)}`); } - source.add(")"); + source.add(")\n"); + if(chunk.name !== 'common'){ + + source.add(`module.exports = __CML__GLOBAL.__CMLCOMPONNETS__['${chunk.name}']`) + } return source; }); chunkTemplate.plugin("hash", function(hash) { diff --git a/packages/chameleon-miniapp-target/src/JsonpMainTemplatePlugin.js b/packages/chameleon-miniapp-target/src/JsonpMainTemplatePlugin.js index affb0ab3d..212a420e7 100644 --- a/packages/chameleon-miniapp-target/src/JsonpMainTemplatePlugin.js +++ b/packages/chameleon-miniapp-target/src/JsonpMainTemplatePlugin.js @@ -205,8 +205,10 @@ this[${JSON.stringify(hotUpdateFunction)}] = ${runtimeSource}`; mainTemplate.plugin("render", (beforeMainSource, chunk, hash, moduleTemplate, dependencyTemplates) => { //beforeMainSource 是每部的MainTemplate render之后的代码 + // __CMLCOMPONNETS__ 是用于存放每个组件的执行函数 const source = new ConcatSource(); source.add(`/******/ var __CML__GLOBAL = {};\n`); + source.add(`/******/ __CML__GLOBAL.__CMLCOMPONNETS__ = {};\n`); source.add(beforeMainSource); source.add(`\r\n /******/ module.exports = __CML__GLOBAL;`); return source; diff --git a/packages/chameleon-mixins/package.json b/packages/chameleon-mixins/package.json index 9f6cb027d..cbbbb5a67 100644 --- a/packages/chameleon-mixins/package.json +++ b/packages/chameleon-mixins/package.json @@ -1,6 +1,6 @@ { "name": "chameleon-mixins", - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "description": "chameleon-mixins", "main": "index.js", "scripts": { @@ -12,7 +12,7 @@ "license": "Apache", "devDependencies": { "chai": "^4.2.0", - "chameleon-css-loader": "0.4.1-alpha.1", + "chameleon-css-loader": "1.0.4-alpha.1", "coveralls": "^2.11.9", "eslint": "^5.9.0", "gulp": "^3.9.1", diff --git a/packages/chameleon-template-parse/package.json b/packages/chameleon-template-parse/package.json index 9e53080b1..3ce0d1455 100644 --- a/packages/chameleon-template-parse/package.json +++ b/packages/chameleon-template-parse/package.json @@ -1,6 +1,6 @@ { "name": "chameleon-template-parse", - "version": "0.4.1-alpha.1", + "version": "1.0.4-alpha.1", "description": "", "main": "index.js", "scripts": { @@ -24,9 +24,9 @@ }, "devDependencies": { "chai": "^4.2.0", - "chameleon-css-loader": "0.4.1-alpha.1", - "chameleon-mixins": "0.4.1-alpha.1", - "chameleon-tool-utils": "0.4.1-alpha.1", + "chameleon-css-loader": "1.0.4-alpha.1", + "chameleon-mixins": "1.0.4-alpha.1", + "chameleon-tool-utils": "1.0.4-alpha.1", "clean-webpack-plugin": "^0.1.19", "coveralls": "^2.11.9", "eslint": "^5.9.0", diff --git a/packages/chameleon-template-parse/src/common/process-template.js b/packages/chameleon-template-parse/src/common/process-template.js index d652b9d30..ee8ceb3b0 100644 --- a/packages/chameleon-template-parse/src/common/process-template.js +++ b/packages/chameleon-template-parse/src/common/process-template.js @@ -441,7 +441,77 @@ exports.postParseUnicode = function(content) { let reg = /\\u/g; return unescape(content.replace(reg, '%u')); } -exports.postParseOriginTag = function(source) { +/** + * 校验 template 模板下如果有 cml 标签,则必须是第一层,且在第一层不能有其他标签; + */ +exports.checkTemplateChildren = function(path){ + let node = path.node; + let children = node.children || []; + let jsxElements = children.filter((child) => { + return t.isJSXElement(child) + }); + let hasCMLTag = jsxElements.some((ele) => { + return ele.openingElement.name.name === 'cml'; + }); + let hasOtherTag = jsxElements.some((ele) => { + return ele.openingElement.name.name !== 'cml'; + }); + return {hasCMLTag,hasOtherTag,jsxElements}; +} +/* +校验 cml 标签的父元素必须是 template; + +*/ +exports.checkCMLParent = function(path){ + let node = path.node; + if(node.openingElement.name.name === 'cml'){ + let parentNode = path.parentPath && path.parentPath.node; + if(parentNode && parentNode.openingElement && parentNode.openingElement.name.name !== 'template'){ + throw new Error('模板多态标签 cml 只允许在 template 标签的第一层'); + } + } +} +/** + * 获取 符合多态模板结构的 template 标签下对应平台的cml标签里的内容; + * @params:jsxElements template 节点下所有的 元素节点标签 + * @params:type 当前平台对应的 type,wx baidu alipay 等 + */ +exports.getCurrentPlatformCML = function(jsxElements,type){ + let currentCML = jsxElements.find((ele) => { + let typeAttr = ele.openingElement.attributes.find((attr) => { + return attr.name.name = 'type'; + }); + if(!typeAttr){ + throw new Error('cml 标签必须有 type 属性,标识用于哪端的代码') + } + let typeValue = typeAttr && typeAttr.value && typeAttr.value.value; + return typeValue.includes(type) + }); + //有对应平台的 type 找到之后直接return 这个节点 + if(currentCML){ + return currentCML; + } + let baseCML = jsxElements.find((ele) => { + let typeAttr = ele.openingElement.attributes.find((attr) => { + return attr.name.name = 'type'; + }); + if(!typeAttr){ + throw new Error('cml 标签必须有 type 属性,标识用于哪端的代码') + } + let typeValue = typeAttr && typeAttr.value && typeAttr.value.value; + return typeValue.includes('base') + }); + + if(!currentCML && baseCML){ + return baseCML; + } + +} +/* +@source: 源 template 文件 +@type:要编译的平台 +*/ +exports.postParseOriginTag = function(source,type) { let callbacks = ['preDisappearAnnotation', 'preParseGtLt', 'preParseBindAttr', 'preParseMustache', 'postParseLtGt']; source = exports.postParseUnicode(source); source = exports.preParseTemplateToSatisfactoryJSX(source, callbacks); @@ -452,6 +522,24 @@ exports.postParseOriginTag = function(source) { enter(path) { let node = path.node; if (t.isJSXElement(node) && (node.openingElement.name && typeof node.openingElement.name.name === 'string')) { + if(node.openingElement.name.name === 'template'){ + let {hasCMLTag,hasOtherTag,jsxElements} = exports.checkTemplateChildren(path); + if(hasCMLTag && hasOtherTag){ + throw new Error('多态模板里只允许在template标签下的一级标签是cml'); + } + if(hasCMLTag && !hasOtherTag){//符合多态模板的结构格式 + let currentPlatformCML = exports.getCurrentPlatformCML(jsxElements,type); + if(currentPlatformCML){ + currentPlatformCML.openingElement.name.name = 'view'; + // 这里要处理自闭和标签,没有closingElement,所以做个判断; + currentPlatformCML.closingElement && (node.closingElement.name.name = 'view'); + node.children = [currentPlatformCML]; + } + } + }; + if(node.openingElement.name.name === 'cml'){ + exports.checkCMLParent(path); + }; if (node.openingElement.name.name.indexOf('origin-') === 0) { let currentTag = node.openingElement.name.name; let targetTag = currentTag.replace('origin-', '') @@ -534,4 +622,4 @@ exports._deOperationGtLt = function(content) { exports.transformNativeEvent = function(source) { let reg = /__CML_NATIVE_EVENTS__/g; return source.replace(reg, '.native'); -} +} \ No newline at end of file diff --git a/packages/chameleon-template-parse/src/common/utils.js b/packages/chameleon-template-parse/src/common/utils.js index 4e17fd883..acce4df33 100644 --- a/packages/chameleon-template-parse/src/common/utils.js +++ b/packages/chameleon-template-parse/src/common/utils.js @@ -289,7 +289,8 @@ _.miniappVUEClassNodes = function (options) { _.getInlineStatementArgs = function(argsStr) { // argsStr:"1,'index'+1,$event,'item',index+1,item" const result = argsStr.split(',').reduce((result, current, index) => { - if (current === '$event') { + // if (current === '$event') { + if (/\s*?\$event\s*?/.test(current)) { result.push("'$event'"); } else { result.push(current) diff --git a/packages/chameleon-template-parse/src/compile-template-cml.js b/packages/chameleon-template-parse/src/compile-template-cml.js index f8589a5ca..86303fce7 100644 --- a/packages/chameleon-template-parse/src/compile-template-cml.js +++ b/packages/chameleon-template-parse/src/compile-template-cml.js @@ -50,7 +50,7 @@ exports.compileTemplateForCml = function (source, type, options) { source = compileBaiduTemplate(source, type, options).code; } // 后置处理,解析origin-tag ==> tag - source = processTemplate.postParseOriginTag(source) + source = processTemplate.postParseOriginTag(source,type) // 后置处理:解析_cml{str}lmc_ ==> {{str}} source = processTemplate.postParseMustache(source) // 后置处理:用于处理 \u ,便于解析unicode 中文 diff --git a/packages/chameleon-template-parse/src/compile-template-vue.js b/packages/chameleon-template-parse/src/compile-template-vue.js index fcaa985ff..9fcb08bd1 100644 --- a/packages/chameleon-template-parse/src/compile-template-vue.js +++ b/packages/chameleon-template-parse/src/compile-template-vue.js @@ -51,7 +51,7 @@ exports.compileTemplateForVue = function (source, type, options) { source = compileBaiduTemplate(source, type, options).code; } // 后置处理,解析origin-tag ==> tag - source = processTemplate.postParseOriginTag(source) + source = processTemplate.postParseOriginTag(source,type) // 后置处理:解析_cml{str}lmc_ ==> {{str}} source = processTemplate.postParseMustache(source) // 后置处理:用于处理 \u ,便于解析unicode 中文 diff --git a/packages/chameleon-template-parse/src/parser/parse-event.js b/packages/chameleon-template-parse/src/parser/parse-event.js index f200be829..b036b5faf 100644 --- a/packages/chameleon-template-parse/src/parser/parse-event.js +++ b/packages/chameleon-template-parse/src/parser/parse-event.js @@ -27,21 +27,22 @@ parseEvent.tap('web-weex', (args) => { let tagName = jsxElementNode.openingElement.name.name; let isOriginOrNative = utils.isOriginTagOrNativeComp(tagName, options); let isNotNativeComp = utils.isNotNativeComponent(tagName, options); - let isNativeComp = utils.isNativeComp(tagName, options); - let originEvents = ['click', 'touchstart', 'touchmove', 'touchend', 'touchcancel']; - if (type === 'web') { // cml标签或者cml组件 - // web端非第三方UI库的上的tap和click都处理成tap; - if (isNotNativeComp || tagName === 'component') { // cml组件上的tap和click都处理成 click.native - node.name.name === 'tap' && (node.name.name = 'click'); + let originEvents = ['tap', 'click', 'touchstart', 'touchmove', 'touchend', 'touchcancel']; + if (type === 'web') { + if (isNotNativeComp || tagName === 'component') { // cml组件上的tap和click都处理成tap.native click.native;这是为了和小程序端保持一致;对于第三方组件或者标签上的click或者tap则不再处理; originEvents.includes(node.name.name) && (node.name.name = `${node.name.name}__CML_NATIVE_EVENTS__`); - } else if (isNativeComp) { - // native组件不处理名字 - } else { // 普通标签都处理成tap - let isOriginTag = tagName.indexOf('origin-') === 0; - if (!isOriginTag) { // 如果是原生 origin- 开头的标签,那么click不要处理成tap - node.name.name === 'click' && (node.name.name = 'tap'); - } } + // if (isNotNativeComp || tagName === 'component') { // cml组件上的tap和click都处理成tap.native click.native;这是为了和小程序端保持一致; + // // node.name.name === 'tap' && (node.name.name = 'click'); + // originEvents.includes(node.name.name) && (node.name.name = `${node.name.name}__CML_NATIVE_EVENTS__`); + // } else if (isNativeComp) { // 对于引用的第三方组件则不处理 + // // native组件不处理名字 + // } else { // 普通标签都处理成tap + // let isOriginTag = tagName.indexOf('origin-') === 0; + // if (!isOriginTag) { // 如果是原生 origin- 开头的标签,那么click不要处理成tap + // // node.name.name === 'click' && (node.name.name = 'tap'); + // } + // } } if (type === 'weex') { // weex端 还是原来的逻辑 node.name.name === 'tap' && (node.name.name = 'click'); diff --git a/packages/chameleon-template-parse/test/common/process-template.test.js b/packages/chameleon-template-parse/test/common/process-template.test.js index 180d0bf7b..f19556ce2 100644 --- a/packages/chameleon-template-parse/test/common/process-template.test.js +++ b/packages/chameleon-template-parse/test/common/process-template.test.js @@ -114,6 +114,33 @@ describe('process-template', function() { expect(processTemplate.postParseOriginTag(``)).to.equal(`;`) }) }); + describe('postParseOriginTag', function() { + it('transform to ', function() { + expect(processTemplate.postParseOriginTag(``,'alipay')).to.equal(`