react-native-update-cli 2.7.2 → 2.7.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/cli.json +0 -1
- package/lib/bundle.js +20 -6
- package/package.json +2 -19
- package/src/bundle.ts +19 -9
- package/lib/esm/api..mjs +0 -183
- package/lib/esm/app..mjs +0 -130
- package/lib/esm/bundle..mjs +0 -823
- package/lib/esm/exports..mjs +0 -11
- package/lib/esm/index..mjs +0 -122
- package/lib/esm/install..mjs +0 -18
- package/lib/esm/locales/en..mjs +0 -131
- package/lib/esm/locales/zh..mjs +0 -130
- package/lib/esm/module-manager..mjs +0 -109
- package/lib/esm/modules/app-module..mjs +0 -213
- package/lib/esm/modules/bundle-module..mjs +0 -178
- package/lib/esm/modules/index..mjs +0 -17
- package/lib/esm/modules/package-module..mjs +0 -6
- package/lib/esm/modules/user-module..mjs +0 -351
- package/lib/esm/modules/version-module..mjs +0 -6
- package/lib/esm/package..mjs +0 -316
- package/lib/esm/provider..mjs +0 -293
- package/lib/esm/types..mjs +0 -1
- package/lib/esm/user..mjs +0 -36
- package/lib/esm/utils/add-gitignore..mjs +0 -32
- package/lib/esm/utils/app-info-parser/aab..mjs +0 -215
- package/lib/esm/utils/app-info-parser/apk..mjs +0 -75
- package/lib/esm/utils/app-info-parser/app..mjs +0 -3
- package/lib/esm/utils/app-info-parser/index..mjs +0 -44
- package/lib/esm/utils/app-info-parser/ipa..mjs +0 -73
- package/lib/esm/utils/app-info-parser/resource-finder..mjs +0 -401
- package/lib/esm/utils/app-info-parser/utils..mjs +0 -121
- package/lib/esm/utils/app-info-parser/xml-parser/binary..mjs +0 -569
- package/lib/esm/utils/app-info-parser/xml-parser/manifest..mjs +0 -200
- package/lib/esm/utils/app-info-parser/zip..mjs +0 -65
- package/lib/esm/utils/check-lockfile..mjs +0 -78
- package/lib/esm/utils/check-plugin..mjs +0 -25
- package/lib/esm/utils/constants..mjs +0 -19
- package/lib/esm/utils/dep-versions..mjs +0 -33
- package/lib/esm/utils/git..mjs +0 -43
- package/lib/esm/utils/http-helper..mjs +0 -70
- package/lib/esm/utils/i18n..mjs +0 -23
- package/lib/esm/utils/index..mjs +0 -316
- package/lib/esm/utils/latest-version/cli..mjs +0 -294
- package/lib/esm/utils/latest-version/index..mjs +0 -238
- package/lib/esm/utils/plugin-config..mjs +0 -23
- package/lib/esm/versions..mjs +0 -290
package/lib/esm/bundle..mjs
DELETED
|
@@ -1,823 +0,0 @@
|
|
|
1
|
-
import { spawn, spawnSync } from "child_process";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { satisfies } from "compare-versions";
|
|
4
|
-
import * as fs from "fs-extra";
|
|
5
|
-
import { open as openZipFile } from "yauzl";
|
|
6
|
-
import { ZipFile as YazlZipFile } from "yazl";
|
|
7
|
-
import { getPlatform } from "./app";
|
|
8
|
-
import { translateOptions } from "./utils";
|
|
9
|
-
import { checkPlugins, question } from "./utils";
|
|
10
|
-
const g2js = require('gradle-to-js/lib/parser');
|
|
11
|
-
import os from "os";
|
|
12
|
-
const properties = require('properties');
|
|
13
|
-
import { addGitIgnore } from "./utils/add-gitignore";
|
|
14
|
-
import { checkLockFiles } from "./utils/check-lockfile";
|
|
15
|
-
import { isPPKBundleFileName, scriptName, tempDir } from "./utils/constants";
|
|
16
|
-
import { depVersions } from "./utils/dep-versions";
|
|
17
|
-
import { t } from "./utils/i18n";
|
|
18
|
-
import { versionCommands } from "./versions";
|
|
19
|
-
let bsdiff;
|
|
20
|
-
let hdiff;
|
|
21
|
-
let diff;
|
|
22
|
-
try {
|
|
23
|
-
bsdiff = require('node-bsdiff').diff;
|
|
24
|
-
} catch (e) {}
|
|
25
|
-
try {
|
|
26
|
-
hdiff = require('node-hdiffpatch').diff;
|
|
27
|
-
} catch (e) {}
|
|
28
|
-
async function runReactNativeBundleCommand({ bundleName, dev, entryFile, outputFolder, platform, sourcemapOutput, config, forceHermes, cli }) {
|
|
29
|
-
let gradleConfig = {};
|
|
30
|
-
if (platform === 'android') {
|
|
31
|
-
gradleConfig = await checkGradleConfig();
|
|
32
|
-
if (gradleConfig.crunchPngs !== false) {
|
|
33
|
-
console.warn(t('androidCrunchPngsWarning'));
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
const reactNativeBundleArgs = [];
|
|
37
|
-
const envArgs = process.env.PUSHY_ENV_ARGS;
|
|
38
|
-
if (envArgs) {
|
|
39
|
-
reactNativeBundleArgs.push(...envArgs.trim().split(/\s+/));
|
|
40
|
-
}
|
|
41
|
-
fs.emptyDirSync(outputFolder);
|
|
42
|
-
let cliPath = '';
|
|
43
|
-
let usingExpo = false;
|
|
44
|
-
const getExpoCli = ()=>{
|
|
45
|
-
try {
|
|
46
|
-
const searchPaths = [
|
|
47
|
-
process.cwd()
|
|
48
|
-
];
|
|
49
|
-
// 尝试添加 expo 包的路径作为额外的搜索路径
|
|
50
|
-
try {
|
|
51
|
-
const expoPath = require.resolve('expo/package.json', {
|
|
52
|
-
paths: [
|
|
53
|
-
process.cwd()
|
|
54
|
-
]
|
|
55
|
-
});
|
|
56
|
-
// 获取 expo 包的目录路径
|
|
57
|
-
const expoDir = expoPath.replace(/\/package\.json$/, '');
|
|
58
|
-
searchPaths.push(expoDir);
|
|
59
|
-
} catch (e) {
|
|
60
|
-
// expo 包不存在,忽略
|
|
61
|
-
}
|
|
62
|
-
// 尝试从搜索路径中解析 @expo/cli
|
|
63
|
-
cliPath = require.resolve('@expo/cli', {
|
|
64
|
-
paths: searchPaths
|
|
65
|
-
});
|
|
66
|
-
const expoCliVersion = JSON.parse(fs.readFileSync(require.resolve('@expo/cli/package.json', {
|
|
67
|
-
paths: searchPaths
|
|
68
|
-
})).toString()).version;
|
|
69
|
-
// expo cli 0.10.17 (expo 49) 开始支持 bundle:embed
|
|
70
|
-
if (satisfies(expoCliVersion, '>= 0.10.17')) {
|
|
71
|
-
usingExpo = true;
|
|
72
|
-
} else {
|
|
73
|
-
cliPath = '';
|
|
74
|
-
}
|
|
75
|
-
} catch (e) {}
|
|
76
|
-
};
|
|
77
|
-
const getRnCli = ()=>{
|
|
78
|
-
try {
|
|
79
|
-
// rn < 0.75
|
|
80
|
-
cliPath = require.resolve('react-native/local-cli/cli.js', {
|
|
81
|
-
paths: [
|
|
82
|
-
process.cwd()
|
|
83
|
-
]
|
|
84
|
-
});
|
|
85
|
-
} catch (e) {
|
|
86
|
-
// rn >= 0.75
|
|
87
|
-
cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
|
|
88
|
-
paths: [
|
|
89
|
-
process.cwd()
|
|
90
|
-
]
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
const getTaroCli = ()=>{
|
|
95
|
-
try {
|
|
96
|
-
cliPath = require.resolve('@tarojs/cli/bin/taro', {
|
|
97
|
-
paths: [
|
|
98
|
-
process.cwd()
|
|
99
|
-
]
|
|
100
|
-
});
|
|
101
|
-
} catch (e) {}
|
|
102
|
-
};
|
|
103
|
-
if (cli.expo) {
|
|
104
|
-
getExpoCli();
|
|
105
|
-
} else if (cli.taro) {
|
|
106
|
-
getTaroCli();
|
|
107
|
-
} else if (cli.rncli) {
|
|
108
|
-
getRnCli();
|
|
109
|
-
}
|
|
110
|
-
if (!cliPath) {
|
|
111
|
-
getExpoCli();
|
|
112
|
-
if (!usingExpo) {
|
|
113
|
-
getRnCli();
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const bundleParams = await checkPlugins();
|
|
117
|
-
const isSentry = bundleParams.sentry;
|
|
118
|
-
if (isSentry) {
|
|
119
|
-
if (platform === 'ios') {
|
|
120
|
-
process.env.SENTRY_PROPERTIES = 'ios/sentry.properties';
|
|
121
|
-
} else if (platform === 'android') {
|
|
122
|
-
process.env.SENTRY_PROPERTIES = 'android/sentry.properties';
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
let bundleCommand = 'bundle';
|
|
126
|
-
if (usingExpo) {
|
|
127
|
-
bundleCommand = 'export:embed';
|
|
128
|
-
} else if (platform === 'harmony') {
|
|
129
|
-
bundleCommand = 'bundle-harmony';
|
|
130
|
-
} else if (cli.taro) {
|
|
131
|
-
bundleCommand = 'build';
|
|
132
|
-
}
|
|
133
|
-
if (platform === 'harmony') {
|
|
134
|
-
bundleName = 'bundle.harmony.js';
|
|
135
|
-
if (forceHermes === undefined) {
|
|
136
|
-
// enable hermes by default for harmony
|
|
137
|
-
forceHermes = true;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
reactNativeBundleArgs.push(cliPath, bundleCommand, '--assets-dest', outputFolder, '--bundle-output', path.join(outputFolder, bundleName));
|
|
141
|
-
if (platform !== 'harmony') {
|
|
142
|
-
reactNativeBundleArgs.push('--platform', platform, '--reset-cache');
|
|
143
|
-
}
|
|
144
|
-
if (cli.taro) {
|
|
145
|
-
reactNativeBundleArgs.push('--type', 'rn');
|
|
146
|
-
} else {
|
|
147
|
-
reactNativeBundleArgs.push('--dev', dev, '--entry-file', entryFile);
|
|
148
|
-
}
|
|
149
|
-
if (sourcemapOutput) {
|
|
150
|
-
reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
|
|
151
|
-
}
|
|
152
|
-
if (config) {
|
|
153
|
-
reactNativeBundleArgs.push('--config', config);
|
|
154
|
-
}
|
|
155
|
-
const reactNativeBundleProcess = spawn('node', reactNativeBundleArgs);
|
|
156
|
-
console.log(`Running bundle command: node ${reactNativeBundleArgs.join(' ')}`);
|
|
157
|
-
return new Promise((resolve, reject)=>{
|
|
158
|
-
reactNativeBundleProcess.stdout.on('data', (data)=>{
|
|
159
|
-
console.log(data.toString().trim());
|
|
160
|
-
});
|
|
161
|
-
reactNativeBundleProcess.stderr.on('data', (data)=>{
|
|
162
|
-
console.error(data.toString().trim());
|
|
163
|
-
});
|
|
164
|
-
reactNativeBundleProcess.on('close', async (exitCode)=>{
|
|
165
|
-
if (exitCode) {
|
|
166
|
-
reject(new Error(t('bundleCommandError', {
|
|
167
|
-
code: exitCode
|
|
168
|
-
})));
|
|
169
|
-
} else {
|
|
170
|
-
let hermesEnabled = false;
|
|
171
|
-
if (forceHermes) {
|
|
172
|
-
hermesEnabled = true;
|
|
173
|
-
console.log(t('forceHermes'));
|
|
174
|
-
} else if (platform === 'android') {
|
|
175
|
-
const gradlePropeties = await new Promise((resolve)=>{
|
|
176
|
-
properties.parse('./android/gradle.properties', {
|
|
177
|
-
path: true
|
|
178
|
-
}, (error, props)=>{
|
|
179
|
-
if (error) {
|
|
180
|
-
console.error(error);
|
|
181
|
-
resolve({});
|
|
182
|
-
}
|
|
183
|
-
resolve(props);
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
hermesEnabled = gradlePropeties.hermesEnabled;
|
|
187
|
-
if (typeof hermesEnabled !== 'boolean') hermesEnabled = gradleConfig.enableHermes;
|
|
188
|
-
} else if (platform === 'ios' && fs.existsSync('ios/Pods/hermes-engine')) {
|
|
189
|
-
hermesEnabled = true;
|
|
190
|
-
}
|
|
191
|
-
if (hermesEnabled) {
|
|
192
|
-
await compileHermesByteCode(bundleName, outputFolder, sourcemapOutput, !isSentry);
|
|
193
|
-
}
|
|
194
|
-
if (platform === 'harmony') {
|
|
195
|
-
const harmonyRawAssetsPath = 'harmony/entry/src/main/resources/rawfile/assets';
|
|
196
|
-
// copy all files in outputFolder to harmonyRawPath
|
|
197
|
-
// assets should be in rawfile/assets
|
|
198
|
-
fs.ensureDirSync(harmonyRawAssetsPath);
|
|
199
|
-
fs.copySync(outputFolder, harmonyRawAssetsPath, {
|
|
200
|
-
overwrite: true
|
|
201
|
-
});
|
|
202
|
-
fs.moveSync(`${harmonyRawAssetsPath}/bundle.harmony.js`, `${harmonyRawAssetsPath}/../bundle.harmony.js`, {
|
|
203
|
-
overwrite: true
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
resolve(null);
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
function getHermesOSBin() {
|
|
212
|
-
if (os.platform() === 'win32') return 'win64-bin';
|
|
213
|
-
if (os.platform() === 'darwin') return 'osx-bin';
|
|
214
|
-
if (os.platform() === 'linux') return 'linux64-bin';
|
|
215
|
-
}
|
|
216
|
-
async function checkGradleConfig() {
|
|
217
|
-
let enableHermes = false;
|
|
218
|
-
let crunchPngs;
|
|
219
|
-
try {
|
|
220
|
-
const gradleConfig = await g2js.parseFile('android/app/build.gradle');
|
|
221
|
-
crunchPngs = gradleConfig.android.buildTypes.release.crunchPngs;
|
|
222
|
-
const projectConfig = gradleConfig['project.ext.react'];
|
|
223
|
-
if (projectConfig) {
|
|
224
|
-
for (const packagerConfig of projectConfig){
|
|
225
|
-
if (packagerConfig.includes('enableHermes') && packagerConfig.includes('true')) {
|
|
226
|
-
enableHermes = true;
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
} catch (e) {}
|
|
232
|
-
return {
|
|
233
|
-
enableHermes,
|
|
234
|
-
crunchPngs
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput, shouldCleanSourcemap) {
|
|
238
|
-
console.log(t('hermesEnabledCompiling'));
|
|
239
|
-
// >= rn 0.69
|
|
240
|
-
const rnDir = path.dirname(require.resolve('react-native', {
|
|
241
|
-
paths: [
|
|
242
|
-
process.cwd()
|
|
243
|
-
]
|
|
244
|
-
}));
|
|
245
|
-
let hermesPath = path.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
|
|
246
|
-
// < rn 0.69
|
|
247
|
-
if (!fs.existsSync(hermesPath)) {
|
|
248
|
-
hermesPath = `node_modules/hermes-engine/${getHermesOSBin()}`;
|
|
249
|
-
}
|
|
250
|
-
const hermesCommand = `${hermesPath}/hermesc`;
|
|
251
|
-
const args = [
|
|
252
|
-
'-emit-binary',
|
|
253
|
-
'-out',
|
|
254
|
-
path.join(outputFolder, bundleName),
|
|
255
|
-
path.join(outputFolder, bundleName),
|
|
256
|
-
'-O'
|
|
257
|
-
];
|
|
258
|
-
if (sourcemapOutput) {
|
|
259
|
-
fs.copyFileSync(sourcemapOutput, path.join(outputFolder, `${bundleName}.txt.map`));
|
|
260
|
-
args.push('-output-source-map');
|
|
261
|
-
}
|
|
262
|
-
console.log(t('runningHermesc', {
|
|
263
|
-
command: hermesCommand,
|
|
264
|
-
args: args.join(' ')
|
|
265
|
-
}));
|
|
266
|
-
spawnSync(hermesCommand, args, {
|
|
267
|
-
stdio: 'ignore'
|
|
268
|
-
});
|
|
269
|
-
if (sourcemapOutput) {
|
|
270
|
-
const composerPath = 'node_modules/react-native/scripts/compose-source-maps.js';
|
|
271
|
-
if (!fs.existsSync(composerPath)) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
console.log(t('composingSourceMap'));
|
|
275
|
-
spawnSync('node', [
|
|
276
|
-
composerPath,
|
|
277
|
-
path.join(outputFolder, `${bundleName}.txt.map`),
|
|
278
|
-
path.join(outputFolder, `${bundleName}.map`),
|
|
279
|
-
'-o',
|
|
280
|
-
sourcemapOutput
|
|
281
|
-
], {
|
|
282
|
-
stdio: 'ignore'
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
if (shouldCleanSourcemap) {
|
|
286
|
-
fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`));
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
async function copyDebugidForSentry(bundleName, outputFolder, sourcemapOutput) {
|
|
290
|
-
if (sourcemapOutput) {
|
|
291
|
-
let copyDebugidPath;
|
|
292
|
-
try {
|
|
293
|
-
copyDebugidPath = require.resolve('@sentry/react-native/scripts/copy-debugid.js', {
|
|
294
|
-
paths: [
|
|
295
|
-
process.cwd()
|
|
296
|
-
]
|
|
297
|
-
});
|
|
298
|
-
} catch (error) {
|
|
299
|
-
console.error(t('sentryCliNotFound'));
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
if (!fs.existsSync(copyDebugidPath)) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
console.log(t('copyingDebugId'));
|
|
306
|
-
spawnSync('node', [
|
|
307
|
-
copyDebugidPath,
|
|
308
|
-
path.join(outputFolder, `${bundleName}.txt.map`),
|
|
309
|
-
path.join(outputFolder, `${bundleName}.map`)
|
|
310
|
-
], {
|
|
311
|
-
stdio: 'ignore'
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`));
|
|
315
|
-
}
|
|
316
|
-
async function uploadSourcemapForSentry(bundleName, outputFolder, sourcemapOutput, version) {
|
|
317
|
-
if (sourcemapOutput) {
|
|
318
|
-
let sentryCliPath;
|
|
319
|
-
try {
|
|
320
|
-
sentryCliPath = require.resolve('@sentry/cli/bin/sentry-cli', {
|
|
321
|
-
paths: [
|
|
322
|
-
process.cwd()
|
|
323
|
-
]
|
|
324
|
-
});
|
|
325
|
-
} catch (error) {
|
|
326
|
-
console.error(t('sentryCliNotFound'));
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
if (!fs.existsSync(sentryCliPath)) {
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
|
-
spawnSync('node', [
|
|
333
|
-
sentryCliPath,
|
|
334
|
-
'releases',
|
|
335
|
-
'set-commits',
|
|
336
|
-
version,
|
|
337
|
-
'--auto'
|
|
338
|
-
], {
|
|
339
|
-
stdio: 'inherit'
|
|
340
|
-
});
|
|
341
|
-
console.log(t('sentryReleaseCreated', {
|
|
342
|
-
version
|
|
343
|
-
}));
|
|
344
|
-
console.log(t('uploadingSourcemap'));
|
|
345
|
-
spawnSync('node', [
|
|
346
|
-
sentryCliPath,
|
|
347
|
-
'releases',
|
|
348
|
-
'files',
|
|
349
|
-
version,
|
|
350
|
-
'upload-sourcemaps',
|
|
351
|
-
'--strip-prefix',
|
|
352
|
-
path.join(process.cwd(), outputFolder),
|
|
353
|
-
path.join(outputFolder, bundleName),
|
|
354
|
-
path.join(outputFolder, `${bundleName}.map`)
|
|
355
|
-
], {
|
|
356
|
-
stdio: 'inherit'
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
const ignorePackingFileNames = [
|
|
361
|
-
'.',
|
|
362
|
-
'..',
|
|
363
|
-
'index.bundlejs.map',
|
|
364
|
-
'bundle.harmony.js.map'
|
|
365
|
-
];
|
|
366
|
-
const ignorePackingExtensions = [
|
|
367
|
-
'DS_Store',
|
|
368
|
-
'txt.map'
|
|
369
|
-
];
|
|
370
|
-
async function pack(dir, output) {
|
|
371
|
-
console.log(t('packing'));
|
|
372
|
-
fs.ensureDirSync(path.dirname(output));
|
|
373
|
-
await new Promise((resolve, reject)=>{
|
|
374
|
-
const zipfile = new YazlZipFile();
|
|
375
|
-
function addDirectory(root, rel) {
|
|
376
|
-
if (rel) {
|
|
377
|
-
zipfile.addEmptyDirectory(rel);
|
|
378
|
-
}
|
|
379
|
-
const childs = fs.readdirSync(root);
|
|
380
|
-
for (const name of childs){
|
|
381
|
-
if (ignorePackingFileNames.includes(name) || ignorePackingExtensions.some((ext)=>name.endsWith(`.${ext}`))) {
|
|
382
|
-
continue;
|
|
383
|
-
}
|
|
384
|
-
const fullPath = path.join(root, name);
|
|
385
|
-
const stat = fs.statSync(fullPath);
|
|
386
|
-
if (stat.isFile()) {
|
|
387
|
-
//console.log('adding: ' + rel+name);
|
|
388
|
-
zipfile.addFile(fullPath, rel + name);
|
|
389
|
-
} else if (stat.isDirectory()) {
|
|
390
|
-
//console.log('adding: ' + rel+name+'/');
|
|
391
|
-
addDirectory(fullPath, `${rel}${name}/`);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
addDirectory(dir, '');
|
|
396
|
-
zipfile.outputStream.on('error', (err)=>reject(err));
|
|
397
|
-
zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', ()=>{
|
|
398
|
-
resolve(void 0);
|
|
399
|
-
});
|
|
400
|
-
zipfile.end();
|
|
401
|
-
});
|
|
402
|
-
console.log(t('fileGenerated', {
|
|
403
|
-
file: output
|
|
404
|
-
}));
|
|
405
|
-
}
|
|
406
|
-
export function readEntry(entry, zipFile) {
|
|
407
|
-
const buffers = [];
|
|
408
|
-
return new Promise((resolve, reject)=>{
|
|
409
|
-
zipFile.openReadStream(entry, (err, stream)=>{
|
|
410
|
-
stream.on('data', (chunk)=>{
|
|
411
|
-
buffers.push(chunk);
|
|
412
|
-
});
|
|
413
|
-
stream.on('end', ()=>{
|
|
414
|
-
resolve(Buffer.concat(buffers));
|
|
415
|
-
});
|
|
416
|
-
stream.on('error', (err)=>{
|
|
417
|
-
reject(err);
|
|
418
|
-
});
|
|
419
|
-
});
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
function basename(fn) {
|
|
423
|
-
const m = /^(.+\/)[^\/]+\/?$/.exec(fn);
|
|
424
|
-
return m == null ? void 0 : m[1];
|
|
425
|
-
}
|
|
426
|
-
async function diffFromPPK(origin, next, output) {
|
|
427
|
-
fs.ensureDirSync(path.dirname(output));
|
|
428
|
-
const originEntries = {};
|
|
429
|
-
const originMap = {};
|
|
430
|
-
let originSource;
|
|
431
|
-
await enumZipEntries(origin, (entry, zipFile)=>{
|
|
432
|
-
originEntries[entry.fileName] = entry;
|
|
433
|
-
if (!/\/$/.test(entry.fileName)) {
|
|
434
|
-
// isFile
|
|
435
|
-
originMap[entry.crc32] = entry.fileName;
|
|
436
|
-
if (isPPKBundleFileName(entry.fileName)) {
|
|
437
|
-
// This is source.
|
|
438
|
-
return readEntry(entry, zipFile).then((v)=>originSource = v);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
if (!originSource) {
|
|
443
|
-
throw new Error(t('bundleFileNotFound'));
|
|
444
|
-
}
|
|
445
|
-
const copies = {};
|
|
446
|
-
const zipfile = new YazlZipFile();
|
|
447
|
-
const writePromise = new Promise((resolve, reject)=>{
|
|
448
|
-
zipfile.outputStream.on('error', (err)=>{
|
|
449
|
-
throw err;
|
|
450
|
-
});
|
|
451
|
-
zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', ()=>{
|
|
452
|
-
resolve(void 0);
|
|
453
|
-
});
|
|
454
|
-
});
|
|
455
|
-
const addedEntry = {};
|
|
456
|
-
function addEntry(fn) {
|
|
457
|
-
//console.log(fn);
|
|
458
|
-
if (!fn || addedEntry[fn]) {
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
const base = basename(fn);
|
|
462
|
-
if (base) {
|
|
463
|
-
addEntry(base);
|
|
464
|
-
}
|
|
465
|
-
zipfile.addEmptyDirectory(fn);
|
|
466
|
-
}
|
|
467
|
-
const newEntries = {};
|
|
468
|
-
await enumZipEntries(next, (entry, nextZipfile)=>{
|
|
469
|
-
newEntries[entry.fileName] = entry;
|
|
470
|
-
if (/\/$/.test(entry.fileName)) {
|
|
471
|
-
// Directory
|
|
472
|
-
if (!originEntries[entry.fileName]) {
|
|
473
|
-
addEntry(entry.fileName);
|
|
474
|
-
}
|
|
475
|
-
} else if (isPPKBundleFileName(entry.fileName)) {
|
|
476
|
-
//console.log('Found bundle');
|
|
477
|
-
return readEntry(entry, nextZipfile).then((newSource)=>{
|
|
478
|
-
//console.log('Begin diff');
|
|
479
|
-
zipfile.addBuffer(diff(originSource, newSource), `${entry.fileName}.patch`);
|
|
480
|
-
//console.log('End diff');
|
|
481
|
-
});
|
|
482
|
-
} else {
|
|
483
|
-
// If same file.
|
|
484
|
-
const originEntry = originEntries[entry.fileName];
|
|
485
|
-
if (originEntry && originEntry.crc32 === entry.crc32) {
|
|
486
|
-
// ignore
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
// If moved from other place
|
|
490
|
-
if (originMap[entry.crc32]) {
|
|
491
|
-
const base = basename(entry.fileName);
|
|
492
|
-
if (!originEntries[base]) {
|
|
493
|
-
addEntry(base);
|
|
494
|
-
}
|
|
495
|
-
copies[entry.fileName] = originMap[entry.crc32];
|
|
496
|
-
return;
|
|
497
|
-
}
|
|
498
|
-
// New file.
|
|
499
|
-
addEntry(basename(entry.fileName));
|
|
500
|
-
return new Promise((resolve, reject)=>{
|
|
501
|
-
nextZipfile.openReadStream(entry, (err, readStream)=>{
|
|
502
|
-
if (err) {
|
|
503
|
-
return reject(err);
|
|
504
|
-
}
|
|
505
|
-
zipfile.addReadStream(readStream, entry.fileName);
|
|
506
|
-
readStream.on('end', ()=>{
|
|
507
|
-
//console.log('add finished');
|
|
508
|
-
resolve(void 0);
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
const deletes = {};
|
|
515
|
-
for(const k in originEntries){
|
|
516
|
-
if (!newEntries[k]) {
|
|
517
|
-
console.log(t('deleteFile', {
|
|
518
|
-
file: k
|
|
519
|
-
}));
|
|
520
|
-
deletes[k] = 1;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
//console.log({copies, deletes});
|
|
524
|
-
zipfile.addBuffer(Buffer.from(JSON.stringify({
|
|
525
|
-
copies,
|
|
526
|
-
deletes
|
|
527
|
-
})), '__diff.json');
|
|
528
|
-
zipfile.end();
|
|
529
|
-
await writePromise;
|
|
530
|
-
}
|
|
531
|
-
async function diffFromPackage(origin, next, output, originBundleName, transformPackagePath = (v)=>v) {
|
|
532
|
-
fs.ensureDirSync(path.dirname(output));
|
|
533
|
-
const originEntries = {};
|
|
534
|
-
const originMap = {};
|
|
535
|
-
let originSource;
|
|
536
|
-
await enumZipEntries(origin, (entry, zipFile)=>{
|
|
537
|
-
if (!/\/$/.test(entry.fileName)) {
|
|
538
|
-
const fn = transformPackagePath(entry.fileName);
|
|
539
|
-
if (!fn) {
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
//console.log(fn);
|
|
543
|
-
// isFile
|
|
544
|
-
originEntries[fn] = entry.crc32;
|
|
545
|
-
originMap[entry.crc32] = fn;
|
|
546
|
-
if (fn === originBundleName) {
|
|
547
|
-
// This is source.
|
|
548
|
-
return readEntry(entry, zipFile).then((v)=>originSource = v);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
|
-
if (!originSource) {
|
|
553
|
-
throw new Error(t('bundleFileNotFound'));
|
|
554
|
-
}
|
|
555
|
-
const copies = {};
|
|
556
|
-
const zipfile = new YazlZipFile();
|
|
557
|
-
const writePromise = new Promise((resolve, reject)=>{
|
|
558
|
-
zipfile.outputStream.on('error', (err)=>{
|
|
559
|
-
throw err;
|
|
560
|
-
});
|
|
561
|
-
zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', ()=>{
|
|
562
|
-
resolve(void 0);
|
|
563
|
-
});
|
|
564
|
-
});
|
|
565
|
-
await enumZipEntries(next, (entry, nextZipfile)=>{
|
|
566
|
-
if (/\/$/.test(entry.fileName)) {
|
|
567
|
-
// Directory
|
|
568
|
-
zipfile.addEmptyDirectory(entry.fileName);
|
|
569
|
-
} else if (isPPKBundleFileName(entry.fileName)) {
|
|
570
|
-
//console.log('Found bundle');
|
|
571
|
-
return readEntry(entry, nextZipfile).then((newSource)=>{
|
|
572
|
-
//console.log('Begin diff');
|
|
573
|
-
zipfile.addBuffer(diff(originSource, newSource), `${entry.fileName}.patch`);
|
|
574
|
-
//console.log('End diff');
|
|
575
|
-
});
|
|
576
|
-
} else {
|
|
577
|
-
// If same file.
|
|
578
|
-
if (originEntries[entry.fileName] === entry.crc32) {
|
|
579
|
-
copies[entry.fileName] = '';
|
|
580
|
-
return;
|
|
581
|
-
}
|
|
582
|
-
// If moved from other place
|
|
583
|
-
if (originMap[entry.crc32]) {
|
|
584
|
-
copies[entry.fileName] = originMap[entry.crc32];
|
|
585
|
-
return;
|
|
586
|
-
}
|
|
587
|
-
return new Promise((resolve, reject)=>{
|
|
588
|
-
nextZipfile.openReadStream(entry, (err, readStream)=>{
|
|
589
|
-
if (err) {
|
|
590
|
-
return reject(err);
|
|
591
|
-
}
|
|
592
|
-
zipfile.addReadStream(readStream, entry.fileName);
|
|
593
|
-
readStream.on('end', ()=>{
|
|
594
|
-
//console.log('add finished');
|
|
595
|
-
resolve(void 0);
|
|
596
|
-
});
|
|
597
|
-
});
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
});
|
|
601
|
-
zipfile.addBuffer(Buffer.from(JSON.stringify({
|
|
602
|
-
copies
|
|
603
|
-
})), '__diff.json');
|
|
604
|
-
zipfile.end();
|
|
605
|
-
await writePromise;
|
|
606
|
-
}
|
|
607
|
-
export async function enumZipEntries(zipFn, callback, nestedPath = '') {
|
|
608
|
-
return new Promise((resolve, reject)=>{
|
|
609
|
-
openZipFile(zipFn, {
|
|
610
|
-
lazyEntries: true
|
|
611
|
-
}, async (err, zipfile)=>{
|
|
612
|
-
if (err) {
|
|
613
|
-
return reject(err);
|
|
614
|
-
}
|
|
615
|
-
zipfile.on('end', resolve);
|
|
616
|
-
zipfile.on('error', reject);
|
|
617
|
-
zipfile.on('entry', async (entry)=>{
|
|
618
|
-
const fullPath = nestedPath + entry.fileName;
|
|
619
|
-
try {
|
|
620
|
-
if (!entry.fileName.endsWith('/') && entry.fileName.toLowerCase().endsWith('.hap')) {
|
|
621
|
-
const tempDir = path.join(os.tmpdir(), `nested_zip_${Date.now()}`);
|
|
622
|
-
await fs.ensureDir(tempDir);
|
|
623
|
-
const tempZipPath = path.join(tempDir, 'temp.zip');
|
|
624
|
-
await new Promise((res, rej)=>{
|
|
625
|
-
zipfile.openReadStream(entry, async (err, readStream)=>{
|
|
626
|
-
if (err) return rej(err);
|
|
627
|
-
const writeStream = fs.createWriteStream(tempZipPath);
|
|
628
|
-
readStream.pipe(writeStream);
|
|
629
|
-
writeStream.on('finish', ()=>res(void 0));
|
|
630
|
-
writeStream.on('error', rej);
|
|
631
|
-
});
|
|
632
|
-
});
|
|
633
|
-
await enumZipEntries(tempZipPath, callback, `${fullPath}/`);
|
|
634
|
-
await fs.remove(tempDir);
|
|
635
|
-
}
|
|
636
|
-
const result = callback(entry, zipfile, fullPath);
|
|
637
|
-
if (result && typeof result.then === 'function') {
|
|
638
|
-
await result;
|
|
639
|
-
}
|
|
640
|
-
} catch (error) {
|
|
641
|
-
console.error(t('processingError', {
|
|
642
|
-
error
|
|
643
|
-
}));
|
|
644
|
-
}
|
|
645
|
-
zipfile.readEntry();
|
|
646
|
-
});
|
|
647
|
-
zipfile.readEntry();
|
|
648
|
-
});
|
|
649
|
-
});
|
|
650
|
-
}
|
|
651
|
-
function diffArgsCheck(args, options, diffFn) {
|
|
652
|
-
const [origin, next] = args;
|
|
653
|
-
if (!origin || !next) {
|
|
654
|
-
console.error(t('usageDiff', {
|
|
655
|
-
command: diffFn
|
|
656
|
-
}));
|
|
657
|
-
process.exit(1);
|
|
658
|
-
}
|
|
659
|
-
if (diffFn.startsWith('hdiff')) {
|
|
660
|
-
if (!hdiff) {
|
|
661
|
-
console.error(t('nodeHdiffpatchRequired', {
|
|
662
|
-
scriptName
|
|
663
|
-
}));
|
|
664
|
-
process.exit(1);
|
|
665
|
-
}
|
|
666
|
-
diff = hdiff;
|
|
667
|
-
} else {
|
|
668
|
-
if (!bsdiff) {
|
|
669
|
-
console.error(t('nodeBsdiffRequired', {
|
|
670
|
-
scriptName
|
|
671
|
-
}));
|
|
672
|
-
process.exit(1);
|
|
673
|
-
}
|
|
674
|
-
diff = bsdiff;
|
|
675
|
-
}
|
|
676
|
-
const { output } = translateOptions({
|
|
677
|
-
...options,
|
|
678
|
-
tempDir
|
|
679
|
-
});
|
|
680
|
-
return {
|
|
681
|
-
origin,
|
|
682
|
-
next,
|
|
683
|
-
realOutput: output.replace(/\$\{time\}/g, `${Date.now()}`)
|
|
684
|
-
};
|
|
685
|
-
}
|
|
686
|
-
export const bundleCommands = {
|
|
687
|
-
bundle: async ({ options })=>{
|
|
688
|
-
const platform = await getPlatform(options.platform);
|
|
689
|
-
const { bundleName, entryFile, intermediaDir, output, dev, sourcemap, taro, expo, rncli, hermes, name, description, metaInfo, packageId, packageVersion, minPackageVersion, maxPackageVersion, packageVersionRange, rollout, dryRun } = translateOptions({
|
|
690
|
-
...options,
|
|
691
|
-
tempDir,
|
|
692
|
-
platform
|
|
693
|
-
});
|
|
694
|
-
checkLockFiles();
|
|
695
|
-
addGitIgnore();
|
|
696
|
-
const bundleParams = await checkPlugins();
|
|
697
|
-
const sourcemapPlugin = bundleParams.sourcemap;
|
|
698
|
-
const isSentry = bundleParams.sentry;
|
|
699
|
-
const sourcemapOutput = path.join(intermediaDir, `${bundleName}.map`);
|
|
700
|
-
const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
|
|
701
|
-
if (!platform) {
|
|
702
|
-
throw new Error(t('platformRequired'));
|
|
703
|
-
}
|
|
704
|
-
console.log(`Bundling with react-native: ${depVersions['react-native']}`);
|
|
705
|
-
await runReactNativeBundleCommand({
|
|
706
|
-
bundleName,
|
|
707
|
-
dev,
|
|
708
|
-
entryFile,
|
|
709
|
-
outputFolder: intermediaDir,
|
|
710
|
-
platform,
|
|
711
|
-
sourcemapOutput: sourcemap || sourcemapPlugin ? sourcemapOutput : '',
|
|
712
|
-
forceHermes: hermes,
|
|
713
|
-
cli: {
|
|
714
|
-
taro: !!taro,
|
|
715
|
-
expo: !!expo,
|
|
716
|
-
rncli: !!rncli
|
|
717
|
-
}
|
|
718
|
-
});
|
|
719
|
-
await pack(path.resolve(intermediaDir), realOutput);
|
|
720
|
-
if (name) {
|
|
721
|
-
const versionName = await versionCommands.publish({
|
|
722
|
-
args: [
|
|
723
|
-
realOutput
|
|
724
|
-
],
|
|
725
|
-
options: {
|
|
726
|
-
platform,
|
|
727
|
-
name,
|
|
728
|
-
description,
|
|
729
|
-
metaInfo,
|
|
730
|
-
packageId,
|
|
731
|
-
packageVersion,
|
|
732
|
-
minPackageVersion,
|
|
733
|
-
maxPackageVersion,
|
|
734
|
-
packageVersionRange,
|
|
735
|
-
rollout,
|
|
736
|
-
dryRun: Boolean(dryRun)
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
if (isSentry) {
|
|
740
|
-
await copyDebugidForSentry(bundleName, intermediaDir, sourcemapOutput);
|
|
741
|
-
await uploadSourcemapForSentry(bundleName, intermediaDir, sourcemapOutput, versionName);
|
|
742
|
-
}
|
|
743
|
-
} else if (!options['no-interactive']) {
|
|
744
|
-
const v = await question(t('uploadBundlePrompt'));
|
|
745
|
-
if (v.toLowerCase() === 'y') {
|
|
746
|
-
const versionName = await versionCommands.publish({
|
|
747
|
-
args: [
|
|
748
|
-
realOutput
|
|
749
|
-
],
|
|
750
|
-
options: {
|
|
751
|
-
platform
|
|
752
|
-
}
|
|
753
|
-
});
|
|
754
|
-
if (isSentry) {
|
|
755
|
-
await copyDebugidForSentry(bundleName, intermediaDir, sourcemapOutput);
|
|
756
|
-
await uploadSourcemapForSentry(bundleName, intermediaDir, sourcemapOutput, versionName);
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
},
|
|
761
|
-
async diff ({ args, options }) {
|
|
762
|
-
const { origin, next, realOutput } = diffArgsCheck(args, options, 'diff');
|
|
763
|
-
await diffFromPPK(origin, next, realOutput);
|
|
764
|
-
console.log(t('diffPackageGenerated', {
|
|
765
|
-
output: realOutput
|
|
766
|
-
}));
|
|
767
|
-
},
|
|
768
|
-
async hdiff ({ args, options }) {
|
|
769
|
-
const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiff');
|
|
770
|
-
await diffFromPPK(origin, next, realOutput);
|
|
771
|
-
console.log(t('diffPackageGenerated', {
|
|
772
|
-
output: realOutput
|
|
773
|
-
}));
|
|
774
|
-
},
|
|
775
|
-
async diffFromApk ({ args, options }) {
|
|
776
|
-
const { origin, next, realOutput } = diffArgsCheck(args, options, 'diffFromApk');
|
|
777
|
-
await diffFromPackage(origin, next, realOutput, 'assets/index.android.bundle');
|
|
778
|
-
console.log(t('diffPackageGenerated', {
|
|
779
|
-
output: realOutput
|
|
780
|
-
}));
|
|
781
|
-
},
|
|
782
|
-
async hdiffFromApk ({ args, options }) {
|
|
783
|
-
const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiffFromApk');
|
|
784
|
-
await diffFromPackage(origin, next, realOutput, 'assets/index.android.bundle');
|
|
785
|
-
console.log(t('diffPackageGenerated', {
|
|
786
|
-
output: realOutput
|
|
787
|
-
}));
|
|
788
|
-
},
|
|
789
|
-
async diffFromApp ({ args, options }) {
|
|
790
|
-
const { origin, next, realOutput } = diffArgsCheck(args, options, 'diffFromApp');
|
|
791
|
-
await diffFromPackage(origin, next, realOutput, 'resources/rawfile/bundle.harmony.js');
|
|
792
|
-
console.log(t('diffPackageGenerated', {
|
|
793
|
-
output: realOutput
|
|
794
|
-
}));
|
|
795
|
-
},
|
|
796
|
-
async hdiffFromApp ({ args, options }) {
|
|
797
|
-
const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiffFromApp');
|
|
798
|
-
await diffFromPackage(origin, next, realOutput, 'resources/rawfile/bundle.harmony.js');
|
|
799
|
-
console.log(t('diffPackageGenerated', {
|
|
800
|
-
output: realOutput
|
|
801
|
-
}));
|
|
802
|
-
},
|
|
803
|
-
async diffFromIpa ({ args, options }) {
|
|
804
|
-
const { origin, next, realOutput } = diffArgsCheck(args, options, 'diffFromIpa');
|
|
805
|
-
await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v)=>{
|
|
806
|
-
const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
|
|
807
|
-
return m == null ? void 0 : m[1];
|
|
808
|
-
});
|
|
809
|
-
console.log(t('diffPackageGenerated', {
|
|
810
|
-
output: realOutput
|
|
811
|
-
}));
|
|
812
|
-
},
|
|
813
|
-
async hdiffFromIpa ({ args, options }) {
|
|
814
|
-
const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiffFromIpa');
|
|
815
|
-
await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v)=>{
|
|
816
|
-
const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
|
|
817
|
-
return m == null ? void 0 : m[1];
|
|
818
|
-
});
|
|
819
|
-
console.log(t('diffPackageGenerated', {
|
|
820
|
-
output: realOutput
|
|
821
|
-
}));
|
|
822
|
-
}
|
|
823
|
-
};
|