@cityholdings/minicube-dev 0.1.2 → 0.1.4

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/README.md CHANGED
@@ -36,8 +36,13 @@ npm publish
36
36
 
37
37
  Optional tools, used only by the commands that need them: `adb` (Android preview), Xcode
38
38
  command-line tools (`xcrun`, iOS simulator/device preview), `kubectl` (token administration or
39
- `transport: "kube"`), `cube-pack` (inline card images), and the mini program compiler
40
- `mini-pkg-builder`.
39
+ `transport: "kube"`), `cube-pack` (inline card images), and the official mPaaS mini program IDE
40
+ (`mPaaS小程序开发者工具`).
41
+
42
+ Mini programs are compiled with the IDE's own `mini-pkg-builder` (and its `esbuild`), found
43
+ automatically in the default install locations: `/Applications` or `~/Applications` on macOS;
44
+ `%LOCALAPPDATA%\Programs`, `%ProgramFiles%` or the installer's recorded folder on Windows. No
45
+ configuration is needed; `builders.mini` / `MINICUBE_MINI_BUILDER` only override it.
41
46
 
42
47
  Card projects must install ACT v4 themselves (`npm i -D @antdigital/cube@4`). minicube-dev uses only
43
48
  that copy, found from the card directory upwards, and stops if it is missing or older than v4; a
@@ -63,16 +68,15 @@ by `MINICUBE_DEV_CONFIG` / `--config`. Create a skeleton with `minicube-dev conf
63
68
  "devices": {
64
69
  "android": { "package": "<android application id>", "cubeConnectActivity": "<debug activity accepting cubeActHost/cubeActPort>" },
65
70
  "ios": { "bundleId": "<bundle id, physical devices only>" }
66
- },
67
- "builders": { "mini": "/path/to/mini-pkg-builder" }
71
+ }
68
72
  }
69
73
  ```
70
74
 
71
75
  * `token` or `tokenEnv` (name of an environment variable holding it) per environment.
72
76
  * Without `baseUrl` (or with `"transport": "kube"`) requests go through `kubectl port-forward`
73
77
  using your local kubeconfig.
74
- * `builders.mini` is the mini-pkg-builder executable (`mini-pkg-builder-macos-arm64`,
75
- `mini-pkg-builder-win-x64.exe`, …) or its runtime `index.js`; `MINICUBE_MINI_BUILDER` overrides it.
78
+ * Optional `"builders": { "mini": "<path>" }` (or `MINICUBE_MINI_BUILDER`) points at another
79
+ mini-pkg-builder executable or runtime `index.js`, e.g. when the IDE is installed elsewhere.
76
80
 
77
81
  `minicube-dev doctor` checks the toolchain and every environment's token.
78
82
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cityholdings/minicube-dev",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Command-line workflow for mPaaS mini programs, H5 offline packages and Cube cards: build, debug upload, device preview and release",
5
5
  "type": "module",
6
6
  "bin": {
package/src/build.js CHANGED
@@ -3,7 +3,7 @@ import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, statSync, writeFil
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { CliError, log } from './log.js';
6
- import { run, which } from './proc.js';
6
+ import { run, runSync, which } from './proc.js';
7
7
  import { listFiles, zipDirectory } from './zip.js';
8
8
 
9
9
  export const OUT_DIR = '.minicube';
@@ -39,19 +39,73 @@ function ensureGitIgnored(root) {
39
39
  const MINI_REQUIRED_OUTPUTS = ['appConfig.json', 'index.html', 'index.js', 'index.worker.js', 'manifest.json'];
40
40
  const MINI_SOURCE_EXCLUDES = new Set([OUT_DIR, '.git', '.idea', '.vscode', '.DS_Store']);
41
41
 
42
+ const IDE_NAME = 'mPaaS小程序开发者工具';
43
+
44
+ /** Where the official mPaaS mini program IDE keeps its compiler (`<app>/builder/`). */
45
+ export function ideBuilderDirs(platform = process.platform, env = process.env, home = os.homedir()) {
46
+ if (platform === 'darwin') {
47
+ return ['/Applications', path.join(home, 'Applications')].map((dir) =>
48
+ path.join(dir, `${IDE_NAME}.app`, 'Contents', 'Resources', 'app', 'builder'));
49
+ }
50
+ if (platform === 'win32') {
51
+ const roots = [
52
+ env.LOCALAPPDATA && path.win32.join(env.LOCALAPPDATA, 'Programs'),
53
+ env.ProgramFiles,
54
+ env['ProgramFiles(x86)'],
55
+ ].filter(Boolean);
56
+ return [...roots.map((root) => path.win32.join(root, IDE_NAME)), ...windowsInstallLocations()]
57
+ .map((dir) => path.win32.join(dir, 'resources', 'app', 'builder'));
58
+ }
59
+ return [];
60
+ }
61
+
62
+ /** Install folders of the IDE recorded by its Windows installer (covers custom locations). */
63
+ function windowsInstallLocations() {
64
+ const found = [];
65
+ for (const hive of ['HKCU', 'HKLM']) {
66
+ try {
67
+ const { code, stdout } = runSync('reg', ['query', `${hive}\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall`, '/s', '/f', IDE_NAME, '/d']);
68
+ if (code !== 0) continue;
69
+ for (const key of stdout.split(/\r?\n/).filter((line) => line.startsWith('HKEY_'))) {
70
+ const value = runSync('reg', ['query', key, '/v', 'InstallLocation']).stdout.match(/InstallLocation\s+REG_\w+\s+(.+)/);
71
+ if (value) found.push(value[1].trim().replace(/^"|"$/g, ''));
72
+ }
73
+ } catch {
74
+ // reg.exe unavailable: fall back to the default folders
75
+ }
76
+ }
77
+ return found;
78
+ }
79
+
80
+ /**
81
+ * The mini program compiler: MINICUBE_MINI_BUILDER, then builders.mini in the config, then the
82
+ * copy inside an installed mPaaS mini program IDE. `env` carries the IDE's esbuild, which the
83
+ * compiler (like the IDE) finds through ESBUILD_BINARY_PATH.
84
+ */
42
85
  export function resolveMiniBuilder(globalConfig) {
43
86
  const configured = process.env.MINICUBE_MINI_BUILDER ?? globalConfig.data.builders?.mini;
44
- if (!configured || String(configured).includes('<')) {
45
- throw new CliError(
46
- 'No mini program builder configured',
47
- 'Set builders.mini in the minicube-dev config to the mini-pkg-builder executable (or its runtime index.js), or export MINICUBE_MINI_BUILDER.',
48
- );
87
+ if (configured && !String(configured).includes('<')) {
88
+ const resolved = which(String(configured)) ?? path.resolve(String(configured));
89
+ if (!existsSync(resolved)) throw new CliError(`Mini program builder not found: ${resolved}`);
90
+ return builderAt(resolved);
49
91
  }
50
- const resolved = which(String(configured)) ?? path.resolve(String(configured));
51
- if (!existsSync(resolved)) throw new CliError(`Mini program builder not found: ${resolved}`);
52
- return resolved.endsWith('.js') || resolved.endsWith('.mjs')
53
- ? { command: process.execPath, prefix: [resolved] }
54
- : { command: resolved, prefix: [] };
92
+ const exe = process.platform === 'win32' ? '.exe' : '';
93
+ for (const dir of ideBuilderDirs()) {
94
+ const file = path.join(dir, `mini-pkg-builder${exe}`);
95
+ if (existsSync(file)) return builderAt(file);
96
+ }
97
+ throw new CliError(
98
+ 'No mini program builder found',
99
+ `Install the mPaaS mini program IDE (${IDE_NAME}), or set builders.mini in the minicube-dev config / MINICUBE_MINI_BUILDER to a mini-pkg-builder executable.`,
100
+ );
101
+ }
102
+
103
+ function builderAt(file) {
104
+ const esbuild = path.join(path.dirname(file), process.platform === 'win32' ? 'esbuild.exe' : 'esbuild');
105
+ const env = existsSync(esbuild) && !process.env.ESBUILD_BINARY_PATH ? { ESBUILD_BINARY_PATH: esbuild } : {};
106
+ return file.endsWith('.js') || file.endsWith('.mjs')
107
+ ? { command: process.execPath, prefix: [file], path: file, env }
108
+ : { command: file, prefix: [], path: file, env };
55
109
  }
56
110
 
57
111
  function readMiniProjectConfig(sourceDir) {
@@ -84,11 +138,14 @@ async function buildMini(project, globalConfig, outRoot) {
84
138
  '--target', 'web', '--mode', 'concurrent', '--no-vuerender', '--zrender', '--rmlrender',
85
139
  '--external', 'appx', '--appxcompatible', 'tiny',
86
140
  '--project-config-json', encodeURIComponent(JSON.stringify(projectConfig)),
87
- '--prod', '--no-minify',
141
+ // Matches the mPaaS cloud build output (compared module by module): no --prod (no module
142
+ // concatenation, hashed module ids, no minify), shared sub-packages, host code placeholders.
143
+ '--force-sub-package-build-type-shared', '--output-code-placeholder', '--output-html-placeholder',
88
144
  ];
89
145
  log.step(`Compiling mini program ${id}`);
146
+ log.detail(`Compiler ${builder.path}`);
90
147
  const logFile = path.join(outRoot, 'mini-build.log');
91
- const result = await run(builder.command, args, { cwd: input, capture: true, env: { FORCE_COLOR: '0', NO_COLOR: '1' } });
148
+ const result = await run(builder.command, args, { cwd: input, capture: true, env: { ...builder.env, FORCE_COLOR: '0', NO_COLOR: '1' } });
92
149
  writeFileSync(logFile, `${result.stdout}\n${result.stderr}`);
93
150
  rmSync(work, { recursive: true, force: true });
94
151
  if (result.code !== 0) {
package/src/cli.js CHANGED
@@ -385,7 +385,7 @@ const COMMANDS = {
385
385
  const config = loadGlobalConfig(ctx.flags);
386
386
  add('config', config.exists, config.file);
387
387
  try {
388
- add('mini builder', true, resolveMiniBuilder(config).prefix[0] ?? resolveMiniBuilder(config).command);
388
+ add('mini builder', true, resolveMiniBuilder(config).path);
389
389
  } catch (e) {
390
390
  add('mini builder', false, e.message);
391
391
  }
package/src/config.js CHANGED
@@ -58,9 +58,6 @@ export const CONFIG_TEMPLATE = {
58
58
  bundleId: '<ios bundle id>',
59
59
  },
60
60
  },
61
- builders: {
62
- mini: '<path to mini-pkg-builder executable or its runtime index.js>',
63
- },
64
61
  };
65
62
 
66
63
  /**