低代码本身基本上不可能成为“一个标准”,每家公司做法都不一样,唯一的标准,只有“代码”本身!
是否具有通用的代码生成能力关系到很多底层问题,所有低代码平台都无法回避,甚至讳莫如深。
低代码平台最让程序员反感的就是“证明我以前工作是没有意义的,还要让我买单!”,这里面最核心的问题,就是代码问题!如果低代码平台成为“代码快速生成器”,成为程序员的助手,应该情况就会好很多,我们来细致分析一下这个敏感的话题。
低代码平台能生成代码吗!?
注意,这里生成的代码是“所开发应用的独立代码”,这个代码是可以“脱离”平台,独立运行的那种。
这个可以提供程序员或使用的企业——最基础的“安全感”!
如果没有代码生成,代表以后只能在这个平台上开发,开发出来的应用只能在这个平台运行,即“开发和运行环境锁定”!
主要是低代码平台有如此之多,自身标准又不统一,你在一个平台开发的应用并不能在其它平台打开或运行,这就很尴尬了。如果这个平台功能受限怎么办?应用性能不行怎么办?平台不运营了怎么办?
iVX、appgyver等就可以生成代码,Wix、WordPress、odoo等也可以。
当然代码生成也包含很多个等级,例如:
(1)是前后台代码都能生成?还是只能生成后台代码?或只能生成前端代码?——最大多数低代码平台如果生,也是生一种。
(2)能否生成数据库的代码?自动生成SQL?
(3)最好生成的后台代码能后和运行时资源解耦,能接云计算尽量接云计算?
生成代码能力方面呢,iVX应该是最强的,在以上这些中。
只有能够首先生成代码,才有后面的然后...
平台生成代码可以和程序员手写代码基本“无差别”吗!?
什么叫无差别呢?
生成代码易用性,可以和现有常见开发环境和代码资源整合
生成的代码最好采用常见的流行框架,例如前端VUE或者react等,后台生成JAVA或Node语言。我并不是觉得JQ或PHP不好,而是现在确实会比较小众一些,这个不属于我们重点讨论的话题。同时,最好能支持mysql、ES、redis、MQ等多类型的数据库或后台常见产品。如果能够和现有的代码开发流程也能整合那就更好了!例如Git等代码管理工具。
生成代码可读性,程序员可以直接复用或二次开发(要做到这一点,基本上就是低代码行业的天花板了)
大家常常提到程序员“不喜欢”“至少是不支持”低代码,可是为什么呢?深层次原因还是程序员将“低代码”当成了自己饭碗的“竞争者”,而并非是“收入”和“效率”提升的贡献者!而在一个企业中,技术选型谁说了算?当然还是“程序员”,这就形成了一个悖论。“低代码平台想抢程序员的饭碗,还要程序员买单!”。
虽然也有程序员不喜欢ChatGPT或代码补全工具,但是似乎要温柔很多,而且更多的程序员还是持赞成态度的。
如果根据这个特征,反思一下低代码生态,那就很清楚了,低代码必须要得到程序员的认可才有出路(那么就一次全部毁灭,直接AI生成完整应用,短时间内还很难)。
生成代码涉及到很多“尖端”技术,例如编译器/解释器的开发,AST的开发等等,因此要想生成代码本来就不容易,生成具有可读性的代码就更难了。
iVX 已经能够自动生成可读代码(我们将在文章最后放一点生成代码片段...)。
生成代码运行效率还要高...
不是很容易证明谁比谁写的代码更好?这是一个比较复杂的问题。但是基本上可以从几个点来进行判断:
(1)生成应用打开的速度?运行时卡不卡顿?
(2)写一个类似的程序,跑一下,打开控制台看看有什么区别?另外,就是看看加载文件的大小?
(3)后台可以压测一下,看看高并发的情况。对于这个问题,我认为最好是把“计算”、“存储”、“安全”、“带宽”等都交给云计算平台来处理和控制。(这是iVX的做法,也就是“只帮用户生成程序本身,和后台运行时需要资源解耦”)
调试和运行代码和以前方式“无差别”
iVX可以生成前端、后台和数据库代码。以生成前端代码为例,可以直接保存成.vue的文件,直接在现有VScode等流行的代码IDE中进行动态调试,任意增加代码,并通过编译。
甚至可以将iVX的前端代码编译成vue和react的component在现有的前端代码中进行调用。
下面是导出代码范例,就是一个简单页面,但是生成格式应该很多前端同学都是可以看和可以改的。
通过这个页面生成:
<template>
<ivx-stage
_id="c38r3wfa3j50000w1az0"
_name="前台"
width="100%"
height="100%"
backgroundColor="#FFFFFF"
bgImage="096adb43f8973934dbcd01eb89b4e0ef_52171_1440_800.png"
:fonts="{}"
:pageCustomIdList="[null]"
>
<ivx-system _id="c38r3wfa3j50000w1ayg" _name="应用系统" />
<ivx-page
_id="c38s06ra3j50000w1b30"
_name="资产负债表格"
horizon="center"
cut="auto"
:paddingLeft="0"
:paddingTop="30"
@curPageBeforeShow="c38s06ra3j50000w1b30_curPageBeforeShow"
>
<data-if
_id="c39a37ca3j50000dmvkg"
_name="摘要"
:value="$var.c39b6a9a3j50000dmw50.value == '摘要'"
>
<ivx-layoutcol
_id="c38sakaa3j50000w1bgg"
_name="摘要"
shadowType="box"
:horizonStretch="false"
width="700px"
largeSize="700px"
mediumSize="700px"
smallSize="700px"
padSize="700px"
xsmallSize="700px"
bgColor="rgba(255,255,255,0)"
bgImage=""
:visible="true"
>
<ivx-container-flex
_id="c398q6wa3j50000dmv5g"
_name="绝对定位容器1"
shadowType="box"
bgImage="29d57ec4e3071bd88a1731296702caeb_154861_677_139.png"
bgColor="rgba(56,153,236,0)"
>
<ivx-text
_id="c38swr3a3j50000w1bh0"
_name="资产负债表"
shadowType="box"
value="资产负债表"
:allowSelect="true"
:fontSize="48"
fontColor="#FFFFFF"
:textStyle="4"
fontWeight="bold"
fontStyle=""
textDecoration=""
:x="0"
:y="30"
:rotate="0"
/>
<ivx-text
_id="c38tpt3a3j50000w1bj0"
_name="公司名称"
shadowType="box"
value="公司名称"
:allowSelect="true"
:fontSize="20"
fontColor="#C6D9F0"
:textStyle="4"
fontWeight="bold"
fontStyle=""
textDecoration=""
:x="0"
:y="100"
:rotate="0"
/>
</ivx-container-flex>
<ivx-layoutrow
_id="c39dphaa3j50000dn1vg"
_name="年份"
shadowType="box"
:marginTop="10"
horizon="right"
:verticalStretch="false"
height="auto"
bgColor="rgba(204,204,204,0)"
:marginBottom="0"
>
<ivx-text
_id="c39dphaa3j50000dn1w0"
_name="2020年"
shadowType="box"
value="2020年"
:allowSelect="true"
width="150px"
justifyContent="flex-end"
:marginRight="0"
:paddingRight="20"
fontColor="#616263"
:fontSize="16"
/>
<ivx-text
_id="c39dphaa3j50000dn1wg"
_name="2021年"
shadowType="box"
value="2021年"
:allowSelect="true"
width="150px"
justifyContent="flex-end"
:paddingRight="20"
fontColor="#616263"
:fontSize="16"
/>
</ivx-layoutrow>
<ivx-divider
_id="c38tr99a3j50000w1bm0"
_name="分割线1"
:marginTop="10"
:marginBottom="10"
borderColor="#DBDFEA"
/>
<ivx-layoutcol
_id="c398t08a3j50000dmv6g"
_name="余额汇总表"
shadowType="box"
bgColor="rgba(177,175,175,0)"
:verticalStretch="false"
height="auto"
>
<ivx-text
_id="c398vk6a3j50000dmv7g"
_name="余额汇总"
shadowType="box"
value="余额汇总"
:allowSelect="true"
fontColor="#FFFFFF"
:fontSize="20"
:textStyle="4"
fontWeight="bold"
fontStyle=""
textDecoration=""
width="100%"
height="30px"
alignItems="center"
:paddingLeft="20"
borderRadius="0px"
bgColor="#1F497D"
/>
<ivx-layoutrow
_id="c398x44a3j50000dmv80"
_name="总资产"
shadowType="box"
:verticalStretch="false"
height="30px"
bgColor="rgba(204,204,204,0)"
:borderWidth="1"
borderColor="#1F497D"
:borderPos="8"
>
<ivx-text
_id="c398xnpa3j50000dmv8g"
_name="总资产"
shadowType="box"
value="总资产"
:allowSelect="true"
width="399px"
height="30px"
fontColor="#616263"
:fontSize="16"
alignItems="center"
:paddingLeft="19"
borderColor="#1F497D"
:borderWidth="1"
:borderPos="6"
/>
<ivx-text
_id="c398y9ha3j50000dmv90"
_name="总资产"
:value="'¥' + $var.c39e14ca3j50000dn45g.value.toFixed(2)"
shadowType="box"
:allowSelect="true"
width="150px"
height="30px"
fontColor="#616263"
:fontSize="16"
alignItems="center"
:paddingLeft="0"
borderColor="#1F497D"
:borderWidth="1"
:borderPos="6"
:paddingRight="20"
justifyContent="flex-end"
/>
<ivx-text
_id="c398ycha3j50000dmva0"
_name="总资产"
:value="'¥' + $var.c39e14ca3j50000dn460.value.toFixed(2)"
shadowType="box"
:allowSelect="true"
width="150px"
height="30px"
fontColor="#616263"
:fontSize="16"
alignItems="center"
:paddingLeft="0"
borderColor="#1F497D"
:borderWidth="1"
:borderPos="6"
justifyContent="flex-end"
:paddingRight="20"
/>
</ivx-layoutrow>
<ivx-layoutrow
_id="c398z0ca3j50000dmvag"
_name="总负债和所有者权益"
shadowType="box"
:verticalStretch="false"
height="30px"
bgColor="rgba(204,204,204,0)"
:borderWidth="1"
borderColor="#1F497D"
:borderPos="8"
>
<ivx-text
_id="c398z0ca3j50000dmvb0"
_name="总负债和所有者权益"
shadowType="box"
value="总负债和所有者权益"
:allowSelect="true"
width="399px"
height="30px"
fontColor="#616263"
:fontSize="16"
alignItems="center"
:paddingLeft="19"
borderColor="#1F497D"
:borderWidth="1"
:borderPos="6"
/>
<ivx-text
_id="c398z0ca3j50000dmvbg"
_name="总资产"
:value="'¥' + $var.c39e14wa3j50000dn46g.value.toFixed(2)"
shadowType="box"
:allowSelect="true"
width="150px"
height="30px"
fontColor="#616263"
:fontSize="16"
alignItems="center"
:paddingLeft="0"
borderColor="#1F497D"
:borderWidth="1"
:borderPos="6"
:paddingRight="20"
justifyContent="flex-end"
/>
<ivx-text
_id="c398z0ca3j50000dmvc0"
_name="总资产"
:value="'¥' + $var.c39e14wa3j50000dn470.value.toFixed(2)"
shadowType="box"
:allowSelect="true"
width="150px"
height="30px"
fontColor="#616263"
:fontSize="16"
alignItems="center"
:paddingLeft="0"
borderColor="#1F497D"
:borderWidth="1"
:borderPos="6"
justifyContent="flex-end"
:paddingRight="20"
/>
</ivx-layoutrow>
<ivx-layoutrow
_id="c398z74a3j50000dmvcg"
_name="余额"
shadowType="box"
:verticalStretch="false"
height="30px"
bgColor="#C5D9F1"
:borderWidth="1"
borderColor="#1F497D"
:borderPos="8"
>
<ivx-text
_id="c398z74a3j50000dmvd0"
_name="余额"
shadowType="box"
value="余额"
:allowSelect="true"
width="399px"
height="30px"
fontColor="#616263"
:fontSize="16"
alignItems="center"
:paddingLeft="19"
borderColor="#1F497D"
:borderWidth="1"
:borderPos="6"
/>
<ivx-text
_id="c398z74a3j50000dmvdg"
_name="总资产"
:value="
'¥' +
(
$var.c39e14ca3j50000dn45g.value -
$var.c39e14wa3j50000dn46g.value
).toFixed(2)
"
shadowType="box"
:allowSelect="true"
width="150px"
height="30px"
fontColor="#616263"
:fontSize="16"
alignItems="center"
:paddingLeft="0"
borderColor="#1F497D"
:borderWidth="1"
:borderPos="6"
:paddingRight="20"
justifyContent="flex-end"
/>
<ivx-text
_id="c398z74a3j50000dmve0"
_name="总资产"
:value="
'¥' +
(
$var.c39e14ca3j50000dn460.value -
$var.c39e14wa3j50000dn470.value
).toFixed(2)
"
shadowType="box"
:allowSelect="true"
width="150px"
height="30px"
fontColor="#616263"
:fontSize="16"
alignItems="center"
:paddingLeft="0"
borderColor="#1F497D"
:borderWidth="1"
:borderPos="6"
justifyContent="flex-end"
:paddingRight="20"
/>
</ivx-layoutrow>
</ivx-layoutcol>
<ivx-container-flex
_id="c398znpa3j50000dmveg"
_name="资产"
shadowType="box"
width="100%"
:marginTop="30"
height="300px"
bgColor="rgba(56,153,236,0)"
borderColor="#8EB4E3"
:borderWidth="1"
overflow="visible"
>
<ivx-barChart
_id="c39906ra3j50000dmvf0"
_name="柱形折线图1"
:dataArr="$var.c39e3vfa3j50000dn4wg.value"
shadowType="box"
:colorArrHeaders="[
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
]"
:dataArrHeaders="[
{ type: 'string' },
{ type: 'string' },
{ type: 'number' },
]"
:colorArr="[
'#C23531',
'#2F4554',
'#61A0A8',
'#D48265',
'#91C7AE',
'#749F83',
'#CA8622',
'#BDA29A',
'#6E7074',
'#546570',
'#C4CCD3',
]"
:yAxisTypes="[['', 12, 12, 'top', false]]"
:yAxisHeaders="[
{ type: 'string' },
{ type: 'number' },
{ type: 'number' },
{
type: 'select',
options: ['none', 'left', 'right'],
optionLocales: {
none: { en: 'None', zh: '不显示' },
left: { en: 'Left', zh: '左侧' },
right: { en: 'Right', zh: '右侧' },
},
},
{ type: 'boolean' },
]"
:seriesTypesAndColors="[
['', '#C23531', 1],
['', '#2F4554', 1],
['', '#61A0A8', 1],
['', '#D48265', 1],
['', '#91C7AE', 1],
['', '#749F83', 1],
['', '#CA8622', 1],
['', '#BDA29A', 1],
['', '#6E7074', 1],
['', '#546570', 1],
['', '#C4CCD3', 1],
]"
:seriesColor="[
'#8EB4E3',
'#1f497d',
'#61A0A8',
'#D48265',
'#91C7AE',
'#749F83',
'#CA8622',
'#BDA29A',
'#6E7074',
'#546570',
'#C4CCD3',
]"
:seriesType="[
'bar',
'bar',
'bar',
'bar',
'bar',
'bar',
'bar',
'bar',
'bar',
'bar',
'bar',
]"
:seriesShowLabel="[
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
]"
:seriesTypesAndColorsHeaders="[
{ type: 'number' },
{ type: 'color' },
{ type: 'number' },
]"
:seriesColorHeaders="[
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
{ type: 'color' },
]"
:seriesTypeHeaders="[
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
{
type: 'sel',
options: ['bar', 'line'],
optionLocales: {
bar: { zh: 'Bar', en: 'Bar' },
line: { zh: 'Line', en: 'Line' },
},
},
]"
:seriesShowLabelHeaders="[
{ type: 'boolean' },
{ type: 'boolean' },
{ type: 'boolean' },
{ type: 'boolean' },
{ type: 'boolean' },
{ type: 'boolean' },
{ type: 'boolean' },
{ type: 'boolean' },
{ type: 'boolean' },
{ type: 'boolean' },
{ type: 'boolean' },
]"
:width="620"
:height="340"
:x="80"
:y="1"
:horizontal="true"
showLegend="right"
:overlap="false"
:showXAxisSplitLine="false"
:showYAxisSplitLine="true"
:xAxisFontSize="12"
:useFixedBarWidth="false"
:showDataZoom="false"
:legendFontSize="12"
:stack="false"
:percent="false"
xAxisName=""
:fontSizeX="12"
:barCategoryGap="0.3"
:colorByData="false"
yAxisMax=""
yAxisMin=""
:rotate="0"
:barGap="0"
:seriesTypesStyle="[
['#8EB4E3', 'bar', false, '', '#C23531', 1],
['#1f497d', 'bar', false, '', '#2F4554', 1],
['#61A0A8', 'bar', false, '', '#61A0A8', 1],
['#D48265', 'bar', false, '', '#D48265', 1],
['#91C7AE', 'bar', false, '', '#91C7AE', 1],
['#749F83', 'bar', false, '', '#749F83', 1],
['#CA8622', 'bar', false, '', '#CA8622', 1],
['#BDA29A', 'bar', false, '', '#BDA29A', 1],
['#6E7074', 'bar', false, '', '#6E7074', 1],
['#546570', 'bar', false, '', '#546570', 1],
['#C4CCD3', 'bar', false, '', '#C4CCD3', 1],
]"
/>
<ivx-text
_id="c3991rqa3j50000dmvfg"
_name="资产"
shadowType="box"
value="资产"
:allowSelect="true"
width=""
height=""
:x="16"
:y="16"
fontColor="#2C2D2E"
:fontSize="16"
:textStyle="4"
fontWeight="bold"
fontStyle=""
textDecoration=""
/>
<ivx-layoutcol
_id="c39efaxa3j50000dn7ag"
_name="y轴数据"
shadowType="box"
:width="135"
:height="220"
:x&#