@cloudbase/lowcode-builder 1.4.5 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,6 +17,7 @@ const common_2 = require("../../utils/common");
17
17
  const postProcess_1 = require("../../utils/postProcess");
18
18
  const cals_1 = require("@cloudbase/cals");
19
19
  const net_1 = require("../util/net");
20
+ const config_1 = require("../config");
20
21
  const pkg = require('../../../package.json');
21
22
  async function buildWedaConfig({ output, domain = undefined, isPrivateMode = undefined, endpointType = undefined, buildTypeList = [common_1.BuildType.WEB], }) {
22
23
  if ((0, common_1.buildAsWebByBuildType)(buildTypeList)) {
@@ -86,24 +87,52 @@ async function buildWedaApp({ cals, subAppCalsList = [], dependencies = [], appK
86
87
  console.log('生成路径', appBuildDir);
87
88
  try {
88
89
  const startTime = Date.now();
90
+ function processRepeaterDisplay(cals) {
91
+ cals.items = (cals.items || []).map((page) => {
92
+ return JSON.parse(JSON.stringify(page, (key, value) => {
93
+ if (value === null || value === void 0 ? void 0 : value.component) {
94
+ const component = value;
95
+ if ((value === null || value === void 0 ? void 0 : value.component) &&
96
+ `${component.module}:${component.component}` === `${config_1.REPEATER.MODULE_NAME}:${config_1.REPEATER.REPEATER_NAME}`) {
97
+ // 给 Repeater 组件加一层虚拟项组件,在虚拟项组件上挂 for 循环
98
+ const { items = [] } = component;
99
+ component.items = items.map((item) => {
100
+ if (component.directives[':display'] !== undefined && component.directives[':display'] !== 'true') {
101
+ if (!item.directives) {
102
+ item.directives = {};
103
+ }
104
+ const current = item.directives[':display'] || 'true';
105
+ item.directives[':display'] = `(\n${component.directives[':display']}\n) && (\n${current}\n)`;
106
+ }
107
+ return item;
108
+ });
109
+ }
110
+ }
111
+ return value;
112
+ }));
113
+ });
114
+ return cals;
115
+ }
89
116
  if (buildTypeList.includes(common_1.BuildType.MP)) {
90
- const mainAppSerializeData = (0, common_2.processCals2WeappsData)(cals, dependencies);
91
- const subAppSerializeDataList = (subAppCalsList === null || subAppCalsList === void 0 ? void 0 : subAppCalsList.map((item) => (0, common_2.processCals2WeappsData)(item, dependencies))) || [];
117
+ const mainAppSerializeData = (0, common_2.processCals2WeappsData)(processRepeaterDisplay(cals), dependencies);
118
+ const subAppSerializeDataList = (subAppCalsList === null || subAppCalsList === void 0 ? void 0 : subAppCalsList.map((item) => (0, common_2.processCals2WeappsData)(processRepeaterDisplay(item), dependencies))) || [];
92
119
  const apps = [mainAppSerializeData, ...subAppSerializeDataList];
93
120
  if (isBrowserMpBuilder) {
94
121
  // 尽早下载物料
95
122
  await (0, net_1.downloadBrowserMaterial)(output === null || output === void 0 ? void 0 : output.path);
96
123
  }
124
+ const { enablePageRoot } = (0, cals_1.parseVersion)(cals === null || cals === void 0 ? void 0 : cals.schemaVersion, dependencies);
97
125
  const mpBuildContext = {
98
126
  ...buildContext,
99
127
  projDir: (output === null || output === void 0 ? void 0 : output.path) || path_1.default.join(appBuildDir, 'mp'),
100
128
  mainAppData: mainAppSerializeData,
101
129
  processCssUnit: ([cals, ...subAppCalsList].find((cals) => {
102
- const FEATURE_MAP = (0, cals_1.parseVersion)(cals.schemaVersion);
130
+ const FEATURE_MAP = (0, cals_1.parseVersion)(cals.schemaVersion, dependencies);
103
131
  return !FEATURE_MAP.defaultDynamicCssUnit;
104
132
  })
105
133
  ? 'px'
106
134
  : 'rpx'),
135
+ enablePageRoot,
107
136
  };
108
137
  const result = await (0, index_1.generateWxMp)({
109
138
  weapps: apps,
@@ -44,6 +44,7 @@ const common_2 = require("../../utils/common");
44
44
  const config_1 = require("../config");
45
45
  const fs_extra_1 = __importDefault(require("fs-extra"));
46
46
  const junk = __importStar(require("../util/junk"));
47
+ const url_1 = require("url");
47
48
  async function buildH5App({ buildContext, i18nConfig, extraData, cals, buildTypeList = [common_1.BuildType.WEB], subAppCalsList, mode, devTool, runtime = types_1.RUNTIME.NONE, deployMode = types_1.DEPLOY_MODE.PREVIEW, ignoreInstall = false, cdnEndpoints, }) {
48
49
  var _a, _b, _c;
49
50
  const { projDir: buildDir, domain, materialLibs: dependencies, appId: appKey, isPrivateMode } = buildContext;
@@ -165,8 +166,18 @@ async function buildH5App({ buildContext, i18nConfig, extraData, cals, buildType
165
166
  .readdirSync(path_1.default.resolve(h5BuildDir, webpack_2.OUTPUT_DIR))
166
167
  .filter((file) => junk.not(file) && file !== MAINIFAST_FILENAME)
167
168
  .map((file) => {
168
- return path_1.default.posix.join(publicPath, file);
169
- });
169
+ if (/LICENSE\.txt$/.test(file) || /\.map$/.test(file)) {
170
+ return '';
171
+ }
172
+ try {
173
+ const url = new url_1.URL(publicPath);
174
+ return `${url.origin}${path_1.default.posix.join(url.pathname, file)}`;
175
+ }
176
+ catch (e) {
177
+ return path_1.default.posix.join(publicPath, file);
178
+ }
179
+ })
180
+ .filter((item) => !!item);
170
181
  // 普通 web 模式,且非hash模式,根据页面生成多份入口
171
182
  if (!((_c = cals.extra) === null || _c === void 0 ? void 0 : _c.historyType) || cals.extra.historyType === types_1.HISTORY_TYPE.BROWSER) {
172
183
  preHeatUrls.push(path_1.default.posix.join(basename));
@@ -26,4 +26,9 @@ export interface IBuildContext {
26
26
  * 云开发sdk请求,js-sdk or wx.cloud
27
27
  */
28
28
  endpointType?: 'tcb-api' | 'wechat-service';
29
+ /**
30
+ * 是否在页面层面添加节点
31
+ * 并设置 #page-root-id
32
+ */
33
+ enablePageRoot?: boolean;
29
34
  }
@@ -276,9 +276,21 @@ function createDataBinds(ctx, widgets) {
276
276
  const { directives = {} } = xProps;
277
277
  setDataBind(dataBinds[id], '_waFor', directives.waFor);
278
278
  setDataBind(dataBinds[id], '_waIf', directives.waIf);
279
+ if (directives.waDisplay) {
280
+ let { type, value } = directives.waDisplay;
281
+ if (!type || type === 'static') {
282
+ type = weapps_core_1.PropBindType.expression;
283
+ value = `${JSON.stringify(value)}`;
284
+ }
285
+ setDataBind(dataBinds[id], '_waDisplay', {
286
+ ...directives.waDisplay,
287
+ type,
288
+ value,
289
+ });
290
+ }
279
291
  setDataBind(dataBinds[id], 'classList', xProps.classListBind);
280
292
  setDataBind(dataBinds[id], 'style', xProps.styleBind);
281
- const { classList, style } = dataBinds[id];
293
+ const { classList, style, _waDisplay } = dataBinds[id];
282
294
  if (classList) {
283
295
  dataBinds[id].classList = {
284
296
  ...classList,
@@ -286,12 +298,21 @@ function createDataBinds(ctx, widgets) {
286
298
  };
287
299
  }
288
300
  if (style) {
289
- const styleExpression = `{...widgetProps.${id}.style, ...(\n${style === null || style === void 0 ? void 0 : style.expression}\n)}`;
301
+ const styleExpression = _waDisplay
302
+ ? `{...widgetProps.${id}.style, ...(\n${style === null || style === void 0 ? void 0 : style.expression}\n), display: (()=>{${_waDisplay === null || _waDisplay === void 0 ? void 0 : _waDisplay.imports}\n return (\n${_waDisplay === null || _waDisplay === void 0 ? void 0 : _waDisplay.expression}\n)})() ? undefined: 'none' }`
303
+ : `{...widgetProps.${id}.style, ...(\n${style === null || style === void 0 ? void 0 : style.expression}\n)}`;
290
304
  dataBinds[id].style = {
291
305
  ...style,
292
306
  expression: processCssUnit === 'rpx' ? `px2rpx(${styleExpression})` : styleExpression,
293
307
  };
294
308
  }
309
+ else if (_waDisplay) {
310
+ const styleExpression = `{...widgetProps.${id}.style, display: (\n${_waDisplay === null || _waDisplay === void 0 ? void 0 : _waDisplay.expression}\n)? undefined: 'none' }`;
311
+ dataBinds[id].style = {
312
+ ..._waDisplay,
313
+ expression: processCssUnit === 'rpx' ? `px2rpx(${styleExpression})` : styleExpression,
314
+ };
315
+ }
295
316
  if (Object.keys(dataBinds[id]).length === 0) {
296
317
  delete dataBinds[id];
297
318
  }
@@ -32,17 +32,36 @@ function generateWxml(ctx, widgets, docTag, wxmlDataPrefix, usingComponents, com
32
32
  ].concat(createXml(widgets)),
33
33
  };
34
34
  if (ctx.isPage) {
35
+ const { enablePageRoot } = ctx;
35
36
  const originElements = xmlJson.elements;
36
37
  // 登录校验: 向其最外层包裹一层block
37
38
  xmlJson.elements = [
38
39
  {
39
40
  type: 'element',
40
- name: 'block',
41
+ name: enablePageRoot ? 'view' : 'block',
41
42
  attributes: {
43
+ id: 'wd-page-root',
42
44
  ['wx:if']: '{{weDaHasLogin}}',
43
45
  ['data-weui-theme']: 'light',
44
46
  },
45
- elements: originElements,
47
+ elements: [
48
+ ...originElements,
49
+ /**
50
+ * 可能需要依赖添加逻辑节点的方式
51
+ * 来触发 page 的 ready
52
+ * 目的是为了让 page 的 ready 在组件的 ready 之后
53
+ */
54
+ // {
55
+ // type: 'element',
56
+ // name: 'readyPlaceHoler',
57
+ // attributes: {
58
+ // ['bind:ready']: '_onReady',
59
+ // },
60
+ // elements: originElements,
61
+ // _order: Infinity,
62
+ // _parent: null,
63
+ // },
64
+ ],
46
65
  _order: -1,
47
66
  _parent: null,
48
67
  },
@@ -164,6 +183,13 @@ function generateWxml(ctx, widgets, docTag, wxmlDataPrefix, usingComponents, com
164
183
  if ((_d = directives.waIf) === null || _d === void 0 ? void 0 : _d.value) {
165
184
  node.attributes['wx:if'] = getAttrBind(directives.waIf, `${attrPrefix}._waIf`);
166
185
  }
186
+ /**
187
+ * 对于 hidden 的支持依赖组件透传对应的属性
188
+ * 为了兼容,采用 style merge 的方式
189
+ */
190
+ // if (directives.waDisplay?.value !== undefined && directives.waDisplay?.value !== true) {
191
+ // node.attributes['hidden'] = getAttrBind(directives.waDisplay, `${attrPrefix}._waDisplay`, false, true);
192
+ // }
167
193
  if ((_e = directives.waFor) === null || _e === void 0 ? void 0 : _e.value) {
168
194
  node.attributes['wx:for'] = getAttrBind(directives.waFor, `${wxmlDataPrefix.widgetProp}${id}${parentForNodes
169
195
  .map((forNodeId) => `[${wxmlDataPrefix.forIndex}${forNodeId}]`)
@@ -368,10 +394,12 @@ function getUsedComponents(widgets, usedCmps = {}) {
368
394
  return usedCmps;
369
395
  }
370
396
  exports.getUsedComponents = getUsedComponents;
371
- function getAttrBind(dVale, widgetBind, isStaticResource) {
397
+ function getAttrBind(dVale, widgetBind, isStaticResource, neg) {
372
398
  const { type, value } = dVale;
373
399
  const attrVal = type === weapps_core_1.PropBindType.prop ? value : widgetBind;
374
- return isStaticResource ? `{{wxsUtils._getStaticResourceAttribute(${attrVal})}}` : `{{${attrVal}}}`;
400
+ return isStaticResource
401
+ ? `{{${neg ? '!' : ''}wxsUtils._getStaticResourceAttribute(${attrVal})}}`
402
+ : `{{${neg ? `!(${attrVal})` : `${attrVal}`}}}`;
375
403
  }
376
404
  function getGenericCompTagName(propName) {
377
405
  return `g--${propName}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/lowcode-builder",
3
- "version": "1.4.5",
3
+ "version": "1.5.1",
4
4
  "description": "云开发 Tencent CloudBase Framework Low Code Plugin,将低码配置生成完整项目并一键部署云开发资源。",
5
5
  "author": "yhsunshining@gmail.com",
6
6
  "homepage": "https://github.com/TencentCloudBase/cloudbase-framework#readme",
@@ -38,8 +38,8 @@
38
38
  "url": "https://github.com/TencentCloudBase/cloudbase-framework/issues"
39
39
  },
40
40
  "dependencies": {
41
- "@cloudbase/cals": "^0.5.14",
42
- "@cloudbase/lowcode-generator": "^1.4.0",
41
+ "@cloudbase/cals": "^0.5.16",
42
+ "@cloudbase/lowcode-generator": "^1.5.1",
43
43
  "axios": "^0.21.0",
44
44
  "browserfs": "^1.4.3",
45
45
  "browserify-zlib": "^0.2.0",
@@ -475,7 +475,7 @@
475
475
  crossorigin
476
476
  src="<%=
477
477
  cdnEndpoints.cdngo
478
- %>/lcap/lcap-resource-cdngo/-/0.1.4/_files/static/weda-render/main.39b933e356640041bb42.bundle.js"
478
+ %>/lcap/lcap-resource-cdngo/-/0.1.4/_files/static/weda-render/main.174df5037414faa855d5.bundle.js"
479
479
  ></script>
480
480
  </body>
481
481
  </html>
@@ -83,20 +83,43 @@ setConfig({
83
83
  })
84
84
 
85
85
  App({
86
- onLaunch(options) {
86
+ _query: {},
87
+ globaldata: {
88
+ _beforeCustomLaunchPromise: null
89
+ },
90
+ async beforeCustomLaunch(query) {
91
+ if(!this.globaldata?._beforeCustomLaunchPromise){
92
+ if(!this.globaldata) {
93
+ this.globaldata = {}
94
+ }
95
+ this.globaldata._beforeCustomLaunchPromise = new Promise(async (resolve)=>{
96
+ try {
97
+ EXTRA_API.setParams('$global', query || {})
98
+ await createStateDataSourceVar('$global', generateParamsParser({ app, $page: {} }));
99
+ } catch (e) {
100
+ throw e;
101
+ } finally {
102
+ resolve()
103
+ }
104
+ })
105
+ }
106
+ return this.globaldata._beforeCustomLaunchPromise
107
+ },
108
+ async onLaunch(options) {
87
109
  this.app = app
88
110
  const onLaunch = lifeCycle.onLaunch || lifeCycle.onAppLaunch
89
111
  let { query = {} } = options
90
- EXTRA_API.setParams('$global', query)
91
- createStateDataSourceVar('$global', generateParamsParser({ app }))
112
+ this._query = query
92
113
 
114
+ await this.beforeCustomLaunch(query)
93
115
  onLaunch && onLaunch.call(this, options)
94
116
  // 初始私有全局数据
95
117
  this.$$global = {
96
118
  homePageId: '<%= appConfig.homePageId %>'
97
119
  }
98
120
  },
99
- onShow(options) {
121
+ async onShow(options) {
122
+ await this.beforeCustomLaunch(this._query)
100
123
  const fn = lifeCycle.onShow || lifeCycle.onAppShow
101
124
  fn && fn.call(this, options)
102
125
  },
@@ -12,6 +12,8 @@ import {
12
12
  import { runWatchers } from './watch';
13
13
  import { getMpEventHandlerName } from './util';
14
14
 
15
+ const wxApp = getApp()
16
+
15
17
  export function createPage(
16
18
  id,
17
19
  uuid,
@@ -103,32 +105,54 @@ export function createPage(
103
105
  },
104
106
  methods: {
105
107
  _pageActive: true,
108
+ _beforePageCustomLaunchPromise: null,
109
+ _query: {},
110
+
106
111
  /** page lifecycles **/
107
112
  ...extractLifecycles(),
108
113
  ...evtHandlers,
109
114
  ...mergeRenderer,
110
- onLoad(options) {
115
+ async beforePageCustomLaunch(query) {
116
+ if(!this._beforePageCustomLaunchPromise){
117
+ this._beforePageCustomLaunchPromise = new Promise(async (resolve)=>{
118
+ await wxApp.globaldata?._beforePageCustomLaunchPromise
119
+ const $page = this._getInstance();
120
+ if(query){
121
+ EXTRA_API.setParams($page.uuid, query);
122
+ }
123
+ if(await checkAuth(app, app.id, $page)){
124
+ this.setData({
125
+ weDaHasLogin: true,
126
+ });
127
+ createStateDataSourceVar($page.uuid, generateParamsParser({ app, $page }));
128
+ resolve()
129
+ }
130
+ })
131
+ }
132
+ return this._beforePageCustomLaunchPromise
133
+ },
134
+ async onLoad(options) {
111
135
  const $page = this._getInstance();
112
136
  setConfig({ currentPageId: $page.uuid });
113
137
  app.__internal__.activePage = $page;
114
138
  this._pageActive = true;
115
139
 
116
- let query = decodePageQuery(options || {});
117
- EXTRA_API.setParams($page.uuid, query);
118
- createStateDataSourceVar($page.uuid, generateParamsParser({ app, $page }));
140
+ this._query = decodePageQuery(options || {});
119
141
 
120
- const hook = lifecycle.onLoad || lifecycle.onPageLoad;
121
- hook?.call?.($page, query);
142
+ await this.beforePageCustomLaunch?.(this._query)
122
143
 
123
- this.invokeEventHandler(id, 'load', { detail: { query } });
144
+ const hook = lifecycle.onLoad || lifecycle.onPageLoad;
145
+ await hook?.call?.($page, this._query);
146
+ this.invokeEventHandler(id, 'load', { detail: { query: this._query } });
124
147
  },
125
- onReady() {
148
+ async onReady() {
126
149
  const $page = this._getInstance();
150
+ console.log("onReady", this, $page)
127
151
 
128
152
  this._disposers.push(...runWatchers(index, this));
129
153
 
130
154
  const hook = lifecycle.onReady || lifecycle.onPageReady;
131
- hook?.call?.($page);
155
+ await hook?.call?.($page);
132
156
 
133
157
  this.invokeEventHandler(id, 'ready');
134
158
  },
@@ -146,15 +170,12 @@ export function createPage(
146
170
  app.__internal__.activePage = $page;
147
171
  this._pageActive = true;
148
172
 
173
+ await this.beforePageCustomLaunch?.(this._query)
174
+
149
175
  // 权限检查
150
- if (await checkAuth(app, app.id, $page)) {
151
- this.setData({
152
- weDaHasLogin: true,
153
- });
154
- const hook = lifecycle.onShow || lifecycle.onPageShow;
155
- hook?.call?.($page);
156
- this.invokeEventHandler(id, 'show');
157
- }
176
+ const hook = lifecycle.onShow || lifecycle.onPageShow;
177
+ await hook?.call?.($page);
178
+ this.invokeEventHandler(id, 'show');
158
179
  },
159
180
  onHide() {
160
181
  const $page = this._getInstance();
@@ -5,7 +5,7 @@
5
5
  "dependencies": {<% if(importJSSDK) {%>
6
6
  "@cloudbase/js-sdk": "2.5.6-beta.1",<% } %>
7
7
  "@cloudbase/oauth": "0.1.1-alpha.5",
8
- "@cloudbase/weda-client": "0.2.47",
8
+ "@cloudbase/weda-client": "0.2.51",
9
9
  "@cloudbase/weda-cloud-sdk": "1.0.26",
10
10
  "mobx": "^5.15.4",
11
11
  "lodash.get": "^4.4.2",