Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 112 additions & 3 deletions src/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getRNVersion, translateOptions } from './utils';
import * as fs from 'fs-extra';
import { ZipFile } from 'yazl';
import { open as openZipFile } from 'yauzl';
import { question, printVersionCommand } from './utils';
import { question, checkPlugins } from './utils';
import { checkPlatform } from './app';
import { spawn, spawnSync } from 'node:child_process';
import semverSatisfies from 'semver/functions/satisfies';
Expand Down Expand Up @@ -86,6 +86,9 @@ async function runReactNativeBundleCommand(
});
}
}
const bundleParams = await checkPlugins();
const minifyOption = bundleParams.minify;
const isSentry = bundleParams.sentry;
const bundleCommand = usingExpo
? 'export:embed'
: platform === 'harmony'
Expand Down Expand Up @@ -123,6 +126,8 @@ async function runReactNativeBundleCommand(
'--platform',
platform,
'--reset-cache',
'--minify',
minifyOption,
]);

if (sourcemapOutput) {
Expand Down Expand Up @@ -190,6 +195,7 @@ async function runReactNativeBundleCommand(
bundleName,
outputFolder,
sourcemapOutput,
!isSentry,
);
}
resolve(null);
Expand Down Expand Up @@ -253,6 +259,7 @@ async function compileHermesByteCode(
bundleName,
outputFolder,
sourcemapOutput,
shouldCleanSourcemap,
) {
console.log('Hermes enabled, now compiling to hermes bytecode:\n');
// >= rn 0.69
Expand Down Expand Up @@ -309,9 +316,98 @@ async function compileHermesByteCode(
},
);
}
if (shouldCleanSourcemap) {
fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`));
}
}

async function copyDebugidForSentry(bundleName, outputFolder, sourcemapOutput) {
if (sourcemapOutput) {
let copyDebugidPath;
try {
copyDebugidPath = require.resolve(
'@sentry/react-native/scripts/copy-debugid.js',
{
paths: [process.cwd()],
},
);
} catch (error) {
console.error(
'无法找到 Sentry copy-debugid.js 脚本文件,请确保已正确安装 @sentry/react-native',
);
return;
}

if (!fs.existsSync(copyDebugidPath)) {
return;
}
console.log('Copying debugid');
spawnSync(
'node',
[
copyDebugidPath,
path.join(outputFolder, `${bundleName}.txt.map`),
path.join(outputFolder, `${bundleName}.map`),
],
{
stdio: 'ignore',
},
);
}
fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`));
}

async function uploadSourcemapForSentry(
bundleName,
outputFolder,
sourcemapOutput,
version,
) {
if (sourcemapOutput) {
let sentryCliPath;
try {
sentryCliPath = require.resolve('@sentry/cli/bin/sentry-cli', {
paths: [process.cwd()],
});
} catch (error) {
console.error('无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli');
return;
}

if (!fs.existsSync(sentryCliPath)) {
return;
}

spawnSync(
'node',
[sentryCliPath, 'releases', 'set-commits', version, '--auto'],
{
stdio: 'inherit',
},
);
console.log(`Sentry release created for version: ${version}`);

console.log('Uploading sourcemap');
spawnSync(
'node',
[
sentryCliPath,
'releases',
'files',
version,
'upload-sourcemaps',
'--strip-prefix',
path.join(process.cwd(), outputFolder),
path.join(outputFolder, bundleName),
path.join(outputFolder, `${bundleName}.map`),
],
{
stdio: 'inherit',
},
);
}
}

async function pack(dir, output) {
console.log('Packing');
fs.ensureDirSync(path.dirname(output));
Expand Down Expand Up @@ -718,12 +814,16 @@ export const commands = {
options.platform || (await question('平台(ios/android/harmony):')),
);

const { bundleName, entryFile, intermediaDir, output, dev, sourcemap } =
const { bundleName, entryFile, intermediaDir, output, dev } =
translateOptions({
...options,
platform,
});

const bundleParams = await checkPlugins();
const sourcemap = bundleParams.sourcemap;
const isSentry = bundleParams.sentry;

const sourcemapOutput = path.join(intermediaDir, `${bundleName}.map`);

const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
Expand All @@ -749,12 +849,21 @@ export const commands = {

const v = await question('是否现在上传此热更包?(Y/N)');
if (v.toLowerCase() === 'y') {
await this.publish({
const versionName = await this.publish({
args: [realOutput],
options: {
platform,
},
});
if (isSentry) {
await copyDebugidForSentry(bundleName, intermediaDir, sourcemapOutput);
await uploadSourcemapForSentry(
bundleName,
intermediaDir,
sourcemapOutput,
versionName,
);
}
}
},

Expand Down
30 changes: 30 additions & 0 deletions src/utils/check-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { plugins } from './plugin-config';

interface BundleParams {
sentry: boolean;
minify: boolean;
sourcemap: boolean;
[key: string]: any;
}

export async function checkPlugins(): Promise<BundleParams> {
const params: BundleParams = {
sentry: false,
minify: true,
sourcemap: false,
};

for (const plugin of plugins) {
try {
const isEnabled = await plugin.detect();
if (isEnabled && plugin.bundleParams) {
Object.assign(params, plugin.bundleParams);
console.log(`检测到 ${plugin.name} 插件,应用相应打包配置`);
}
} catch (err) {
console.warn(`检测 ${plugin.name} 插件时出错:`, err);
}
}

return params;
}
3 changes: 3 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import AppInfoParser from './app-info-parser';
import semverSatisfies from 'semver/functions/satisfies';
import chalk from 'chalk';
import latestVersion from '@badisi/latest-version';
import { checkPlugins } from './check-plugin';

import { read } from 'read';

Expand Down Expand Up @@ -225,3 +226,5 @@ export async function printVersionCommand() {
}

export const pricingPageUrl = 'https://pushy.reactnative.cn/pricing.html';

export { checkPlugins };
34 changes: 34 additions & 0 deletions src/utils/plugin-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import fs from 'fs-extra';

interface PluginConfig {
name: string;
bundleParams?: {
minify?: boolean;
[key: string]: any;
};
detect: () => Promise<boolean>;
}

export const plugins: PluginConfig[] = [
{
name: 'sentry',
bundleParams: {
sentry: true,
minify: false,
sourcemap: true,
},
detect: async () => {
try {
await fs.access('ios/sentry.properties');
return true;
} catch {
try {
await fs.access('android/sentry.properties');
return true;
} catch {
return false;
}
}
}
}
];
4 changes: 3 additions & 1 deletion src/versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ export const commands = {

const { hash } = await uploadFile(fn);

const versionName = name || (await question('输入版本名称: ')) || '(未命名)';
const { id } = await post(`/app/${appId}/version/create`, {
name: name || (await question('输入版本名称: ')) || '(未命名)',
name: versionName,
hash,
description: description || (await question('输入版本描述:')),
metaInfo: metaInfo || (await question('输入自定义的 meta info:')),
Expand All @@ -111,6 +112,7 @@ export const commands = {
if (v.toLowerCase() === 'y') {
await this.update({ args: [], options: { versionId: id, platform } });
}
return versionName;
},
versions: async ({ options }) => {
const platform = checkPlatform(
Expand Down
Loading