mirror of
https://gitcode.com/github-mirrors/react-native-update-cli.git
synced 2025-09-16 09:41:38 +08:00
@@ -1,5 +1,5 @@
|
||||
import path from 'node:path';
|
||||
import { getRNVersion, translateOptions } from './utils';
|
||||
import { translateOptions } from './utils';
|
||||
import * as fs from 'fs-extra';
|
||||
import { ZipFile } from 'yazl';
|
||||
import { open as openZipFile } from 'yauzl';
|
||||
@@ -10,6 +10,7 @@ import semverSatisfies from 'semver/functions/satisfies';
|
||||
const g2js = require('gradle-to-js/lib/parser');
|
||||
import os from 'node:os';
|
||||
const properties = require('properties');
|
||||
import { depVersions } from './utils/dep-versions';
|
||||
|
||||
let bsdiff;
|
||||
let hdiff;
|
||||
@@ -82,11 +83,13 @@ async function runReactNativeBundleCommand({
|
||||
paths: [process.cwd()],
|
||||
});
|
||||
const expoCliVersion = JSON.parse(
|
||||
fs.readFileSync(
|
||||
require.resolve('@expo/cli/package.json', {
|
||||
paths: [process.cwd()],
|
||||
}),
|
||||
).toString(),
|
||||
fs
|
||||
.readFileSync(
|
||||
require.resolve('@expo/cli/package.json', {
|
||||
paths: [process.cwd()],
|
||||
}),
|
||||
)
|
||||
.toString(),
|
||||
).version;
|
||||
// expo cli 0.10.17 (expo 49) 开始支持 bundle:embed
|
||||
if (semverSatisfies(expoCliVersion, '>= 0.10.17')) {
|
||||
@@ -175,19 +178,11 @@ async function runReactNativeBundleCommand({
|
||||
platform,
|
||||
'--reset-cache',
|
||||
]);
|
||||
|
||||
|
||||
if (cli.taro) {
|
||||
reactNativeBundleArgs.push(...[
|
||||
'--type',
|
||||
'rn',
|
||||
])
|
||||
reactNativeBundleArgs.push(...['--type', 'rn']);
|
||||
} else {
|
||||
reactNativeBundleArgs.push(...[
|
||||
'--dev',
|
||||
dev,
|
||||
'--entry-file',
|
||||
entryFile,
|
||||
])
|
||||
reactNativeBundleArgs.push(...['--dev', dev, '--entry-file', entryFile]);
|
||||
}
|
||||
|
||||
if (sourcemapOutput) {
|
||||
@@ -927,9 +922,7 @@ export const commands = {
|
||||
throw new Error('Platform must be specified.');
|
||||
}
|
||||
|
||||
const { version, major, minor } = getRNVersion();
|
||||
|
||||
console.log(`Bundling with react-native: ${version}`);
|
||||
console.log(`Bundling with react-native: ${depVersions['react-native']}`);
|
||||
|
||||
await runReactNativeBundleCommand({
|
||||
bundleName,
|
||||
|
@@ -5,6 +5,7 @@ import { checkPlatform, getSelectedApp } from './app';
|
||||
|
||||
import { getApkInfo, getIpaInfo, getAppInfo } from './utils';
|
||||
import Table from 'tty-table';
|
||||
import { depVersions } from './utils/dep-versions';
|
||||
|
||||
export async function listPackage(appId: string) {
|
||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
||||
@@ -79,6 +80,7 @@ export const commands = {
|
||||
name: versionName,
|
||||
hash,
|
||||
buildTime,
|
||||
deps: depVersions,
|
||||
});
|
||||
saveToLocal(fn, `${appId}/package/${id}.ipa`);
|
||||
console.log(
|
||||
@@ -116,6 +118,7 @@ export const commands = {
|
||||
name: versionName,
|
||||
hash,
|
||||
buildTime,
|
||||
deps: depVersions,
|
||||
});
|
||||
saveToLocal(fn, `${appId}/package/${id}.apk`);
|
||||
console.log(
|
||||
@@ -153,6 +156,7 @@ export const commands = {
|
||||
name: versionName,
|
||||
hash,
|
||||
buildTime,
|
||||
deps: depVersions,
|
||||
});
|
||||
saveToLocal(fn, `${appId}/package/${id}.app`);
|
||||
console.log(
|
||||
|
26
src/utils/dep-versions.ts
Normal file
26
src/utils/dep-versions.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
const currentPackage = require(`${process.cwd()}/package.json`);
|
||||
|
||||
const depKeys = Object.keys(currentPackage.dependencies);
|
||||
const devDepKeys = Object.keys(currentPackage.devDependencies);
|
||||
const dedupedDeps = [...new Set([...depKeys, ...devDepKeys])];
|
||||
|
||||
const _depVersions: Record<string, string> = {};
|
||||
|
||||
for (const dep of dedupedDeps) {
|
||||
try {
|
||||
const packageJsonPath = require.resolve(`${dep}/package.json`, {
|
||||
paths: [process.cwd()],
|
||||
});
|
||||
const version = require(packageJsonPath).version;
|
||||
_depVersions[dep] = version;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
export const depVersions = Object.keys(_depVersions)
|
||||
.sort() // Sort the keys alphabetically
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = _depVersions[key]; // Rebuild the object with sorted keys
|
||||
return obj;
|
||||
}, {} as Record<string, string>);
|
||||
|
||||
// console.log({ depVersions });
|
@@ -10,6 +10,7 @@ import { checkPlugins } from './check-plugin';
|
||||
|
||||
import { read } from 'read';
|
||||
import { tempDir } from './constants';
|
||||
import { depVersions } from './dep-versions';
|
||||
|
||||
export async function question(query: string, password?: boolean) {
|
||||
if (NO_INTERACTIVE) {
|
||||
@@ -38,26 +39,6 @@ export function translateOptions(options: Record<string, string>) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function getRNVersion() {
|
||||
const version = JSON.parse(
|
||||
fs
|
||||
.readFileSync(
|
||||
require.resolve('react-native/package.json', {
|
||||
paths: [process.cwd()],
|
||||
}),
|
||||
)
|
||||
.toString(),
|
||||
).version;
|
||||
|
||||
const [, major, minor] = /^(\d+)\.(\d+)\./.exec(version) || [];
|
||||
|
||||
return {
|
||||
version,
|
||||
major: Number(major),
|
||||
minor: Number(minor),
|
||||
};
|
||||
}
|
||||
|
||||
export async function getApkInfo(fn: string) {
|
||||
const appInfoParser = new AppInfoParser(fn);
|
||||
const bundleFile = await appInfoParser.parser.getEntry(
|
||||
@@ -198,21 +179,11 @@ export async function printVersionCommand() {
|
||||
`react-native-update-cli: ${pkg.version}${latestPushyCliVersion}`,
|
||||
);
|
||||
let pushyVersion = '';
|
||||
try {
|
||||
const PACKAGE_JSON_PATH = require.resolve(
|
||||
'react-native-update/package.json',
|
||||
{
|
||||
paths: [process.cwd()],
|
||||
},
|
||||
);
|
||||
pushyVersion = require(PACKAGE_JSON_PATH).version;
|
||||
latestPushyVersion = latestPushyVersion
|
||||
? ` (最新:${chalk.green(latestPushyVersion)})`
|
||||
: '';
|
||||
console.log(`react-native-update: ${pushyVersion}${latestPushyVersion}`);
|
||||
} catch (e) {
|
||||
console.log('react-native-update: 无法获取版本号,请在项目目录中运行命令');
|
||||
}
|
||||
pushyVersion = depVersions['react-native-update'];
|
||||
latestPushyVersion = latestPushyVersion
|
||||
? ` (最新:${chalk.green(latestPushyVersion)})`
|
||||
: '';
|
||||
console.log(`react-native-update: ${pushyVersion}${latestPushyVersion}`);
|
||||
if (pushyVersion) {
|
||||
if (semverSatisfies(pushyVersion, '<8.5.2')) {
|
||||
console.warn(
|
||||
@@ -229,6 +200,8 @@ export async function printVersionCommand() {
|
||||
'当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10',
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.log('react-native-update: 无法获取版本号,请在项目目录中运行命令');
|
||||
}
|
||||
}
|
||||
|
||||
|
24
src/utils/lock-checker.ts
Normal file
24
src/utils/lock-checker.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
const lockFiles = [
|
||||
'package-lock.json',
|
||||
'yarn.lock',
|
||||
'pnpm-lock.yaml',
|
||||
'bun.lockb',
|
||||
'bun.lock',
|
||||
];
|
||||
|
||||
const lockNotFound = `
|
||||
没有检测到任何 lock 文件,这可能导致依赖关系不一致而使热更异常。
|
||||
`;
|
||||
|
||||
const multipleLocksFound = `
|
||||
检测到多个锁文件(),这可能导致依赖关系不一致而使热更异常。
|
||||
`;
|
||||
|
||||
|
||||
const lockBestPractice = `
|
||||
关于 lock 文件的最佳实践:
|
||||
1. 开发团队中的所有成员应该使用相同的包管理器,维护同一份 lock 文件。
|
||||
2. 将 lock 文件添加到版本控制中(但不要同时提交多种不同格式的 lock 文件)。
|
||||
3. 代码审核时应关注 lock 文件的变化。
|
||||
这样可以最大限度避免因依赖关系不一致而导致的热更异常,也降低供应链攻击等安全隐患。
|
||||
`;
|
@@ -4,6 +4,7 @@ import { question, saveToLocal } from './utils';
|
||||
import { checkPlatform, getSelectedApp } from './app';
|
||||
import { choosePackage } from './package';
|
||||
import { compare } from 'compare-versions';
|
||||
import { depVersions } from './utils/dep-versions';
|
||||
|
||||
async function showVersion(appId: string, offset: number) {
|
||||
const { data, count } = await get(`/app/${appId}/version/list`);
|
||||
@@ -13,11 +14,11 @@ async function showVersion(appId: string, offset: number) {
|
||||
.slice(0, 3)
|
||||
.map((v) => v.name)
|
||||
.join(', ');
|
||||
const count = version.packages.length;
|
||||
if (count > 3) {
|
||||
packageInfo += `...and ${count - 3} more`;
|
||||
const pkgCount = version.packages.length;
|
||||
if (pkgCount > 3) {
|
||||
packageInfo += `...and ${pkgCount - 3} more`;
|
||||
}
|
||||
if (count === 0) {
|
||||
if (pkgCount === 0) {
|
||||
packageInfo = 'no package';
|
||||
} else {
|
||||
packageInfo = `[${packageInfo}]`;
|
||||
@@ -31,7 +32,7 @@ async function showVersion(appId: string, offset: number) {
|
||||
return data;
|
||||
}
|
||||
|
||||
async function listVersions(appId) {
|
||||
async function listVersions(appId: string) {
|
||||
let offset = 0;
|
||||
while (true) {
|
||||
await showVersion(appId, offset);
|
||||
@@ -52,7 +53,7 @@ async function listVersions(appId) {
|
||||
}
|
||||
}
|
||||
|
||||
async function chooseVersion(appId) {
|
||||
async function chooseVersion(appId: string) {
|
||||
let offset = 0;
|
||||
while (true) {
|
||||
const data = await showVersion(appId, offset);
|
||||
@@ -103,6 +104,7 @@ export const commands = {
|
||||
hash,
|
||||
description: description || (await question('输入版本描述:')),
|
||||
metaInfo: metaInfo || (await question('输入自定义的 meta info:')),
|
||||
deps: depVersions,
|
||||
});
|
||||
// TODO local diff
|
||||
saveToLocal(fn, `${appId}/ppk/${id}.ppk`);
|
||||
|
Reference in New Issue
Block a user