@atomicservice/ascf-toolkit-hvigor-plugin 1.0.3-beta.0 → 1.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomicservice/ascf-toolkit-hvigor-plugin",
3
- "version": "1.0.3-beta.0",
3
+ "version": "1.0.3",
4
4
  "title": "ASCF toolkit hvigor plugin for atomicservice",
5
5
  "description": "ASCF toolkit hvigor plugin for atomicservice",
6
6
  "main": "index.ts",
@@ -11,7 +11,7 @@
11
11
  "@ohos/hvigor-ohos-plugin": "5.8.9"
12
12
  },
13
13
  "dependencies": {
14
- "@atomicservice/ascf-toolkit": "1.0.3-beta.0"
14
+ "@atomicservice/ascf-toolkit": "1.0.3"
15
15
  },
16
16
  "scripts": {
17
17
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -105,7 +105,8 @@
105
105
  "@jridgewell/source-map": "0.3.2",
106
106
  "browserslist": "4.24.2",
107
107
  "resolve": "1.22.8",
108
- "terser-webpack-plugin": "5.3.7"
108
+ "terser-webpack-plugin": "5.3.7",
109
+ "@swc/types": "0.1.17"
109
110
  },
110
111
  "license": "Apache-2.0",
111
112
  "licenseFilename": "LICENSE"
@@ -0,0 +1,33 @@
1
+ export enum LogLevel {
2
+ DEBUG = 'debug',
3
+ INFO = 'info',
4
+ WARN = 'warn',
5
+ ERROR = 'error'
6
+ }
7
+ export enum DevtoolEnum {
8
+ EVAL = 'eval',
9
+ EVAL_CHEAP_SOURCE_MAP = 'eval-cheap-source-map',
10
+ EVAL_CHEAP_MODULE_SOURCE_MAP = 'eval-cheap-module-source-map',
11
+ EVAL_SOURCE_MAP = 'eval-source-map',
12
+ CHEAP_SOURCE_MAP = 'cheap-source-map',
13
+ CHEAP_MODULE_SOURCE_MAP = 'cheap-module-source-map',
14
+ SOURCE_MAP = 'source-map',
15
+ INLINE_CHEAP_SOURCE_MAP = 'inline-cheap-source-map',
16
+ INLINE_CHEAP_MODULE_SOURCE_MAP = 'inline-cheap-module-source-map',
17
+ INLINE_SOURCE_MAP = 'inline-source-map',
18
+ EVAL_NOSOURCES_CHEAP_SOURCE_MAP = 'eval-nosources-cheap-source-map',
19
+ EVAL_NOSOURCES_CHEAP_MODULE_SOURCE_MAP = 'eval-nosources-cheap-module-source-map',
20
+ EVAL_NOSOURCES_SOURCE_MAP = 'eval-nosources-source-map',
21
+ INLINE_NOSOURCES_CHEAP_SOURCE_MAP = 'inline-nosources-cheap-source-map',
22
+ INLINE_NOSOURCES_CHEAP_MODULE_SOURCE_MAP = 'inline-nosources-cheap-module-source-map',
23
+ INLINE_NOSOURCES_SOURCE_MAP = 'inline-nosources-source-map',
24
+ NOSOURCES_CHEAP_SOURCE_MAP = 'nosources-cheap-source-map',
25
+ NOSOURCES_CHEAP_MODULE_SOURCE_MAP = 'nosources-cheap-module-source-map',
26
+ NOSOURCES_SOURCE_MAP = 'nosources-source-map',
27
+ HIDDEN_NOSOURCES_CHEAP_SOURCE_MAP = 'hidden-nosources-cheap-source-map',
28
+ HIDDEN_NOSOURCES_CHEAP_MODULE_SOURCE_MAP = 'hidden-nosources-cheap-module-source-map',
29
+ HIDDEN_NOSOURCES_SOURCE_MAP = 'hidden-nosources-source-map',
30
+ HIDDEN_CHEAP_SOURCE_MAP = 'hidden-cheap-source-map',
31
+ HIDDEN_CHEAP_MODULE_SOURCE_MAP = 'hidden-cheap-module-source-map',
32
+ HIDDEN_SOURCE_MAP = 'hidden-source-map',
33
+ }
@@ -0,0 +1,26 @@
1
+ type DeepPartial<T> = {
2
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
3
+ };
4
+
5
+ function deepMerge<T extends object>(target: T, source?: DeepPartial<T>): T {
6
+ if (!source) {
7
+ return target;
8
+ }
9
+ for (const key of Object.keys(source) as Array<keyof T>) {
10
+ const sourceValue = source[key];
11
+ const targetValue = target[key];
12
+
13
+ if (isObject(sourceValue) && key in target && isObject(targetValue)) {
14
+ deepMerge(targetValue as Object, sourceValue as DeepPartial<typeof targetValue>);
15
+ } else {
16
+ target[key] = sourceValue as T[keyof T];
17
+ }
18
+ }
19
+ return target;
20
+ }
21
+
22
+ function isObject(target: any) {
23
+ return Object.prototype.toString.call(target) === '[object Object]';
24
+ }
25
+
26
+ export { deepMerge };
package/src/config.json CHANGED
@@ -1,3 +1,4 @@
1
1
  {
2
- "ascfHspUrl": "https://h5hosting-drcn.dbankcdn.cn/cch5/wallet/ascf-cn/ascfHsp.html?auto=1"
2
+ "ascfHspUrl": "https://h5hosting-drcn.dbankcdn.cn/cch5/wallet/ascf-cn/ascfHsp.html?auto=1",
3
+ "ascfRuntimeHspUrl": "https://h5hosting-drcn.dbankcdn.cn/cch5/wallet/ascf-cn/ascfRuntimeHsp.html?auto=1"
3
4
  }
@@ -1,11 +1,14 @@
1
- import { OhosAppContext, OhosPluginId } from '@ohos/hvigor-ohos-plugin';
1
+ import {OhosAppContext, OhosHapContext, OhosPluginId} from '@ohos/hvigor-ohos-plugin';
2
2
  import { Property } from '@ohos/hvigor-ohos-plugin/src/sdk/lib/property-get';
3
3
  import { PropertyConst } from '@ohos/hvigor-ohos-plugin/src/const/property-const';
4
- import { hvigor, HvigorLogger, HvigorNode, HvigorPlugin } from '@ohos/hvigor';
4
+ import { hvigor, HvigorLogger, HvigorNode, HvigorPlugin, Level } from '@ohos/hvigor';
5
5
  import ascf from '@atomicservice/ascf-toolkit';
6
6
  import { exec } from 'child_process';
7
7
  import path from 'path';
8
+ import fs from 'fs';
8
9
  import os from 'os';
10
+ import { DevtoolEnum, LogLevel } from '../common/common-enum';
11
+ import { deepMerge } from '../common/common-utils';
9
12
 
10
13
  import { doModifyShareInfoPlugin } from './modifyShareInfoPlugin';
11
14
  import { doInstallAscfHspPlugin } from './installAscfHspPlugin';
@@ -13,23 +16,30 @@ import { doInstallAscfHspPlugin } from './installAscfHspPlugin';
13
16
  const logger = HvigorLogger.getLogger('ascfPlugin');
14
17
 
15
18
  export interface AscfPluginOptions {
16
- fixSharedHsp: true,
17
- installAscfHsp: true,
18
- debug: true,
19
+ fixSharedHsp: boolean,
20
+ installAscfHsp: boolean,
21
+ debug: boolean,
22
+ logging?: LogLevel,
23
+ devtool?: DevtoolEnum,
24
+ compilerOptions: {
25
+ swc: boolean,
26
+ }
19
27
  }
20
28
 
21
29
  const DEFAULT_OPTIONS: AscfPluginOptions = {
22
30
  fixSharedHsp: true,
23
31
  installAscfHsp: true,
24
32
  debug: true,
33
+ compilerOptions: {
34
+ swc: false,
35
+ }
25
36
  };
26
37
 
27
- export default function ascfToolkitHvigorPlugin(options: AscfPluginOptions): HvigorPlugin {
38
+ export default function ascfToolkitHvigorPlugin(options?: AscfPluginOptions): HvigorPlugin {
28
39
  return {
29
40
  pluginId: 'ascfToolkitHvigorPlugin',
30
41
  apply(node: HvigorNode) {
31
- const opts = Object.assign({}, DEFAULT_OPTIONS, options);
32
-
42
+ const opts = deepMerge(DEFAULT_OPTIONS, options);
33
43
  hvigor.nodesEvaluated(async () => {
34
44
  await execPlugin(opts, node);
35
45
 
@@ -42,19 +52,48 @@ export default function ascfToolkitHvigorPlugin(options: AscfPluginOptions): Hvi
42
52
  },
43
53
  });
44
54
  } else {
45
- logger.debug('start exec ascf compile');
55
+ logger.debug('start exec ascf quickGenSub');
56
+ await ascf.quickGenerateSubpackage();
57
+ logger.debug('ascf quickGenSub completed');
46
58
  const appContext = node.getContext(OhosPluginId.OHOS_APP_PLUGIN) as OhosAppContext;
47
- const buildMode = appContext.getBuildMode();
48
- const nodeExe = getNodeExe();
49
- const ascfScript = getAscfScript();
50
- let cmd = `\"${nodeExe}\" \"${ascfScript}\" compile -c ${buildMode === 'debug' ? '-m' : ''} ${appContext.getProjectPath()}`;
51
-
52
- if (opts.debug && logger.getLevel().levelStr === 'DEBUG') {
53
- cmd += ' --debug';
54
- }
59
+ node.subNodes((subNode: HvigorNode) => {
60
+ const hapContext = subNode.getContext(OhosPluginId.OHOS_HAP_PLUGIN) as OhosHapContext;
61
+ if(hapContext && hapContext.getModuleType() === 'entry') {
62
+ subNode.registerTask({
63
+ // 任务名称
64
+ name: 'quickGenerateSubpackage',
65
+ // 任务执行逻辑主体函数
66
+ async run() {
67
+ logger.debug('start exec ascf compile');
68
+ const buildMode = appContext.getBuildMode();
69
+ const nodeExe = getNodeExe();
70
+ const ascfScript = getAscfScript();
71
+ let cmd = `${nodeExe} ${ascfScript} compile -c ${buildMode === 'debug' ? '-m' : ''} ${appContext.getProjectPath()}`;
55
72
 
56
- await executeCommand(cmd);
57
- logger.debug('ascf compile completed');
73
+ const hvigorLevelStr = (logger.getLevel() as Level).levelStr.toLowerCase();
74
+ if (opts.debug && hvigorLevelStr === LogLevel.DEBUG) {
75
+ cmd += ' --debug';
76
+ }
77
+ if (opts.compilerOptions.swc) {
78
+ cmd += ' --swc';
79
+ }
80
+ const devtool = opts.devtool?.toLowerCase();
81
+ if (devtool) {
82
+ cmd += ` --devtool=${devtool}`;
83
+ }
84
+ const logLevel = (opts.logging ? opts.logging : hvigorLevelStr).toLowerCase();
85
+ cmd += ` --logging=${logLevel}`;
86
+ logger.debug(cmd);
87
+ await executeCommand(cmd, hvigorLevelStr);
88
+ logger.debug('ascf compile completed');
89
+ },
90
+ // 配置前置任务依赖
91
+ dependencies: ['default@PreBuild'],
92
+ // 配置任务的后置任务依赖
93
+ postDependencies: ['assembleHap']
94
+ });
95
+ }
96
+ });
58
97
  }
59
98
  } catch (err: any) {
60
99
  logger.errorExit(new Error(err));
@@ -74,33 +113,53 @@ async function execPlugin(opts: AscfPluginOptions, node: HvigorNode) {
74
113
  }
75
114
  }
76
115
 
77
- function executeCommand(command: string) {
116
+ function executeCommand(command: string, levelStr: string) {
78
117
  return new Promise((resolve, reject) => {
79
- exec(command, (error: any, stdout: any, stderr: string) => {
118
+ exec(command, (error: any, stdout: string, stderr: string) => {
119
+ printLogger(stdout, levelStr);
80
120
  if (error) {
81
121
  reject(error);
82
122
  } else {
83
- logger.debug(stderr);
84
- logger.debug(stdout);
85
- resolve(stderr);
123
+ resolve(stdout);
86
124
  }
87
125
  });
88
126
  });
89
127
  }
90
128
 
129
+ function printLogger(stdout: string, levelStr: string) {
130
+ if (stdout.length === 0) {
131
+ return;
132
+ }
133
+ if (levelStr === LogLevel.INFO) {
134
+ logger.info(stdout);
135
+ } else if (levelStr === LogLevel.WARN) {
136
+ logger.warn(stdout);
137
+ } else if (levelStr === LogLevel.ERROR) {
138
+ logger.error(stdout);
139
+ } else {
140
+ logger.debug(stdout);
141
+ }
142
+ }
143
+
91
144
  function getNodeExe() {
92
145
  const property: Property = new Property();
93
146
  const nodeDir = property.getProperty(PropertyConst.NPM_DIR);
94
147
  const platform = os.platform();
148
+ let got = 'node';
149
+
95
150
  if (platform === 'win32') {
96
- return path.join(nodeDir, 'node.exe');
151
+ got = path.join(nodeDir, 'node.exe');
97
152
  } else if (platform === 'darwin' || platform === 'linux') {
98
- return path.join(nodeDir, 'node');
99
- } else {
100
- return 'node';
153
+ got = path.join(nodeDir, 'node');
101
154
  }
155
+
156
+ return fs.existsSync(got) ? adjustPathByPlatform(got) : 'node';
102
157
  }
103
158
 
104
159
  function getAscfScript() {
105
- return path.join(ascf.getAscfToolkitDirname(), 'bin', 'ascf.js');
160
+ return adjustPathByPlatform(path.join(ascf.getAscfToolkitDirname(), 'bin', 'ascf.js'));
161
+ }
162
+
163
+ function adjustPathByPlatform(path: string) {
164
+ return os.platform() === 'win32' ? `\"${path}\"` : path;
106
165
  }
@@ -5,7 +5,7 @@ import { execSync } from 'child_process';
5
5
  import path from 'path';
6
6
  import fs from 'fs';
7
7
 
8
- const logger = HvigorLogger.getLogger('modifyShareInfoPlugin');
8
+ const logger = HvigorLogger.getLogger('installAscfHspPlugin');
9
9
 
10
10
  function execSafe(cmd: string) {
11
11
  try {
@@ -15,40 +15,58 @@ function execSafe(cmd: string) {
15
15
  }
16
16
  }
17
17
 
18
- const BUNDLE_NAME_ASCF = 'com.huawei.hms.ascfruntime';
19
- const ERR_MSG = `${BUNDLE_NAME_ASCF} install failed, please open helloUniapp manually.`;
18
+ function checkProjectAscfVer() {
19
+ logger.debug(`Check project ascf dependency version.`);
20
+ const node = hvigor.getNodeByName('entry');
21
+ let ohPkgFile = path.resolve(node?.getNodePath(), './oh-package.json');
22
+ if (!fs.existsSync(ohPkgFile)) {
23
+ ohPkgFile += '5'; // trying module.json5
24
+ if (!fs.existsSync(ohPkgFile)) {
25
+ logger.warn(`Check oh-package failed. Not found ${ohPkgFile}.`);
26
+ return false;
27
+ }
28
+ }
29
+ const ohPkgDeps = JSON.parse(fs.readFileSync(ohPkgFile).toString())?.dependencies;
30
+ logger.debug(`ohPkgDeps: ${JSON.stringify(ohPkgDeps)}`);
31
+ return !!Object.prototype.hasOwnProperty.call(ohPkgDeps, '@atomicservice/ascf');
32
+ }
20
33
 
21
- function checkAscfHsp() {
22
- logger.debug(`Check and install ${BUNDLE_NAME_ASCF} for local development`);
23
- const sharedInfo = execSafe(`hdc shell bm dump-shared -a`);
24
- if (sharedInfo?.includes(BUNDLE_NAME_ASCF)) {
25
- const verInfo = execSafe(`hdc shell "bm dump-shared -n ${BUNDLE_NAME_ASCF} | grep versionName"`);
26
- logger.debug(`found ${BUNDLE_NAME_ASCF} ${verInfo}`);
34
+ function checkAscfHsp(ascfBundleName: string) {
35
+ logger.debug(`Check and install ${ascfBundleName} for local development`);
36
+ const sharedInfo: string = execSafe(`hdc shell bm dump-shared -a`) ?? '';
37
+ if (new RegExp(`${ascfBundleName}(\\r?\\n|$)`).test(sharedInfo)) {
38
+ const verInfo = execSafe(`hdc shell "bm dump-shared -n ${ascfBundleName} | grep versionName"`);
39
+ logger.debug(`found ${ascfBundleName} ${verInfo}`);
27
40
  return true;
28
41
  }
29
42
  return false;
30
43
  }
31
44
 
32
45
  function doInstallAscfHsp(resolve: any, reject: any) {
33
- if (checkAscfHsp()) {
46
+ const isDepOldAscf: boolean = checkProjectAscfVer();
47
+ const ascfBundleName: string = isDepOldAscf ? 'com.huawei.hms.ascf' : 'com.huawei.hms.ascfruntime';
48
+ const errMsg: string = `${ascfBundleName} install failed, please open helloUniapp manually.`;
49
+
50
+ if (checkAscfHsp(ascfBundleName)) {
34
51
  resolve();
35
52
  return;
36
53
  }
37
54
 
38
- logger.debug(`trying to install ${BUNDLE_NAME_ASCF}`);
55
+ logger.debug(`trying to install ${ascfBundleName}`);
39
56
  const configJsonPath = path.resolve(__dirname, '../config.json');
40
57
  const configJson = JSON.parse(fs.readFileSync(configJsonPath).toString());
41
- const startInfo = execSafe(`hdc shell aa start -b com.huawei.hmos.browser -a MainAbility -A ohos.want.action.viewData -U "${configJson.ascfHspUrl}"`);
58
+ const hspUrl = isDepOldAscf ? configJson.ascfHspUrl : configJson.ascfRuntimeHspUrl;
59
+ const startInfo = execSafe(`hdc shell aa start -b com.huawei.hmos.browser -a MainAbility -A ohos.want.action.viewData -U "${hspUrl}"`);
42
60
  if (!startInfo?.includes('successfully')) {
43
- logger.warn(`${ERR_MSG} errorInfo=${startInfo}`);
44
- reject(ERR_MSG);
61
+ logger.warn(`${errMsg} errorInfo=${startInfo}`);
62
+ reject(errMsg);
45
63
  return;
46
64
  }
47
65
 
48
66
  logger.debug(`begin to wait install hsp`);
49
67
  let needWait = 0;
50
68
  let timer = setInterval(() => {
51
- const found = checkAscfHsp();
69
+ const found = checkAscfHsp(ascfBundleName);
52
70
  needWait++;
53
71
 
54
72
  if (found || needWait > 5) {
@@ -56,8 +74,8 @@ function doInstallAscfHsp(resolve: any, reject: any) {
56
74
  if (found) {
57
75
  resolve();
58
76
  } else {
59
- logger.warn(ERR_MSG);
60
- reject(ERR_MSG);
77
+ logger.warn(errMsg);
78
+ reject(errMsg);
61
79
  }
62
80
  return;
63
81
  }