提交 a48d508d 编写于 作者: J JiM-W

完成cml和vue语法严格校验

上级 4b2cdf40
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
"chai": "^4.2.0", "chai": "^4.2.0",
"chameleon-css-loader": "0.1.0-alpha.2", "chameleon-css-loader": "0.1.0-alpha.2",
"chameleon-mixins": "0.1.0-alpha.2", "chameleon-mixins": "0.1.0-alpha.2",
"chameleon-tool-utils": "0.0.29",
"clean-webpack-plugin": "^0.1.19", "clean-webpack-plugin": "^0.1.19",
"coveralls": "^2.11.9", "coveralls": "^2.11.9",
"eslint": "^5.9.0", "eslint": "^5.9.0",
......
...@@ -411,18 +411,26 @@ exports.preCheckTemplateSyntax = function(source, type, options) { ...@@ -411,18 +411,26 @@ exports.preCheckTemplateSyntax = function(source, type, options) {
errorInfo = exports.preCheckTemplateSyntaxForVue(source, type, options) errorInfo = exports.preCheckTemplateSyntaxForVue(source, type, options)
} catch (e) { } catch (e) {
console.log('catch', e) errorInfo = 'vue syntax error '
}
}
if (lang === 'cml') {
try {
errorInfo = exports.preCheckTemplateSyntaxForCml(source, type, options)
} catch (e) {
errorInfo = 'cml syntax error '
} }
} }
return errorInfo return errorInfo
} }
exports.preCheckTemplateSyntaxForVue = function(source, type, options) { exports.preCheckTemplateSyntaxForVue = function(source, type, options) {
debugger;
let {lang} = options; let {lang} = options;
if (lang === 'vue') { if (lang === 'vue') {
let callbacks = ['preDisappearAnnotation', 'preParseEventSyntax', 'preParseGtLt', 'preParseBindAttr', 'preParseMustache', 'postParseLtGt'] let callbacks = ['preDisappearAnnotation', 'preParseEventSyntax', 'preParseGtLt', 'preParseBindAttr', 'preParseMustache', 'postParseLtGt']
source = exports.preParseTemplateToSatisfactoryJSX(source, callbacks); source = exports.preParseTemplateToSatisfactoryJSX(source, callbacks);
let errorInfo = ''; let errorInfo = '';
let directiveError, twoWayBindError, eventBindingError;
let disabledPropsInVueSyntax = ['c-if', 'c-else-if', 'c-else', 'c-show', 'c-text', 'c-model', 'c-animation', 'c-for'] let disabledPropsInVueSyntax = ['c-if', 'c-else-if', 'c-else', 'c-show', 'c-text', 'c-model', 'c-animation', 'c-for']
const ast = babylon.parse(source, { const ast = babylon.parse(source, {
plugins: ['jsx'] plugins: ['jsx']
...@@ -430,14 +438,49 @@ exports.preCheckTemplateSyntaxForVue = function(source, type, options) { ...@@ -430,14 +438,49 @@ exports.preCheckTemplateSyntaxForVue = function(source, type, options) {
traverse(ast, { traverse(ast, {
enter(path) { enter(path) {
let node = path.node; let node = path.node;
if (t.isJSXAttribute(node) && disabledPropsInVueSyntax.includes(node.name.name)) { if (!directiveError && t.isJSXAttribute(node) && disabledPropsInVueSyntax.includes(node.name.name)) {
errorInfo += `vue 语法下不能使用 ${node.name.name}` errorInfo += `vue 语法下不能使用 ${node.name.name};`
directiveError = true
}
if (!twoWayBindError && t.isJSXAttribute(node) && utils.isMustacheReactive(node.value.value)) {
errorInfo += 'vue 语法下不能用 id={{value}},请使用 v-bind:id="value" 或者 :id="value" 进行响应式值的绑定;'
twoWayBindError = true;
}
if (!eventBindingError && t.isJSXNamespacedName(node.name) && node.name.namespace.name === 'c-bind') {
errorInfo += 'vue 语法下不能用 c-bind 进行事件绑定,请使用 @ 或者v-on进行事件绑定;'
eventBindingError = true
}
}
});
return errorInfo
}
}
exports.preCheckTemplateSyntaxForCml = function(source, type, options) {
let {lang} = options;
if (lang === 'cml') {
let callbacks = ['preDisappearAnnotation', 'preParseEventSyntax', 'preParseGtLt', 'preParseBindAttr', 'preParseMustache', 'postParseLtGt']
source = exports.preParseTemplateToSatisfactoryJSX(source, callbacks);
let errorInfo = '';
let directiveError, twoWayBindError, eventBindingError;
let disabledPropsInVueSyntax = ['v-if', 'v-else-if', 'v-else', 'v-show', 'v-text', 'v-model', 'v-animation', 'v-for']
const ast = babylon.parse(source, {
plugins: ['jsx']
})
traverse(ast, {
enter(path) {
let node = path.node;
if (!directiveError && t.isJSXAttribute(node) && disabledPropsInVueSyntax.includes(node.name.name)) {
errorInfo += `cml 语法下不能使用 ${node.name.name};`
directiveError = true;
} }
if (t.isJSXAttribute(node) && utils.isMustacheReactive(node.value.value)) { if (!twoWayBindError && t.isJSXNamespacedName(node.name) && node.name.namespace.name === 'v-bind') {
errorInfo += 'vue 语法下属性值不能用 {{}}' errorInfo += 'cml 语法下不能用 :id="value" 或者 v-bind:id="value"进行响应式的值得双向绑定,请使用 id={{value}} ;'
twoWayBindError = true;
} }
if (t.isJSXNamespacedName(node.name) && node.name.namespace.name === 'c-bind') { if (!eventBindingError && t.isJSXNamespacedName(node.name) && node.name.namespace.name === 'v-on') {
errorInfo += 'vue 语法下事件绑定不能用 c-bind,请使用 @ 或者v-on进行事件绑定' errorInfo += 'cml 语法下不能用 @ 或者 v-on 进行事件绑定,请使用 c-bind进行事件绑定;'
eventBindingError = true;
} }
} }
}); });
......
...@@ -7,10 +7,12 @@ const parseTemplate = require('./parser/index.js'); ...@@ -7,10 +7,12 @@ const parseTemplate = require('./parser/index.js');
// 对于模板的预处理 - 后置处理 - 等正则的一些替换; // 对于模板的预处理 - 后置处理 - 等正则的一些替换;
const processTemplate = require('./common/process-template.js') const processTemplate = require('./common/process-template.js')
// 目前事件的处理有两处:第一,c-bind,第二c-model,两者互相不影响;借鉴于此,需要新增处理事件支持传参的形式,而此时就需要处理c-bind; // 目前事件的处理有两处:第一,c-bind,第二c-model,两者互相不影响;借鉴于此,需要新增处理事件支持传参的形式,而此时就需要处理c-bind;
const cliUtils = require('chameleon-tool-utils');
exports.compileTemplateForCml = function (source, type, options) { exports.compileTemplateForCml = function (source, type, options) {
let errorInfo = processTemplate.preCheckTemplateSyntax(source, type, options) let errorInfo = processTemplate.preCheckTemplateSyntax(source, type, options)
if (errorInfo) { if (errorInfo) {
throw new Error(errorInfo) // throw new Error(`${errorInfo} in ${options.filePath}`)
cliUtils.log.warn(`${errorInfo} in ${options.filePath}`);
} }
// source // source
// 预处理html模板中的注释,jsx不支持,这个需要优先处理,防止解析 < > 的时候出现问题; // 预处理html模板中的注释,jsx不支持,这个需要优先处理,防止解析 < > 的时候出现问题;
......
...@@ -7,10 +7,12 @@ const parseTemplate = require('./parser/index.js'); ...@@ -7,10 +7,12 @@ const parseTemplate = require('./parser/index.js');
// 对于模板的预处理 - 后置处理 - 等正则的一些替换; // 对于模板的预处理 - 后置处理 - 等正则的一些替换;
const processTemplate = require('./common/process-template.js') const processTemplate = require('./common/process-template.js')
// 目前事件的处理有两处:第一,c-bind,第二c-model,两者互相不影响;借鉴于此,需要新增处理事件支持传参的形式,而此时就需要处理c-bind; // 目前事件的处理有两处:第一,c-bind,第二c-model,两者互相不影响;借鉴于此,需要新增处理事件支持传参的形式,而此时就需要处理c-bind;
const cliUtils = require('chameleon-tool-utils');
exports.compileTemplateForVue = function (source, type, options) { exports.compileTemplateForVue = function (source, type, options) {
let errorInfo = processTemplate.preCheckTemplateSyntax(source, type, options) let errorInfo = processTemplate.preCheckTemplateSyntax(source, type, options)
if (errorInfo) { if (errorInfo) {
throw new Error(errorInfo) // throw new Error(`${errorInfo} in ${options.filePath}`)
cliUtils.log.warn(`${errorInfo} in ${options.filePath}`);
} }
// source // source
// 预处理html模板中的注释,将其删除;这个需要优先处理,防止解析 < > 的时候出现问题; // 预处理html模板中的注释,将其删除;这个需要优先处理,防止解析 < > 的时候出现问题;
......
...@@ -132,7 +132,7 @@ parseClass.tap('weex-vue', (args) => { ...@@ -132,7 +132,7 @@ parseClass.tap('weex-vue', (args) => {
}) })
parseClass.tap('wx-alipay-baidu-vue', (args) => { parseClass.tap('wx-alipay-baidu-vue', (args) => {
let { node, type, options: {lang} } = args; let { node, type, options: {lang, filePath} } = args;
if (lang === 'vue' && (type === 'wx' || type === 'alipay' || type === 'baidu')) { if (lang === 'vue' && (type === 'wx' || type === 'alipay' || type === 'baidu')) {
let tagName = node.openingElement.name.name; let tagName = node.openingElement.name.name;
let attributes = node.openingElement.attributes; let attributes = node.openingElement.attributes;
...@@ -140,7 +140,11 @@ parseClass.tap('wx-alipay-baidu-vue', (args) => { ...@@ -140,7 +140,11 @@ parseClass.tap('wx-alipay-baidu-vue', (args) => {
attr.name.name === 'class' || attr.name.name.name === 'class' attr.name.name === 'class' || attr.name.name.name === 'class'
); );
let extraClass = ` cml-base cml-${tagName}`; let extraClass = ` cml-base cml-${tagName}`;
if (type === 'alipay') {
let num = 32;
let randomClassName = fnv.hash(filePath, num).str();
extraClass = `${extraClass} cml-${randomClassName}`
}
utils.handleVUEClassNodes({classNodes, attributes, extraClass, lang, type: 'miniapp'}) utils.handleVUEClassNodes({classNodes, attributes, extraClass, lang, type: 'miniapp'})
} }
......
const compileTemplate = require('../src/index.js'); const compileTemplate = require('../src/index.js');
const source = `<view> const source = `<scroller height="{{-1}}">
<cube-button @tap="handleClick"></cube-button> <view v-if="false"> v-if</view>
<thirdComp2 c-bind:tap="handleClick"></thirdComp2> <view > v-if</view>
</view> ` </scroller> `
// <view><text :class="{{true? 'bg-green':''}}" >fafafa</text></view> // <view><text :class="{{true? 'bg-green':''}}" >fafafa</text></view>
// <view><text :class="true? 'bg-green':''" >fafafa</text></view> // <view><text :class="true? 'bg-green':''" >fafafa</text></view>
// //
// let result = compileTemplate(source,'web'); // let result = compileTemplate(source,'web');
let options = {lang: 'vue', let options = {lang: 'cml',
filePath: '/Users/didi/components',
buildInComponents: {button: "cml-buildin-button"}, buildInComponents: {button: "cml-buildin-button"},
cmss: { cmss: {
rem: true, rem: true,
...@@ -36,11 +37,11 @@ let options = {lang: 'vue', ...@@ -36,11 +37,11 @@ let options = {lang: 'vue',
}; };
console.log('before-compile', source); console.log('before-compile', source);
let result_web = compileTemplate(source, 'web', options); let result_web = compileTemplate(source, 'web', options);
// let result_wx = compileTemplate(source, 'wx', options); let result_wx = compileTemplate(source, 'wx', options);
// let result_baidu = compileTemplate(source, 'wx', options); // let result_baidu = compileTemplate(source, 'wx', options);
// let result_alipay = compileTemplate(source, 'alipay', options); // let result_alipay = compileTemplate(source, 'alipay', options);
// let result_alipay = compileTemplate(source,'alipay',{lang:'cml'}); // let result_alipay = compileTemplate(source,'alipay',{lang:'cml'});
console.log('result_web', result_web) console.log('result_web', result_web)
// console.log('result_wx', result_wx) console.log('result_wx', result_wx)
// console.log('result_alipay', result_alipay) // console.log('result_alipay', result_alipay)
// console.log('result_baidu', result_baidu) // console.log('result_baidu', result_baidu)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册