1
0
mirror of https://gitcode.com/github-mirrors/react-native-update-cli.git synced 2025-09-16 09:41:38 +08:00
Code Issues Packages Projects Releases Wiki Activity GitHub Gitee

support taro

This commit is contained in:
sunnylqm
2025-02-13 16:02:04 +08:00
parent f16aff5674
commit 1d1e6cde0f
2 changed files with 197 additions and 97 deletions

View File

@@ -145,6 +145,15 @@
}, },
"sourcemap": { "sourcemap": {
"default": false "default": false
},
"taro": {
"default": false
},
"expo": {
"default": false
},
"rncli": {
"default": false
} }
} }
}, },

View File

@@ -22,16 +22,29 @@ try {
hdiff = require('node-hdiffpatch').diff; hdiff = require('node-hdiffpatch').diff;
} catch (e) {} } catch (e) {}
async function runReactNativeBundleCommand({
async function runReactNativeBundleCommand( bundleName,
bundleName: string, dev,
development: string, entryFile,
entryFile: string, outputFolder,
outputFolder: string, platform,
platform: string, sourcemapOutput,
sourcemapOutput: string, config,
config: string, cli,
) { }: {
bundleName: string;
dev: string;
entryFile: string;
outputFolder: string;
platform: string;
sourcemapOutput: string;
config?: string;
cli: {
taro?: boolean;
expo?: boolean;
rncli?: boolean;
};
}) {
let gradleConfig: { let gradleConfig: {
crunchPngs?: boolean; crunchPngs?: boolean;
enableHermes?: boolean; enableHermes?: boolean;
@@ -58,26 +71,31 @@ async function runReactNativeBundleCommand(
fs.emptyDirSync(outputFolder); fs.emptyDirSync(outputFolder);
let cliPath; let cliPath: string | undefined;
let usingExpo = false; let usingExpo = false;
try {
cliPath = require.resolve('@expo/cli', { const getExpoCli = () => {
paths: [process.cwd()], try {
}); cliPath = require.resolve('@expo/cli', {
const expoCliVersion = JSON.parse( paths: [process.cwd()],
fs.readFileSync( });
require.resolve('@expo/cli/package.json', { const expoCliVersion = JSON.parse(
paths: [process.cwd()], fs.readFileSync(
}), require.resolve('@expo/cli/package.json', {
), paths: [process.cwd()],
).version; }),
// expo cli 0.10.17 (expo 49) 开始支持 bundle:embed ),
if (semverSatisfies(expoCliVersion, '>= 0.10.17')) { ).version;
usingExpo = true; // expo cli 0.10.17 (expo 49) 开始支持 bundle:embed
} if (semverSatisfies(expoCliVersion, '>= 0.10.17')) {
} catch (e) {} usingExpo = true;
if (!usingExpo) { } else {
cliPath = undefined;
}
} catch (e) {}
};
const getRnCli = () => {
try { try {
// rn >= 0.75 // rn >= 0.75
cliPath = require.resolve('@react-native-community/cli/build/bin.js', { cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
@@ -89,20 +107,49 @@ async function runReactNativeBundleCommand(
paths: [process.cwd()], paths: [process.cwd()],
}); });
} }
};
const getTaroCli = () => {
try {
cliPath = require.resolve('@tarojs/cli/bin/taro.js', {
paths: [process.cwd()],
});
} catch (e) {}
};
if (cli.expo) {
getExpoCli();
} else if (cli.taro) {
getTaroCli();
} else if (cli.rncli) {
getRnCli();
} }
if (!cliPath) {
getExpoCli();
if (!usingExpo) {
getRnCli();
}
}
const bundleParams = await checkPlugins(); const bundleParams = await checkPlugins();
const isSentry = bundleParams.sentry; const isSentry = bundleParams.sentry;
const bundleCommand = usingExpo
? 'export:embed' let bundleCommand = 'bundle';
: platform === 'harmony' if (usingExpo) {
? 'bundle-harmony' bundleCommand = 'export:embed';
: 'bundle'; } else if (platform === 'harmony') {
bundleCommand = 'bundle-harmony';
} else if (cli.taro) {
bundleCommand = 'build';
}
if (platform === 'harmony') { if (platform === 'harmony') {
Array.prototype.push.apply(reactNativeBundleArgs, [ Array.prototype.push.apply(reactNativeBundleArgs, [
cliPath, cliPath,
bundleCommand, bundleCommand,
'--dev', '--dev',
development, dev,
'--entry-file', '--entry-file',
entryFile, entryFile,
]); ]);
@@ -122,14 +169,24 @@ async function runReactNativeBundleCommand(
outputFolder, outputFolder,
'--bundle-output', '--bundle-output',
path.join(outputFolder, bundleName), path.join(outputFolder, bundleName),
'--dev',
development,
'--entry-file',
entryFile,
'--platform', '--platform',
platform, platform,
'--reset-cache', '--reset-cache',
]); ]);
if (cli.taro) {
reactNativeBundleArgs.push(...[
'--type',
'rn',
])
} else {
reactNativeBundleArgs.push(...[
'--dev',
dev,
'--entry-file',
entryFile,
])
}
if (sourcemapOutput) { if (sourcemapOutput) {
reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput); reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
@@ -165,7 +222,9 @@ async function runReactNativeBundleCommand(
let hermesEnabled: boolean | undefined = false; let hermesEnabled: boolean | undefined = false;
if (platform === 'android') { if (platform === 'android') {
const gradlePropeties = await new Promise<{ hermesEnabled?: boolean }>((resolve) => { const gradlePropeties = await new Promise<{
hermesEnabled?: boolean;
}>((resolve) => {
properties.parse( properties.parse(
'./android/gradle.properties', './android/gradle.properties',
{ path: true }, { path: true },
@@ -322,7 +381,11 @@ async function compileHermesByteCode(
} }
} }
async function copyDebugidForSentry(bundleName: string, outputFolder: string, sourcemapOutput: string) { async function copyDebugidForSentry(
bundleName: string,
outputFolder: string,
sourcemapOutput: string,
) {
if (sourcemapOutput) { if (sourcemapOutput) {
let copyDebugidPath; let copyDebugidPath;
try { try {
@@ -423,7 +486,10 @@ async function pack(dir: string, output: string) {
} }
const childs = fs.readdirSync(root); const childs = fs.readdirSync(root);
for (const name of childs) { for (const name of childs) {
if (ignorePackingFileNames.includes(name) || ignorePackingExtensions.some(ext => name.endsWith(`.${ext}`))) { if (
ignorePackingFileNames.includes(name) ||
ignorePackingExtensions.some((ext) => name.endsWith(`.${ext}`))
) {
continue; continue;
} }
const fullPath = path.join(root, name); const fullPath = path.join(root, name);
@@ -723,55 +789,66 @@ async function diffFromPackage(
await writePromise; await writePromise;
} }
export async function enumZipEntries(zipFn: string, callback: (entry: any, zipFile: any) => void, nestedPath = '') { export async function enumZipEntries(
zipFn: string,
callback: (entry: any, zipFile: any) => void,
nestedPath = '',
) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
openZipFile(zipFn, { lazyEntries: true }, async (err: any, zipfile: ZipFile) => { openZipFile(
if (err) { zipFn,
return reject(err); { lazyEntries: true },
} async (err: any, zipfile: ZipFile) => {
if (err) {
zipfile.on('end', resolve); return reject(err);
zipfile.on('error', reject);
zipfile.on('entry', async (entry) => {
const fullPath = nestedPath + entry.fileName;
try {
if (
!entry.fileName.endsWith('/') &&
entry.fileName.toLowerCase().endsWith('.hap')
) {
const tempDir = path.join(os.tmpdir(), `nested_zip_${Date.now()}`);
await fs.ensureDir(tempDir);
const tempZipPath = path.join(tempDir, 'temp.zip');
await new Promise((res, rej) => {
zipfile.openReadStream(entry, async (err, readStream) => {
if (err) return rej(err);
const writeStream = fs.createWriteStream(tempZipPath);
readStream.pipe(writeStream);
writeStream.on('finish', res);
writeStream.on('error', rej);
});
});
await enumZipEntries(tempZipPath, callback, `${fullPath}/`);
await fs.remove(tempDir);
}
const result = callback(entry, zipfile, fullPath);
if (result && typeof result.then === 'function') {
await result;
}
} catch (error) {
console.error('处理文件时出错:', error);
} }
zipfile.readEntry(); zipfile.on('end', resolve);
}); zipfile.on('error', reject);
zipfile.on('entry', async (entry) => {
const fullPath = nestedPath + entry.fileName;
zipfile.readEntry(); try {
}); if (
!entry.fileName.endsWith('/') &&
entry.fileName.toLowerCase().endsWith('.hap')
) {
const tempDir = path.join(
os.tmpdir(),
`nested_zip_${Date.now()}`,
);
await fs.ensureDir(tempDir);
const tempZipPath = path.join(tempDir, 'temp.zip');
await new Promise((res, rej) => {
zipfile.openReadStream(entry, async (err, readStream) => {
if (err) return rej(err);
const writeStream = fs.createWriteStream(tempZipPath);
readStream.pipe(writeStream);
writeStream.on('finish', res);
writeStream.on('error', rej);
});
});
await enumZipEntries(tempZipPath, callback, `${fullPath}/`);
await fs.remove(tempDir);
}
const result = callback(entry, zipfile, fullPath);
if (result && typeof result.then === 'function') {
await result;
}
} catch (error) {
console.error('处理文件时出错:', error);
}
zipfile.readEntry();
});
zipfile.readEntry();
},
);
}); });
} }
@@ -817,11 +894,20 @@ export const commands = {
options.platform || (await question('平台(ios/android/harmony):')), options.platform || (await question('平台(ios/android/harmony):')),
); );
const { bundleName, entryFile, intermediaDir, output, dev, sourcemap } = const {
translateOptions({ bundleName,
...options, entryFile,
platform, intermediaDir,
}); output,
dev,
sourcemap,
taro,
expo,
rncli,
} = translateOptions({
...options,
platform,
});
const bundleParams = await checkPlugins(); const bundleParams = await checkPlugins();
const sourcemapPlugin = bundleParams.sourcemap; const sourcemapPlugin = bundleParams.sourcemap;
@@ -839,20 +925,25 @@ export const commands = {
console.log(`Bundling with react-native: ${version}`); console.log(`Bundling with react-native: ${version}`);
await runReactNativeBundleCommand( await runReactNativeBundleCommand({
bundleName, bundleName,
dev, dev,
entryFile, entryFile,
intermediaDir, outputFolder: intermediaDir,
platform, platform,
sourcemap || sourcemapPlugin ? sourcemapOutput : '', sourcemapOutput: sourcemap || sourcemapPlugin ? sourcemapOutput : '',
); cli: {
taro,
expo,
rncli,
},
});
await pack(path.resolve(intermediaDir), realOutput); await pack(path.resolve(intermediaDir), realOutput);
const v = await question('是否现在上传此热更包?(Y/N)'); const v = await question('是否现在上传此热更包?(Y/N)');
if (v.toLowerCase() === 'y') { if (v.toLowerCase() === 'y') {
const versionName = await this.publish({ const versionName = await this.publish({
args: [realOutput], args: [realOutput],
options: { options: {
platform, platform,