@cloudbase/lowcode-builder 1.1.5-alpha.1 → 1.1.5-alpha.3

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.
@@ -3,7 +3,7 @@ import { BuildType, GenerateMpType, WebpackBuildCallBack, WebpackModeType } from
3
3
  import { DEPLOY_MODE, RUNTIME } from '../../types';
4
4
  import { IPlatformApp } from '@cloudbase/cals';
5
5
  import { ICDN_ENDPOINTS_COFIG } from '../config';
6
- export interface IBaseAppProps {
6
+ interface IBaseAppProps {
7
7
  appKey: string;
8
8
  dependencies?: IMaterialItem[];
9
9
  publicPath?: string;
@@ -37,8 +37,9 @@ export interface IBuildWedaApp extends IBaseAppProps {
37
37
  };
38
38
  isBrowserMpBuilder?: boolean;
39
39
  cdnEndpoints?: ICDN_ENDPOINTS_COFIG;
40
+ isPrivateMode?: boolean;
40
41
  }
41
- export declare function buildWedaApp({ cals, subAppCalsList, dependencies, appKey, runtime, ignoreInstall, buildTypeList, mode, devTool, deployOptions, generateMpType, plugins, extraData, resourceAppId, domain, output, isBrowserMpBuilder, cdnEndpoints, }: IBuildWedaApp, cb?: WebpackBuildCallBack): Promise<string | undefined>;
42
+ export declare function buildWedaApp({ cals, subAppCalsList, dependencies, appKey, runtime, ignoreInstall, buildTypeList, mode, devTool, deployOptions, generateMpType, plugins, extraData, resourceAppId, domain, output, isBrowserMpBuilder, cdnEndpoints, isPrivateMode, }: IBuildWedaApp, cb?: WebpackBuildCallBack): Promise<string | undefined>;
42
43
  export declare function cleanComponentDir(): Promise<void>;
43
44
  export declare const version: any;
44
45
  export { getFiles, fileToZip, strToBuf } from '../util/generateFiles';
@@ -20,7 +20,7 @@ const pkg = require('../../../package.json');
20
20
  async function buildWedaApp({ cals, subAppCalsList = [], dependencies = [], appKey = 'test', runtime = types_1.RUNTIME.NONE, ignoreInstall = false, buildTypeList = [common_1.BuildType.WEB], mode = common_1.WebpackModeType.PRODUCTION, devTool = 'webpack', deployOptions = { mode: types_1.DEPLOY_MODE.PREVIEW }, generateMpType = common_1.GenerateMpType.APP, plugins = [], extraData = {
21
21
  isComposite: false,
22
22
  compProps: {},
23
- }, resourceAppId = undefined, domain = '', output, isBrowserMpBuilder = false, cdnEndpoints, }, cb) {
23
+ }, resourceAppId = undefined, domain = '', output, isBrowserMpBuilder = false, cdnEndpoints, isPrivateMode = false, }, cb) {
24
24
  var _a, _b;
25
25
  if (!cals) {
26
26
  console.error('无效的应用配置');
@@ -28,6 +28,17 @@ async function buildWedaApp({ cals, subAppCalsList = [], dependencies = [], appK
28
28
  }
29
29
  const { mode: deployMode = types_1.DEPLOY_MODE.PREVIEW } = deployOptions;
30
30
  let appBuildDir = (output === null || output === void 0 ? void 0 : output.path) || (runtime === types_1.RUNTIME.CI ? (_a = (0, util_1.getCompileDirs)('app')) === null || _a === void 0 ? void 0 : _a.appBuildDir : (_b = (0, util_1.getCompileDirs)(appKey)) === null || _b === void 0 ? void 0 : _b.appBuildDir);
31
+ const buildContext = {
32
+ projDir: appBuildDir,
33
+ appId: appKey,
34
+ isProduction: mode === common_1.WebpackModeType.PRODUCTION,
35
+ materialLibs: dependencies,
36
+ debugMode: mode !== common_1.WebpackModeType.PRODUCTION && !!process.env.WEAPPS_DEBUG,
37
+ isMixMode: generateMpType === common_1.GenerateMpType.SUBPACKAGE,
38
+ domain,
39
+ isBrowserMpBuilder,
40
+ isPrivateMode,
41
+ };
31
42
  console.log('domain', domain);
32
43
  console.log('应用名', appKey);
33
44
  console.log('生成模式', generateMpType);
@@ -37,23 +48,21 @@ async function buildWedaApp({ cals, subAppCalsList = [], dependencies = [], appK
37
48
  if (buildTypeList.includes(common_1.BuildType.MP)) {
38
49
  const mainAppSerializeData = (0, common_2.processCals2WeappsData)(cals, dependencies);
39
50
  const subAppSerializeDataList = (subAppCalsList === null || subAppCalsList === void 0 ? void 0 : subAppCalsList.map((item) => (0, common_2.processCals2WeappsData)(item, dependencies))) || [];
40
- appBuildDir = (output === null || output === void 0 ? void 0 : output.path) || path_1.default.join(appBuildDir, 'mp');
41
- const isMixMode = generateMpType === common_1.GenerateMpType.SUBPACKAGE;
42
51
  const apps = [mainAppSerializeData, ...subAppSerializeDataList];
43
52
  if (isBrowserMpBuilder) {
44
53
  // 尽早下载物料
45
54
  await (0, net_1.downloadBrowserMaterial)(output === null || output === void 0 ? void 0 : output.path);
46
55
  }
56
+ const mpBuildContext = {
57
+ ...buildContext,
58
+ projDir: (output === null || output === void 0 ? void 0 : output.path) || path_1.default.join(appBuildDir, 'mp'),
59
+ mainAppData: mainAppSerializeData,
60
+ };
47
61
  const result = await (0, index_1.generateWxMp)({
48
62
  weapps: apps,
49
- projDir: appBuildDir,
50
- appId: appKey,
51
- domain,
52
- materials: dependencies,
63
+ buildContext: mpBuildContext,
53
64
  plugins,
54
- isProduction: mode === common_1.WebpackModeType.PRODUCTION,
55
65
  deployMode,
56
- isMixMode,
57
66
  options: {
58
67
  isCrossAccount: resourceAppId !== deployOptions.targetMpAppId,
59
68
  mpAppId: deployOptions.mpAppId || '',
@@ -61,19 +70,20 @@ async function buildWedaApp({ cals, subAppCalsList = [], dependencies = [], appK
61
70
  },
62
71
  buildTypeList,
63
72
  isBrowserMpBuilder,
73
+ ignoreInstall,
64
74
  });
65
75
  // 如果是混合模式,则将特定的目录复制到工程下
66
76
  // 针对 app.json / package.json 则采用 merge 的操作
67
- if (isMixMode) {
68
- console.log(chalk_1.default.green('【混合模式】'), appBuildDir);
77
+ if (buildContext.isMixMode) {
78
+ console.log(chalk_1.default.green('【混合模式】'), mpBuildContext.projDir);
69
79
  await (0, mixMode_1.handleMixMode)({
80
+ buildContext: mpBuildContext,
70
81
  apps,
71
- generateMpPath: appBuildDir,
72
82
  miniprogramRoot: result.miniprogramRoot,
73
83
  plugins,
74
84
  });
75
85
  }
76
- const outDir = appBuildDir;
86
+ const outDir = mpBuildContext.projDir;
77
87
  let projectJsonPath = path_1.default.resolve(outDir, 'project.config.json');
78
88
  await (0, postProcess_1.postprocessProjectConfig)(projectJsonPath, {
79
89
  appid: deployOptions === null || deployOptions === void 0 ? void 0 : deployOptions.mpAppId,
@@ -81,7 +91,7 @@ async function buildWedaApp({ cals, subAppCalsList = [], dependencies = [], appK
81
91
  });
82
92
  // 如果是代开发的模式,则写入ext.json
83
93
  await (0, postProcess_1.postprocessDeployExtraJson)(outDir, deployOptions);
84
- if (!isBrowserMpBuilder && generateMpType === common_1.GenerateMpType.APP) {
94
+ if (!isBrowserMpBuilder && generateMpType === common_1.GenerateMpType.APP && !ignoreInstall) {
85
95
  // 模板拷入的 miniprogram_npm 有问题,直接删除使用重新构建的版本
86
96
  // 模板需要占位保证 mp 文件夹存在
87
97
  fs_extra_1.default.removeSync(path_1.default.resolve(outDir, 'miniprogram_npm'));
@@ -95,9 +105,7 @@ async function buildWedaApp({ cals, subAppCalsList = [], dependencies = [], appK
95
105
  }
96
106
  else {
97
107
  const h5BuildDir = await (0, index_2.buildH5App)({
98
- appKey,
99
- buildDir: appBuildDir,
100
- dependencies,
108
+ buildContext: { ...buildContext, isMixMode: false },
101
109
  cals,
102
110
  subAppCalsList,
103
111
  extraData,
@@ -107,7 +115,6 @@ async function buildWedaApp({ cals, subAppCalsList = [], dependencies = [], appK
107
115
  runtime,
108
116
  deployMode,
109
117
  ignoreInstall,
110
- domain,
111
118
  cdnEndpoints,
112
119
  });
113
120
  await (cb === null || cb === void 0 ? void 0 : cb(null, {
@@ -194,7 +201,7 @@ function normalizeInputs(inputs, { envId, getWebRootPath, }) {
194
201
  ...deployOptions,
195
202
  mpAppId: deployOptions.mpAppId || mpAppId,
196
203
  };
197
- if (inputs.deployOptions.targetMpAppId === undefined) {
204
+ if (!inputs.deployOptions.targetMpAppId) {
198
205
  inputs.deployOptions.targetMpAppId = inputs.deployOptions.mpAppId;
199
206
  }
200
207
  }
@@ -1,14 +1,13 @@
1
- import { IMaterialItem, II18nConfig, IExtraData } from '@cloudbase/lowcode-generator/lib/weapps-core';
1
+ import { II18nConfig, IExtraData } from '@cloudbase/lowcode-generator/lib/weapps-core';
2
2
  import { BuildType, WebpackModeType } from '../types/common';
3
3
  import { DEPLOY_MODE, RUNTIME } from '../../types';
4
4
  import { IPlatformApp } from '@cloudbase/cals';
5
5
  import { ICDN_ENDPOINTS_COFIG } from '../config';
6
- export declare function buildH5App({ appKey, buildDir, dependencies, i18nConfig, extraData, cals, buildTypeList, subAppCalsList, mode, devTool, runtime, deployMode, ignoreInstall, domain, cdnEndpoints, }: {
7
- appKey: string;
8
- buildDir: string;
6
+ import { IBuildContext } from '../mp/BuildContext';
7
+ export declare function buildH5App({ buildContext, i18nConfig, extraData, cals, buildTypeList, subAppCalsList, mode, devTool, runtime, deployMode, ignoreInstall, cdnEndpoints, }: {
8
+ buildContext: Omit<IBuildContext, 'mainAppData'>;
9
9
  cals: IPlatformApp;
10
10
  subAppCalsList: IPlatformApp[];
11
- dependencies: IMaterialItem[];
12
11
  i18nConfig?: II18nConfig;
13
12
  buildTypeList: BuildType[];
14
13
  extraData: IExtraData;
@@ -17,6 +16,5 @@ export declare function buildH5App({ appKey, buildDir, dependencies, i18nConfig,
17
16
  runtime?: RUNTIME;
18
17
  deployMode?: DEPLOY_MODE;
19
18
  ignoreInstall?: boolean;
20
- domain: string;
21
19
  cdnEndpoints?: ICDN_ENDPOINTS_COFIG;
22
20
  }): Promise<string>;
@@ -20,8 +20,9 @@ const mp_1 = require("../mp");
20
20
  const common_2 = require("../../utils/common");
21
21
  const config_1 = require("../config");
22
22
  const fs_extra_1 = __importDefault(require("fs-extra"));
23
- async function buildH5App({ appKey, buildDir, dependencies, i18nConfig, extraData, cals, buildTypeList = [common_1.BuildType.WEB], subAppCalsList, mode, devTool, runtime = types_1.RUNTIME.NONE, deployMode = types_1.DEPLOY_MODE.PREVIEW, ignoreInstall = false, domain = '', cdnEndpoints, }) {
23
+ 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, }) {
24
24
  var _a, _b, _c;
25
+ const { projDir: buildDir, domain, materialLibs: dependencies, appId: appKey, isPrivateMode } = buildContext;
25
26
  try {
26
27
  const { materialsDir } = runtime === types_1.RUNTIME.CI ? (0, util_1.getCompileDirs)(appKey) : (0, util_1.getCompileDirs)('app');
27
28
  const h5BuildDir = path_1.default.join(buildDir, 'h5');
@@ -35,19 +36,9 @@ async function buildH5App({ appKey, buildDir, dependencies, i18nConfig, extraDat
35
36
  }
36
37
  const mainAppSerializeData = (0, common_2.processCals2WeappsData)(cals, dependencies);
37
38
  const subAppSerializeDataList = (subAppCalsList === null || subAppCalsList === void 0 ? void 0 : subAppCalsList.map((item) => (0, common_2.processCals2WeappsData)(item, dependencies))) || [];
38
- const buildContext = {
39
- projDir: buildDir,
40
- appId: appKey,
41
- isProduction: mode === common_1.WebpackModeType.PRODUCTION,
42
- materialLibs: dependencies,
43
- isMixMode: false,
44
- mainAppData: mainAppSerializeData,
45
- domain,
46
- };
47
39
  const { allAppUsedComps } = (0, mp_1.handleUsedComponents)({
48
- buildContext,
40
+ buildContext: { ...buildContext, mainAppData: mainAppSerializeData },
49
41
  weapps: [mainAppSerializeData, ...subAppSerializeDataList],
50
- materials: dependencies,
51
42
  });
52
43
  // 处理应用数据
53
44
  const mainAppData = (0, weapps_core_1.deserialize)(mainAppSerializeData);
@@ -97,6 +88,7 @@ async function buildH5App({ appKey, buildDir, dependencies, i18nConfig, extraDat
97
88
  runtime,
98
89
  deployMode,
99
90
  _indexPage,
91
+ isPrivateMode,
100
92
  });
101
93
  console.timeEnd(runGenerateTag);
102
94
  // // 构建 NPM 包
@@ -3,6 +3,9 @@ import { IMaterialItem, IWeAppData, IMiniprogramPlugin } from '@cloudbase/lowcod
3
3
  * All build parameters and intermediate data to be share across processes
4
4
  */
5
5
  export interface IBuildContext {
6
+ /**
7
+ * 应用id
8
+ */
6
9
  appId: string;
7
10
  domain: string;
8
11
  projDir: string;
@@ -14,4 +17,5 @@ export interface IBuildContext {
14
17
  miniprogramPlugins?: IMiniprogramPlugin[];
15
18
  debugMode?: boolean;
16
19
  isBrowserMpBuilder?: boolean;
20
+ isPrivateMode?: boolean;
17
21
  }
@@ -1,17 +1,12 @@
1
- import { IMaterialItem, IWeAppData, IPlugin } from '@cloudbase/lowcode-generator/lib/weapps-core';
1
+ import { IWeAppData, IPlugin } from '@cloudbase/lowcode-generator/lib/weapps-core';
2
2
  import { IBuildContext } from './BuildContext';
3
3
  import { DEPLOY_MODE } from '../../types';
4
4
  import { BuildType, IAppUsedComp, IUsedComps } from '../types/common';
5
- export declare function generateWxMp({ weapps, projDir, appId, domain, materials, plugins, isProduction, deployMode, isMixMode, options, buildTypeList, isBrowserMpBuilder, }: {
5
+ export declare function generateWxMp({ buildContext, weapps, plugins, deployMode, options, buildTypeList, isBrowserMpBuilder, ignoreInstall, }: {
6
+ buildContext: IBuildContext;
6
7
  weapps: IWeAppData[];
7
- projDir: string;
8
- appId: string;
9
- domain: string;
10
- materials: IMaterialItem[];
11
8
  plugins: IPlugin[];
12
- isProduction: boolean;
13
9
  deployMode: DEPLOY_MODE;
14
- isMixMode: boolean;
15
10
  options: {
16
11
  mpAppId: string;
17
12
  resourceAppId?: string;
@@ -19,6 +14,7 @@ export declare function generateWxMp({ weapps, projDir, appId, domain, materials
19
14
  };
20
15
  buildTypeList: BuildType[];
21
16
  isBrowserMpBuilder: boolean;
17
+ ignoreInstall: boolean;
22
18
  }): Promise<{
23
19
  miniprogramRoot: string;
24
20
  }>;
@@ -27,10 +23,9 @@ export declare function writeLowCodeFiles(appData: IWeAppData, outDir: string, c
27
23
  * TODO: 与 cals 里的实现进行整合
28
24
  * 关键点在于 appUsedComps 分组, 与 generic componen 的实现
29
25
  */
30
- export declare function handleUsedComponents({ buildContext, weapps, materials, }: {
26
+ export declare function handleUsedComponents({ buildContext, weapps }: {
31
27
  buildContext: IBuildContext;
32
28
  weapps: IWeAppData[];
33
- materials: IMaterialItem[];
34
29
  }): {
35
30
  appUsedComps: IAppUsedComp[];
36
31
  allAppUsedComps: IUsedComps;
@@ -54,29 +54,13 @@ const cals_1 = require("@cloudbase/cals");
54
54
  const templateDir = `${config_1.appTemplateDir}/mp/`;
55
55
  const em = chalk_1.default.blue.bold;
56
56
  const error = chalk_1.default.redBright;
57
- async function generateWxMp({ weapps, projDir, appId, domain, materials, plugins, isProduction, deployMode, isMixMode, options, buildTypeList, isBrowserMpBuilder = false, }) {
57
+ async function generateWxMp({ buildContext, weapps, plugins, deployMode, options, buildTypeList, isBrowserMpBuilder = false, ignoreInstall = false, }) {
58
58
  var _a;
59
+ const { appId, projDir, materialLibs: materials, isProduction, mainAppData, domain, isPrivateMode = false, } = buildContext;
59
60
  const operationLabel = em('Wexin MiniProgram Generated');
60
61
  console.time(operationLabel);
61
62
  console.log(`Generating ${em('Wexin MiniProgram')} to ${projDir}`);
62
- console.log(em('domain') + domain);
63
- let mainAppData = weapps[0];
64
- const buildContext = {
65
- projDir,
66
- appId,
67
- isProduction,
68
- materialLibs: materials,
69
- debugMode: !isProduction && !!process.env.WEAPPS_DEBUG,
70
- isMixMode,
71
- mainAppData,
72
- domain,
73
- isBrowserMpBuilder,
74
- };
75
- const { allAppUsedComps } = handleUsedComponents({
76
- buildContext,
77
- weapps,
78
- materials,
79
- });
63
+ const { allAppUsedComps } = handleUsedComponents({ buildContext, weapps });
80
64
  buildContext.miniprogramPlugins = (mainAppData.miniprogramPlugins || []).filter((plugin) => allAppUsedComps[plugin.name]);
81
65
  // 安装依赖库,生成 materials 目录
82
66
  await (0, materials_1.installMaterials)(projDir, allAppUsedComps, weapps, buildContext);
@@ -153,7 +137,6 @@ async function generateWxMp({ weapps, projDir, appId, domain, materials, plugins
153
137
  const importor = (0, util_3.generateLowcodeImportor)(mainAppData.lowCodes || []);
154
138
  appFileData = {
155
139
  ...appFileData,
156
- 'common/wx_yypt_report_v2.js': {},
157
140
  'app.js': { appConfig, importor },
158
141
  'app.json': { content: appConfig },
159
142
  'app.wxss': {
@@ -166,6 +149,7 @@ async function generateWxMp({ weapps, projDir, appId, domain, materials, plugins
166
149
  },
167
150
  'package.json': {
168
151
  appId,
152
+ isPrivateMode,
169
153
  extraDeps: resolveNpmDeps(),
170
154
  },
171
155
  };
@@ -187,6 +171,7 @@ async function generateWxMp({ weapps, projDir, appId, domain, materials, plugins
187
171
  resourceAppid: !!options.isCrossAccount ? options.resourceAppId : '',
188
172
  isProd: deployMode === types_1.DEPLOY_MODE.UPLOAD,
189
173
  clientID: (_a = mainAppData.extra) === null || _a === void 0 ? void 0 : _a.clientId,
174
+ isPrivateMode,
190
175
  },
191
176
  'datasources/datasource-profiles.js.tpl': {
192
177
  datasourceProfiles: (0, util_3.JsonToStringWithVariableName)((0, lowcode_generator_1.getDatasourceProfiles)(
@@ -221,6 +206,7 @@ async function generateWxMp({ weapps, projDir, appId, domain, materials, plugins
221
206
  await (0, generateFiles_1.default)({
222
207
  'package.json': {
223
208
  appId,
209
+ isPrivateMode,
224
210
  extraDeps: resolveNpmDeps(),
225
211
  },
226
212
  }, templateDir, subpackageRootPath, buildContext);
@@ -228,7 +214,10 @@ async function generateWxMp({ weapps, projDir, appId, domain, materials, plugins
228
214
  }
229
215
  }));
230
216
  if (!isBrowserMpBuilder && fs.existsSync(path_1.default.join(miniprogramRoot, 'package.json'))) {
231
- await (0, webpack_1.installDependencies)(miniprogramRoot);
217
+ await (0, webpack_1.installDependencies)(miniprogramRoot, {
218
+ ignoreInstall,
219
+ fixNodeModulesMap: { '@cloudbase/js-sdk': !isPrivateMode, mobx: true },
220
+ });
232
221
  }
233
222
  await handleMpPlugins();
234
223
  console.timeEnd(operationLabel);
@@ -240,7 +229,7 @@ async function generateWxMp({ weapps, projDir, appId, domain, materials, plugins
240
229
  var _a;
241
230
  const deps = [
242
231
  {
243
- deps: ((_a = weapps.find((a) => !a.rootPath)) === null || _a === void 0 ? void 0 : _a.npmDependencies) || [],
232
+ deps: ((_a = weapps.find((a) => !a.rootPath)) === null || _a === void 0 ? void 0 : _a.npmDependencies) || {},
244
233
  name: '主包',
245
234
  },
246
235
  ];
@@ -427,7 +416,7 @@ async function writeLowCodeFiles(appData, outDir, ctx) {
427
416
  // 混合模式,子包不生成顶级(应用级)的 lowcodes
428
417
  if (!(ctx.isMixMode && appData.rootPath)) {
429
418
  await Promise.all(lowCodes
430
- .filter((mod) => mod.type !== 'renderer')
419
+ .filter((mod) => mod.type !== cals_1.ECodeType.RENDERER)
431
420
  .map((m) => {
432
421
  (0, lowcode_1.writeCode2file)(m, lowcodeRootDir, { appDir: outDir }, themeStyle.code);
433
422
  }));
@@ -435,7 +424,7 @@ async function writeLowCodeFiles(appData, outDir, ctx) {
435
424
  await Promise.all((0, weapps_core_1.loopDealWithFn)(appData.pageInstanceList, async (page) => {
436
425
  const codes = (0, cals_1.processRuntimeCodeResources)({ id: page.id }, page.lowCodes || page.codeModules, 'page');
437
426
  await codes
438
- .filter((mod) => mod.type !== 'renderer')
427
+ .filter((mod) => mod.type !== cals_1.ECodeType.RENDERER)
439
428
  .forEach((m) => {
440
429
  (0, lowcode_1.writeCode2file)(m, lowcodeRootDir, { pageId: page.id, appDir: outDir }, themeStyle.code, ctx);
441
430
  });
@@ -463,7 +452,8 @@ function getAppendableJson(json) {
463
452
  * TODO: 与 cals 里的实现进行整合
464
453
  * 关键点在于 appUsedComps 分组, 与 generic componen 的实现
465
454
  */
466
- function handleUsedComponents({ buildContext, weapps, materials, }) {
455
+ function handleUsedComponents({ buildContext, weapps }) {
456
+ const { materialLibs: materials } = buildContext;
467
457
  const appUsedComps = weapps.map((app) => {
468
458
  var _a;
469
459
  const usedComps = {};
@@ -327,6 +327,12 @@ async function generateCompositeComponent(compositedComp, ctx, compLibCommonReso
327
327
  ${compLibCommonResource.theme.class || ''}
328
328
  `;
329
329
  }
330
+ /**
331
+ * 低码没有开放 index 类别,直接去掉
332
+ */
333
+ if (mod.name === 'index') {
334
+ return;
335
+ }
330
336
  return (0, lowcode_1.writeCode2file)(mod, path.join(outDir, LOWCODE_DIR_NAME), { comp: compositedComp }, themeCode, ctx);
331
337
  });
332
338
  // await writeLowCodeFiles(weapp, appRoot)
@@ -1,8 +1,9 @@
1
1
  import { IWeAppData, IPlugin, IMaterialItem } from '@cloudbase/lowcode-generator/lib/weapps-core';
2
2
  import { IAppUsedComp } from '../types/common';
3
- export declare function handleMixMode({ apps, generateMpPath, miniprogramRoot, plugins, }: {
3
+ import { IBuildContext } from '../mp/BuildContext';
4
+ export declare function handleMixMode({ buildContext, apps, miniprogramRoot, plugins, }: {
5
+ buildContext: IBuildContext;
4
6
  apps: IWeAppData[];
5
- generateMpPath: string;
6
7
  miniprogramRoot: string;
7
8
  plugins: IPlugin[];
8
9
  }): Promise<void>;
@@ -36,13 +36,16 @@ const chalk_1 = __importDefault(require("chalk"));
36
36
  const generateFiles_1 = require("../util/generateFiles");
37
37
  const webpack_1 = require("../service/webpack");
38
38
  // 将 BUILD 目录往混合模式移动
39
- async function handleMixMode({ apps = [], generateMpPath, miniprogramRoot, plugins = [], }) {
39
+ async function handleMixMode({ buildContext, apps = [], miniprogramRoot, plugins = [], }) {
40
+ const { projDir: generateMpPath, isPrivateMode } = buildContext;
40
41
  // await handleMainApp()
41
42
  // await handleAppPages()
42
43
  await handleSubApps();
43
44
  // await handleAppJson()
44
45
  // await handlePkgJson()
45
- await (0, webpack_1.installDependencies)(miniprogramRoot);
46
+ await (0, webpack_1.installDependencies)(miniprogramRoot, {
47
+ fixNodeModulesMap: { mobx: true, '@cloudbase/js-sdk': !isPrivateMode },
48
+ });
46
49
  await handlePlugins();
47
50
  // 复制框架公用内容
48
51
  async function handleMainApp() {
@@ -48,6 +48,7 @@ function generateMpConfig(weapps, ctx, options) {
48
48
  const { miniprogramPlugins = [] } = ctx;
49
49
  const projConfig = (0, lodash_1.merge)({}, mp_1.defaultProjConfig, {
50
50
  projectname: (ctx.mainAppData && ctx.mainAppData.label) || `WeDa-${ctx.appId}`,
51
+ appid: (options === null || options === void 0 ? void 0 : options.mpAppId) || mp_1.defaultProjConfig.appid,
51
52
  });
52
53
  const pageConfigs = weapps.map((app) => {
53
54
  var _a;
@@ -167,7 +168,7 @@ function transformDynamicData(originData) {
167
168
  const temp = {};
168
169
  for (const key in originData) {
169
170
  const target = originData[key];
170
- if (target && target.value) {
171
+ if (target === null || target === void 0 ? void 0 : target.value) {
171
172
  temp[key] = target.value;
172
173
  }
173
174
  }
@@ -67,7 +67,7 @@ function generateDataBindMeta(bind) {
67
67
  imports += (0, lowcode_generator_1.generateExpressionAlias)(value);
68
68
  }
69
69
  catch (e) {
70
- console.error('parse expression error', value);
70
+ console.error('parse expression error', value, e === null || e === void 0 ? void 0 : e.message);
71
71
  }
72
72
  expr = value;
73
73
  }
@@ -75,11 +75,17 @@ export interface IInstallOpts {
75
75
  version: string;
76
76
  downloadUrl: string;
77
77
  };
78
+ fixNodeModulesMap?: IFixNodeModulesMap;
78
79
  }
79
80
  export declare function installDependencies(targetDir: string, options?: IInstallOpts): Promise<void>;
81
+ interface IFixNodeModulesMap {
82
+ mobx?: boolean;
83
+ '@cloudbase/js-sdk'?: boolean;
84
+ }
80
85
  export declare function getMaterialNodeModulesPathList(dependencies: IMaterialItem[] | undefined, materialsDir: string, base?: string): string[];
81
86
  export declare function generateWebpackWebDevServerFile({ appBuildDir, buildTypeList }: {
82
87
  appBuildDir: any;
83
88
  buildTypeList: any;
84
89
  }): Promise<void>;
85
90
  export declare function downloadAssets(targetDir: string, assetUrl: string): Promise<unknown>;
91
+ export {};
@@ -455,7 +455,11 @@ async function installDependencies(targetDir, options = {}) {
455
455
  }
456
456
  }
457
457
  catch (e) { }
458
- if ((options === null || options === void 0 ? void 0 : options.ignoreInstall) && fs_extra_1.default.existsSync(path_1.default.join(targetDir, 'node_modules'))) {
458
+ // 如果generatedFileContents[path.resolve(targetDir, 'package.json')]不存在,说明是不存在缓存文件,isPkgModify必须是true,才不会忽略install
459
+ const isPkgModify = !generateFiles_1.generatedFileContents[path_1.default.resolve(targetDir, 'package.json')]
460
+ ? true
461
+ : generateFiles_1.generatedFileContents[path_1.default.resolve(targetDir, 'package.json')].modify;
462
+ if ((options === null || options === void 0 ? void 0 : options.ignoreInstall) && fs_extra_1.default.existsSync(path_1.default.join(targetDir, 'node_modules')) && !isPkgModify) {
459
463
  console.log(`ignore install dependencies in ${targetDir}`);
460
464
  return;
461
465
  }
@@ -480,20 +484,25 @@ async function installDependencies(targetDir, options = {}) {
480
484
  };
481
485
  }
482
486
  }
483
- let installProcess;
484
487
  // 云端构建, 选用 npm
485
- const installlProcessOptions = {
488
+ const installProcessOptions = {
486
489
  cwd: targetDir,
487
490
  // NODE_ENV="production"时,devDependencies里的包不会下载,兼容h5在线编译
488
491
  env: { ...process.env, NODE_ENV: '' },
489
492
  stdio: 'inherit',
490
493
  };
494
+ let installprocess;
495
+ // TODO: install 失败 应该终止进程
491
496
  if (yarnExists && (options === null || options === void 0 ? void 0 : options.runtime) !== types_1.RUNTIME.CI) {
492
497
  const addPackage = packageName ? ['add', packageName] : [];
493
- installProcess = cross_spawn_1.default.sync('yarn', [...addPackage, registry], installlProcessOptions);
498
+ installprocess = cross_spawn_1.default.sync('yarn', [...addPackage, registry], installProcessOptions);
494
499
  }
495
500
  else {
496
- installProcess = cross_spawn_1.default.sync('npm', ['install', packageName, ...npmOptions], installlProcessOptions);
501
+ installprocess = cross_spawn_1.default.sync('npm', ['install', packageName, ...npmOptions], installProcessOptions);
502
+ }
503
+ // TODO: 确认 process.status 语义来判断是否标识进程正常退出
504
+ if (installprocess.status) {
505
+ throw new Error(`安装依赖失败 ${installprocess.error || ''}`);
497
506
  }
498
507
  fixNodeModules(targetDir);
499
508
  try {
@@ -504,14 +513,24 @@ async function installDependencies(targetDir, options = {}) {
504
513
  console.timeEnd(operationTag);
505
514
  }
506
515
  exports.installDependencies = installDependencies;
507
- function fixNodeModules(projDir) {
508
- // # fix mobx/package.json: "main": "lib/index.js" -> "main": "lib/index.js"
509
- const mobxPackageFile = path_1.default.join(projDir, 'node_modules', 'mobx/package.json');
510
- if (fs_extra_1.default.existsSync(mobxPackageFile)) {
511
- const mobxPackageFileContent = fs_extra_1.default.readJSONSync(mobxPackageFile);
512
- if (fs_extra_1.default.existsSync(path_1.default.join(projDir, 'node_modules', 'mobx/lib/mobx.min.js'))) {
513
- mobxPackageFileContent.main = 'lib/mobx.min.js';
514
- fs_extra_1.default.writeJSONSync(mobxPackageFile, mobxPackageFileContent);
516
+ function fixNodeModules(projDir, options = { mobx: false, '@cloudbase/js-sdk': false }) {
517
+ const { mobx = false, ['@cloudbase/js-sdk']: jsSDK = false } = options;
518
+ if (mobx) {
519
+ // # fix mobx/package.json: "main": "lib/index.js" -> "main": "lib/index.js"
520
+ const mobxPackageFile = path_1.default.join(projDir, 'node_modules', 'mobx/package.json');
521
+ if (fs_extra_1.default.existsSync(mobxPackageFile)) {
522
+ const mobxPackageFileContent = fs_extra_1.default.readJSONSync(mobxPackageFile);
523
+ if (fs_extra_1.default.existsSync(path_1.default.join(projDir, 'node_modules', 'mobx/lib/mobx.min.js'))) {
524
+ mobxPackageFileContent.main = 'lib/mobx.min.js';
525
+ fs_extra_1.default.writeJSONSync(mobxPackageFile, mobxPackageFileContent);
526
+ }
527
+ }
528
+ }
529
+ if (jsSDK) {
530
+ const scriptPath = path_1.default.resolve(projDir, 'node_modules', '@cloudbase/weda-cloud-sdk/scripts/fix-wx-none-private');
531
+ if (fs_extra_1.default.existsSync(scriptPath)) {
532
+ const fix = require(scriptPath);
533
+ fix();
515
534
  }
516
535
  }
517
536
  }
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { IBuildContext } from '../mp/BuildContext';
3
3
  import { OutputType } from 'jszip';
4
+ export declare const generatedFileContents: {};
4
5
  export default function generateFiles(appFileData: any, srcDir: string, dstDir: string, ctx: IBuildContext): Promise<string[]>;
5
6
  export declare function writeFile(outFile: string, content: string): Promise<boolean>;
6
7
  export declare function removeFile(file: string): void;
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.strToBuf = exports.fileToZip = exports.getFiles = exports.copyRecursiveSync = exports.copyFileSync = exports.copy = exports.copyFiles = exports.cleanDir = exports.removeFile = exports.writeFile = void 0;
29
+ exports.strToBuf = exports.fileToZip = exports.getFiles = exports.copyRecursiveSync = exports.copyFileSync = exports.copy = exports.copyFiles = exports.cleanDir = exports.removeFile = exports.writeFile = exports.generatedFileContents = void 0;
30
30
  const fs_extra_1 = __importDefault(require("fs-extra"));
31
31
  const path_1 = __importDefault(require("path"));
32
32
  const lodash_1 = require("lodash");
@@ -34,7 +34,7 @@ const junk = __importStar(require("../util/junk"));
34
34
  const glob_1 = __importDefault(require("glob"));
35
35
  const jszip_1 = __importDefault(require("jszip"));
36
36
  const buffer_1 = require("buffer");
37
- const generatedFileContents = {}; // generated files for incrmental build
37
+ exports.generatedFileContents = {}; // generated files for incrmental build
38
38
  async function generateFiles(appFileData, srcDir, dstDir, ctx) {
39
39
  const filesGenerated = [];
40
40
  // Generating file by template and data
@@ -67,22 +67,24 @@ async function generateFiles(appFileData, srcDir, dstDir, ctx) {
67
67
  }
68
68
  exports.default = generateFiles;
69
69
  async function writeFile(outFile, content) {
70
- const generated = generatedFileContents[outFile];
70
+ var _a;
71
+ const generated = (_a = exports.generatedFileContents[outFile]) === null || _a === void 0 ? void 0 : _a.content;
71
72
  if (generated === content && fs_extra_1.default.existsSync(outFile)) {
73
+ exports.generatedFileContents[outFile].modify = false;
72
74
  return false;
73
75
  }
74
76
  // console.log(outFile);
75
77
  await fs_extra_1.default.ensureFile(outFile);
76
78
  await fs_extra_1.default.writeFile(outFile, content);
77
- generatedFileContents[outFile] = content;
79
+ exports.generatedFileContents[outFile] = { content, modify: true };
78
80
  return true;
79
81
  }
80
82
  exports.writeFile = writeFile;
81
83
  function removeFile(file) {
82
84
  console.log(`Removing ${file}`);
83
- Object.keys(generatedFileContents).map((cachedFile) => {
85
+ Object.keys(exports.generatedFileContents).map((cachedFile) => {
84
86
  if (cachedFile.indexOf(file) === 0) {
85
- delete generatedFileContents[cachedFile];
87
+ delete exports.generatedFileContents[cachedFile];
86
88
  }
87
89
  });
88
90
  return fs_extra_1.default.removeSync(file);
@@ -1,2 +1,3 @@
1
1
  export declare const is: (filename: any) => boolean;
2
2
  export declare const not: (filename: any) => boolean;
3
+ export declare const isFilePath: (filename: any) => boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.not = exports.is = void 0;
3
+ exports.isFilePath = exports.not = exports.is = void 0;
4
4
  const ignoreList = [
5
5
  // # All
6
6
  '^npm-debug\\.log$',
@@ -25,8 +25,14 @@ const ignoreList = [
25
25
  '^readme.md$',
26
26
  '^README.md$',
27
27
  ];
28
+ const filePathIgnoreList = [
29
+ '__MACOSX', // 路径有__MACOSX就过滤
30
+ ];
28
31
  const regex = new RegExp(ignoreList.join('|'));
32
+ const filePathRegex = new RegExp(filePathIgnoreList.join('|'));
29
33
  const is = (filename) => regex.test(filename);
30
34
  exports.is = is;
31
35
  const not = (filename) => !(0, exports.is)(filename);
32
36
  exports.not = not;
37
+ const isFilePath = (filename) => filePathRegex.test(filename);
38
+ exports.isFilePath = isFilePath;
@@ -34,6 +34,7 @@ const compressing_1 = __importDefault(require("compressing"));
34
34
  const jszip_1 = __importDefault(require("jszip"));
35
35
  const config_1 = require("../config");
36
36
  const generateFiles_1 = require("../util/generateFiles");
37
+ const junk_1 = require("../util/junk");
37
38
  async function downloadFile(url, filePath) {
38
39
  await fs_extra_1.default.ensureDir(path.dirname(filePath));
39
40
  const res = await axios_1.default.get(url, { responseType: 'stream' });
@@ -91,6 +92,9 @@ async function saveFiles(files, dstDir) {
91
92
  try {
92
93
  for (const fileName of Object.keys(files)) {
93
94
  const dest = path.join(dstDir, fileName);
95
+ if ((0, junk_1.isFilePath)(dest)) {
96
+ continue;
97
+ }
94
98
  if (files[fileName].dir) { // 如果该文件为目录需先创建文件夹
95
99
  fs_extra_1.default.mkdirSync(dest, {
96
100
  recursive: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/lowcode-builder",
3
- "version": "1.1.5-alpha.1",
3
+ "version": "1.1.5-alpha.3",
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.4.10",
42
- "@cloudbase/lowcode-generator": "^1.1.2-alpha.0",
41
+ "@cloudbase/cals": "^0.5.0",
42
+ "@cloudbase/lowcode-generator": "1.1.2-alpha.1",
43
43
  "axios": "^0.21.0",
44
44
  "browserfs": "^1.4.3",
45
45
  "browserify-zlib": "^0.2.0",
@@ -37,7 +37,8 @@ setConfig({
37
37
  }
38
38
 
39
39
  // 后续做过滤处理
40
- if (!loginPage || (params?.data?.mode === 'c' && skip)) {
40
+ const endpointType = app?.__internal__?.getCloudSdkConfig('endpointType');
41
+ if ((params?.data?.mode === 'c' && skip) || (endpointType !== 'tcb-api' && !loginPage)) {
41
42
  return params;
42
43
  }
43
44
  // await initTcb();
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  import { findForItemsOfWidget, getWidget } from './widget'
3
- import { observable } from 'mobx';
3
+ import { observable, untracked } from 'mobx';
4
4
  import { getAccessToken } from '../datasources/index'
5
5
  import { app } from '../app/weapps-api'
6
6
 
@@ -31,9 +31,13 @@ export function createComputed(funcs, bindContext = null) {
31
31
  export function generateDataContext(widget) {
32
32
  const dataContext = {};
33
33
  while (widget?._scope) {
34
- if (widget._scope.dataContext && !isEmptyObj(widget._scope.dataContext)) {
35
- dataContext[widget._scope.id] = widget._scope.dataContext;
36
- }
34
+ const current = widget
35
+ // 此处采用代理的方式,是为了可以获取到最新的 _scope.dataContext 防止 dataContext 引用被重新赋值
36
+ Object.defineProperty(dataContext, current._scope.id, {
37
+ get() {
38
+ return current._scope.dataContext;
39
+ },
40
+ });
37
41
  widget = widget.parent;
38
42
  }
39
43
  return dataContext;
@@ -57,7 +61,7 @@ export function createEventHandlers(evtListeners) {
57
61
  const [prefix = ''] = name.split('$');
58
62
  // The page event handler
59
63
  const { lists = [], itemsById = {} } = !!currentTarget && findForItemsOfWidget(currentTarget) || {}
60
- const dataContext = generateDataContext(currentTarget)
64
+ const dataContext = untracked(()=>generateDataContext(currentTarget))
61
65
 
62
66
  listeners.forEach(async l => {
63
67
  let { data = {}, boundData = {} } = l;
@@ -221,7 +221,7 @@ function runFor(
221
221
  clearTimeout(_FOR_ERROR_CACHE_MAP[nodeId]);
222
222
 
223
223
  const $instance = ownerMpInst.getWeAppInst();
224
- const dataContext = generateDataContext(defaultParent);
224
+ const dataContext = untracked(()=>generateDataContext(defaultParent));
225
225
 
226
226
  forList = dataBinds[nodeId]._waFor.call(
227
227
  $instance,
@@ -364,7 +364,7 @@ function setUpWidgetDataBinds(w, dataBinds, forItems, failedBinds, ctx) {
364
364
  try {
365
365
  clearTimeout(timer);
366
366
 
367
- const dataContext = generateDataContext(w);
367
+ const dataContext = untracked(()=>generateDataContext(w));
368
368
 
369
369
  // Computed data bind in the next tick since data bind may read widgets data
370
370
  const value = dataBinds[prop].call(ctx, ctx, forItems.lists, forItems.itemsById, undefined, dataContext);
@@ -22,4 +22,9 @@ export default {
22
22
  * key 为页面ID(全局为$global), val 为变量配置数组
23
23
  */
24
24
  datasetProfiles: datasetProfiles,
25
+ /**
26
+ * 确定调用链路
27
+ */
28
+ endpointType: <%= isPrivateMode %> ? 'tcb-api' : 'wechat-service',
29
+ isPrivate: <%= isPrivateMode %>
25
30
  }
@@ -2,18 +2,18 @@
2
2
  "name": "lcap-<%= appId%>",
3
3
  "version": "1.0.8",
4
4
  "scripts": {},
5
- "dependencies": {
6
- "@cloudbase/weda-client": "0.2.25",
7
- "@cloudbase/weda-cloud-sdk": "1.0.19",
5
+ "dependencies": {<% if(isPrivateMode) {%>
6
+ "@cloudbase/js-sdk": "2.5.5-alpha.0",<% } %>
8
7
  "@cloudbase/oauth": "0.1.1-alpha.5",
8
+ "@cloudbase/weda-client": "0.2.32",
9
+ "@cloudbase/weda-cloud-sdk": "1.0.24-alpha.3",
9
10
  "mobx": "^5.15.4",
10
11
  "lodash.get": "^4.4.2",
11
12
  "lodash.set": "^4.3.2",
12
13
  "miniprogram-gesture": "^1.0.6",
13
14
  "miniprogram-api-promise": "^1.0.4"<% Object.keys(extraDeps).map(depName => {%>,
14
- "<%= depName%>": "<%= extraDeps[depName]%>"<%
15
- })
16
- %>
15
+ "<%= depName%>": "<%= extraDeps[depName]%>"<%
16
+ })%>
17
17
  }
18
18
  }
19
19
 
@@ -1,460 +0,0 @@
1
- /*
2
- * 使用方法
3
- const wxReportSdk = require('./components/gsd-lib/report/index.js');
4
- new wxReportSdk({
5
- reportUrl:'http://www.qq.com',
6
- })
7
- */
8
- export default class wxReportSdk {
9
- constructor (opt) {
10
- this.originPage = Page;
11
- this.originApp = App;
12
- this.logTimer = null;
13
- this.idxKey = '_monitor_idx';
14
- this.config = {
15
- mp_appid: '', // 填入小程序的appid
16
- appKey: '', // 填入你的应用key
17
- stopReport: false, // 停止上报
18
- isNet: true, // 是否上报网络信息(默认:true)
19
- isSys: true, // 是否上报系统信息(默认:true)
20
- isError: true, // 是否开启错误上报 (默认:false)
21
- autoReportPV: false, // 是否自动上报页面PV
22
- commonPageEId: 'MP_ALLPAGES_ONSHOW', // 统一的页面上报标志
23
- getRemoteParamsUrl: '',// 获取远程参数url
24
- reportUrl: '', // 上报url
25
- intervalTime: 3, // 间隔多久执行一次上报,默认3秒
26
- reportLogsNum: 5, // 每次合并上报记录条数,默认5次
27
- };
28
-
29
- this.reportData = {
30
- ky: '',//app key,应用的身份标识
31
- pf: 'MiniProgram',// 平台类型
32
- id: '',// 平台型相关的ID字段,如微信平台中则是open_id
33
- cui: '',// custom user id,自定义用户id,用户上报的自定义用户id,也就是app业务方统计用户的身份标识,用于多平台帐号打通。
34
- geo: '',// 地理位置
35
- scene: '', // 入口场景,小程序的场景值
36
- ev: {
37
- 'cn': '',//connect type,设备连接方式
38
- 'lg': '',//anguage,系统语言类型
39
- 'sr': '',//screen resolution,屏幕分辨率
40
- 'tz': '',//time zone,系统的时区
41
- 'os': '',//操作系统,
42
- 'ua': '-', //
43
- },
44
- ui: '',// 一个随机生成的id,因为大多数没有id,cui,所以用ui计算uv
45
- si: '',//session id,会话id,一串随机产生的数字,标识一个新的会话
46
- ts: '',//timestamp,时间戳
47
- pi: '',// page id,页面id
48
- rf: '',// refer page id,来源页面id
49
- et: '1',// eventtype,事件类型,PAGE_VIEW(1),PAGE_HIDE(3001),SESSION_ENV(2),ERROR(3),CUSTOM(1000),ADDITION(1001),MONITOR_STAT(1002);SPECIAL_CUSTON(),小程序onshow使用PAGE_VIEW,关闭或隐藏时使用PAGE_HIDE,事件使用1000
50
- ht: '',// hot tag string 屏幕的点击事件ID
51
- htx: '',// hot tag x string 点击位置的X坐标
52
- hty: '',// hot tag y string 点击位置的Y坐标
53
- ei: '',// event id,自定义事件id string 自定义事件id
54
- kv: '',// Key-Value,自定义事件Key-Value参数对 map JSON格式
55
- er: '',// error,错误、异常信息 string 错误字符串或堆栈异常信息
56
- ea: '',//error attribute uint 共有4种错误类型:USER_MSG(0)、USER_EXCEPTION(1)、AUTO_EXCEPTION(2)、NATIVE_CRASH(3)、SDK_EXCEPTION(99)
57
- ext: '',//扩展字段,不进行计算,可存储更细的用户信息
58
- region: '', // 城市码
59
- mp_appid: '', // 小程序appid
60
- adt: "", // 自定义渠道来源
61
- };
62
-
63
- this.config = Object.assign(this.config, opt || {});
64
- this.reportLogs = [];
65
- this.pagePrams = {};//存储每个页面自定义上报的数据,例如kv
66
- this.cusSid = this._getCusSid();
67
- this._init();
68
- }
69
-
70
- // 获取自定义session
71
- _getCusSid(len = 10) {
72
- const $chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz123456789";
73
- const maxPos = $chars.length;
74
- let pwd = "";
75
- for (let i = 0; i < len; i++) {
76
- pwd = pwd + $chars.charAt(Math.floor(Math.random() * maxPos));
77
- }
78
- return pwd + new Date().getTime();
79
- }
80
-
81
- // 获取用户唯一标示
82
- _getUuid () {
83
- let uuidKey = "_mp_monitor_uuid_v2";
84
- let uuid = wx.getStorageSync(uuidKey);
85
- if (uuid) {
86
- return uuid;
87
- }
88
- let s = [];
89
- let hexDigits = '0123456789abcdef';
90
- for (let i = 0; i < 36; i++) {
91
- s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
92
- }
93
- s[14] = '4'; // bits 12-15 of the time_hi_and_version field to 0010
94
- s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
95
- s[8] = s[13] = s[18] = s[23] = '-';
96
- uuid = "mc_" + s.join('');
97
- wx.setStorageSync(uuidKey, uuid);
98
- return uuid;
99
- };
100
-
101
- startReport () {
102
- if (this.config.stopReport || !this._isAllowReport()) return;
103
- const _this = this;
104
- _this._logRequest();
105
- _this.logTimer = setInterval(function () {
106
- _this._logRequest();
107
- }, _this.config.intervalTime * 1000);
108
- }
109
-
110
- /*点击流上报
111
- * eid 事件id
112
- * kv Key-Value,自定义事件Key-Value参数对
113
- * event 事件对象
114
- * */
115
- eventClick (eid, params = {}, event) {
116
- let cookiedObj = {};
117
- // 兼容老版本事项直接传入kv值
118
- if (eid === 'MP_SHIXIANG' && !params.kv) {
119
- cookiedObj.kv = params;
120
- }
121
- else {
122
- cookiedObj = params;
123
- }
124
- this._statpid(Object.assign({
125
- et: '1000',// eventtype 事件使用1000
126
- ei: eid, // 事件id
127
- htx: event ? event.detail.x : '',
128
- hty: event ? event.detail.y : '',
129
- ht: event ? event.target.id : '',// hot tag string 屏幕的点击事件ID
130
- }, cookiedObj));
131
- }
132
-
133
- logInfo (msg, params = {}) {
134
- params.type = 'info';
135
- params.msg = msg;
136
- this._logReport(params);
137
- }
138
-
139
- logWarn (msg, params = {}) {
140
- params.type = 'warn';
141
- params.msg = msg;
142
- this._logReport(params);
143
- }
144
-
145
- logError (msg, params = {}) {
146
- params.type = 'error';
147
- params.msg = msg;
148
- this._logReport(params);
149
- }
150
-
151
- // 日志上报
152
- _logReport (params = {}) {
153
- let cookiedObj = { kv: params };
154
- this._statpid(Object.assign({
155
- et: '2000',//
156
- }, cookiedObj));
157
- }
158
-
159
- /*页面pv上报
160
- * pageId 页面标识id
161
- * params 额外参数,比如城市码
162
- * */
163
- pagePV (pageId, params = {}) {
164
- this._statpid(Object.assign({
165
- et: '3001',// eventtype,事件类型,PAGE_VIEW(1),PAGE_HIDE(3001),SESSION_ENV(2),ERROR(3),CUSTOM(1000),ADDITION(1001),MONITOR_STAT(1002);SPECIAL_CUSTON(),小程序onshow使用PAGE_VIEW,关闭或隐藏时使用PAGE_HIDE,事件使用1000å
166
- ei: pageId, // 事件id
167
- }, params));
168
- }
169
-
170
- // 设置页面参数
171
- setPagePrams (params) {
172
- let pagePath = this._getPagePath();
173
- if (pagePath && params) {
174
- this.pagePrams[pagePath] = params;
175
- }
176
- }
177
-
178
- // 是否允许上报
179
- _isAllowReport () {
180
- if (!this.config.reportUrl || !this.config.appKey) {
181
- console.error('reportUrl、appKey,存在没传的参数,不允许上报');
182
- return false;
183
- }
184
- return true;
185
- }
186
-
187
- _init () {
188
- if (this.config.stopReport || !this._isAllowReport()) return;
189
- this._spyApp();
190
- this._spyPage();
191
- if (this.config.isNet) this._network();
192
- if (this.config.isSys) this._system();
193
- }
194
-
195
- // 包装App对象
196
- _spyApp () {
197
- const _this = this;
198
- App = (app) => {
199
- const _onError = app.onError || function () { };
200
- const _onLaunch = app.onLaunch || function () { };
201
- const _onHide = app.onHide || function () { };
202
- app.onLaunch = function (opt) {
203
- _this.reportData.adt = opt.query.ysschannel || '';
204
- // _this.reportData.mp_appid = opt.referrerInfo &&
205
- // opt.referrerInfo.appId ||
206
- // '';
207
- _this.reportData.sense = opt.scene;
208
- wx.setStorageSync(_this.idxKey, 1);
209
- if (_this.config.getRemoteParamsUrl) {
210
- wx.request({
211
- url: _this.config.getRemoteParamsUrl,
212
- data: {},
213
- }).then((res) => {
214
- if (res.open) {
215
- _this.config = Object.assign(_this.config,
216
- {
217
- intervalTime: res.sec || _this.config.intervalTime,
218
- reportLogsNum: res.num || _this.config.reportLogsNum,
219
- stopReport: !!res.stop,
220
- });
221
- }
222
- });
223
- }
224
- return _onLaunch.apply(this, arguments);
225
- };
226
- if (this.config.isError) {
227
- // 错误捕获并上报
228
- app.onError = function (err) {
229
- let errspit = err.split(/\n/) || [];
230
- let src, col, line;
231
- let errs = err.match(/\(.+?\)/);
232
- if (errs && errs.length) errs = errs[0];
233
- errs = (errs || '').replace(/\w.+js/g, $1 => {
234
- src = $1;
235
- return '';
236
- });
237
- errs = errs.split(':');
238
- if (errs && errs.length > 1) line = parseInt(errs[1] || 0);
239
- col = parseInt(errs[2] || 0);
240
- _this._reportError(JSON.stringify({
241
- col: col,
242
- line: line,
243
- name: src,
244
- msg: `${errspit[0]};${errspit[1]};${errspit[2]};`,
245
- type: 'js',
246
- }));
247
- return _onError.apply(this, arguments);
248
- };
249
- }
250
- app.onHide = function () {
251
- if (_this.logTimer) {
252
- clearInterval(_this.logTimer);
253
- }
254
- _this._logRequest(true);
255
- return _onHide.apply(this, arguments);
256
- };
257
- _this.originApp(app);
258
- };
259
- }
260
-
261
- _wrapPagePV (pageOnShowTime) {
262
- const _this = this;
263
- if (_this.config.autoReportPV) {
264
- _this.pagePV(_this.config.commonPageEId,
265
- { du: Math.ceil((Date.now() - pageOnShowTime) / 1000) });
266
- }
267
- }
268
-
269
- // 包装page对象
270
- _spyPage () {
271
- const _this = this;
272
- Page = (page) => {
273
- const _onShow = page.onShow || function () { };
274
- const _onHide = page.onHide || function () { };
275
- const _onUnload = page.onUnload || function () { };
276
- let pageOnShowTime = 0;
277
- page.onShow = function () {
278
- pageOnShowTime = Date.now();
279
- if (_this.config.autoReportPV) {
280
- _this.pagePV(_this.config.commonPageEId, { et: '1' });
281
- }
282
- return _onShow.apply(this, arguments);
283
- };
284
- page.onHide = function () {
285
- _this._wrapPagePV(pageOnShowTime);
286
- return _onHide.apply(this, arguments);
287
- };
288
- page.onUnload = function () {
289
- _this._wrapPagePV(pageOnShowTime);
290
- return _onUnload.apply(this, arguments);
291
- };
292
- _this.originPage(page);
293
- };
294
-
295
- Component = (component) => {
296
- if (component._componentType === 'page') {
297
- const _this = this
298
- const _onShow = component.pageLifetimes.show || function() { }
299
- const _onHide = component.pageLifetimes.hide || function() { }
300
- let pageOnShowTime = 0
301
- component.pageLifetimes.show = function() {
302
- pageOnShowTime = Date.now()
303
- if (_this.config.autoReportPV) {
304
- _this.pagePV(_this.config.commonPageEId, { et: '1' })
305
- }
306
- return _onShow.apply(this, arguments)
307
- }
308
- component.pageLifetimes.hide = function() {
309
- _this._wrapPagePV(pageOnShowTime)
310
- return _onHide.apply(this, arguments)
311
- }
312
- }
313
- _this.originComponent(component)
314
- };
315
- }
316
-
317
- // 集中收集 logs 方法
318
- // type = 'memory' | 'storage'
319
- _collectLogs (item) {
320
- let nData = [];
321
- let oData = this.reportLogs;
322
- Array.isArray(item) ? nData = item : nData.push(item);
323
- // 剔除掉无值的字段,减少体积
324
- nData.forEach(tempItem => {
325
- for (let tempKey in tempItem) {
326
- let tempVal = tempItem[tempKey];
327
- if (tempVal === '' ||
328
- (typeof tempVal === 'object' && Object.keys(tempVal).length === 0)) {
329
- delete tempItem[tempKey];
330
- }
331
- }
332
- });
333
- // 内存不能超过 100 条
334
- let rule = oData.length > 100;
335
- if (rule) {
336
- oData.splice(0, nData.length);
337
- }
338
- this.reportLogs = oData.concat(nData);
339
- }
340
-
341
- // 获取页面路径
342
- _getPagePath () {
343
- let currentPages = getCurrentPages();
344
- if (currentPages && currentPages.length) {
345
- const length = currentPages.length;
346
- const lastpage = currentPages[length - 1];
347
- return lastpage.__route__;
348
- }
349
- else {
350
- return '';
351
- }
352
- }
353
-
354
- // 埋点上报
355
- _statpid (opt) {
356
- let currentPages = getCurrentPages();
357
- if (currentPages && currentPages.length) {
358
- const length = currentPages.length;
359
- const lastpage = currentPages[length - 1];
360
- opt.pi = lastpage.__route__;
361
- if (length >= 2) {
362
- opt.rf = currentPages[length - 2].__route__;
363
- }
364
- opt.ext = lastpage.options || {};
365
- // 合并用户传入的自定义参数
366
- opt = Object.assign(opt, this.pagePrams[opt.pi]);
367
- }
368
- let idx = Number(wx.getStorageSync(this.idxKey) || '0') + 1;
369
- wx.setStorageSync(this.idxKey, idx);
370
- opt.idx = idx;
371
- const _statpid2 = this._getCookiedReportData(opt);
372
- this._collectLogs(_statpid2);
373
- }
374
-
375
- /*错误上报
376
- * desc 错误信息
377
- * */
378
- _reportError (desc) {
379
- this._logReport({ type: 'error', msg: desc });
380
- }
381
-
382
- _getCookiedReportData (opt) {
383
- const realUserId = wx.getStorageSync('wx-openid') || wx.getStorageSync('tif-openid') ||
384
- wx.getStorageSync('openid') || opt.openid || this._getUuid();
385
- return Object.assign({}, this.reportData, {
386
- ts: Date.now(),//timestamp,时间戳
387
- ky: this.config.appKey, // app key,应用的身份标识
388
- si: wx.getStorageSync('wx-sessionid') || wx.getStorageSync('tif-sid') || this.cusSid,
389
- id: realUserId, // 平台型相关的ID字段,如微信平台中则是open_id
390
- cui: realUserId, // custom user
391
- ui: wx.getStorageSync('tif-unionid') || realUserId, // id,自定义用户id,用户上报的自定义用户id,也就是app业务方统计用户的身份标识,用于多平台帐号打通。
392
- region: wx.getStorageSync('reportRegion') || '',
393
- mp_appid: this.config.mp_appid || '',
394
- }, opt);
395
- }
396
-
397
- /*
398
- * cycle:是否循环上报
399
- * */
400
- _logRequest (cycle = false) {
401
- // 过滤掉开发者工具、测试环境的logs
402
- let _this = this;
403
- // 停止上报
404
- if (_this.config.stopReport) return;
405
- const reportLogs = _this.reportLogs;
406
- if (reportLogs.length === 0) {
407
- return;
408
- }
409
- let data = reportLogs.splice(0, _this.config.reportLogsNum);
410
- let sessionid = wx.getStorageSync('wx-sessionid') || wx.getStorageSync('tif-sid')
411
- wx.request({
412
- url: _this.config.reportUrl,
413
- header: {
414
- 'x-tif-sid': sessionid,
415
- 'x-tif-did': wx.getStorageSync('tif-did'),
416
- 'wx-sessionid': sessionid,
417
- 'content-type': 'application/x-www-form-urlencoded',
418
- },
419
- data: {reportInfo: JSON.stringify(data)},
420
- method: 'POST',
421
- complete (res) {
422
- if (cycle && res.data && Number(res.data.errcode) === 0 &&
423
- reportLogs.length > 0) {
424
- _this._logRequest(true);
425
- }
426
- if (res.data && (Number(res.data.errcode) !== 0)) {
427
- if (data && data.length !== 0) {
428
- _this._collectLogs(data);
429
- }
430
- }
431
- },
432
- });
433
- }
434
-
435
- // 获取网络类型
436
- _network () {
437
- wx.getNetworkType({
438
- success: res => {
439
- this.reportData.ev.cn = res.networkType;//connect type,设备连接方式
440
- },
441
- });
442
- }
443
-
444
- // 获取系统信息
445
- _system () {
446
- wx.getSystemInfo({
447
- success: res => {
448
- this.reportData.ev = {
449
- 'lg': res.language,//anguage,系统语言类型
450
- 'sr': res.screenWidth + '*' + res.screenHeight,//screen resolution,屏幕分辨率
451
- 'tz': new Date().getTimezoneOffset(),//time zone,系统的时区
452
- 'os': res.system,//操作系统,
453
- 'version': res.version,//微信版本号
454
- 'SDKVersion': res.SDKVersion,//客户端基础库版本
455
- 'ua': `oa=${res.system},mp_version=${res.version},mp_sdk=${res.SDKVersion}`,
456
- };
457
- },
458
- });
459
- }
460
- }