feat: 完善一波代码 & 支持win(待测试验证)

This commit is contained in:
volare
2022-12-04 17:53:43 +08:00
parent 93a79f482f
commit 84d749a54d
10 changed files with 164 additions and 30 deletions

View File

@@ -1,6 +1,7 @@
import { IS_MAC } from '@/utils/platform.js';
import { IBuilder } from './base.js';
import MacBuilder from './MacBuilder.js';
import WinBuilder from './WinBulider.js';
export default class BuilderFactory {
static create(): IBuilder {

View File

@@ -7,8 +7,10 @@ import { IBuilder } from './base.js';
import { shellExec } from '@/utils/shell.js';
// @ts-expect-error 加上resolveJsonModule rollup会打包报错
import tauriConf from '../../src-tauri/tauri.conf.json';
import { fileURLToPath } from 'url';
import log from 'loglevel';
import { mergeTauriConfig } from './common.js';
import { npmDirectory } from '@/utils/dir.js';
import logger from '@/options/logger.js';
export default class MacBuilder implements IBuilder {
async prepare() {
@@ -33,34 +35,26 @@ export default class MacBuilder implements IBuilder {
async build(url: string, options: PakeAppOptions) {
log.debug('PakeAppOptions', options);
const { name } = options;
const { width, height, fullscreen, transparent, resizable, identifier, name } = options;
const tauriConfWindowOptions = {
width,
height,
fullscreen,
transparent,
resizable,
};
// TODO 下面这块逻辑还可以再拆 目前比较简单
Object.assign(tauriConf.tauri.windows[0], { url, ...tauriConfWindowOptions });
tauriConf.package.productName = name;
tauriConf.tauri.bundle.identifier = identifier;
tauriConf.tauri.bundle.icon = [options.icon];
const npmDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
const configJsonPath = path.join(npmDirectory, 'src-tauri/tauri.conf.json');
await fs.writeFile(configJsonPath, Buffer.from(JSON.stringify(tauriConf), 'utf-8'));
await mergeTauriConfig(url, options, tauriConf);
const code = await shellExec(`cd ${npmDirectory} && npm run build`);
const dmgName = `${name}_${tauriConf.package.version}_universal.dmg`;
const appPath = this.getBuildedAppPath(npmDirectory, dmgName);
await fs.copyFile(appPath, path.resolve(`${name}_universal.dmg`));
const distPath = path.resolve(`${name}_universal.dmg`);
await fs.copyFile(appPath, distPath);
await fs.unlink(appPath);
logger.success('Build success!');
logger.success('You can find the app installer in', distPath);
}
getBuildedAppPath(npmDirectory: string, dmgName: string) {
return path.join(npmDirectory, 'src-tauri/target/universal-apple-darwin/release/bundle/dmg', dmgName);
return path.join(
npmDirectory,
'src-tauri/target/universal-apple-darwin/release/bundle/dmg',
dmgName
);
}
}

View File

@@ -0,0 +1,60 @@
import fs from 'fs/promises';
import path from 'path';
import prompts from 'prompts';
import { checkRustInstalled, installRust } from '@/helpers/rust.js';
import { PakeAppOptions } from '@/types.js';
import { IBuilder } from './base.js';
import { shellExec } from '@/utils/shell.js';
// @ts-expect-error 加上resolveJsonModule rollup会打包报错
import tauriConf from '../../src-tauri/tauri.conf.json';
import { fileURLToPath } from 'url';
import logger from '@/options/logger.js';
import { mergeTauriConfig } from './common.js';
import { npmDirectory } from '@/utils/dir.js';
export default class WinBuilder implements IBuilder {
async prepare() {
logger.info(
'To build the Windows app, you need to install Rust and VS Build Tools.'
);
logger.info(
'See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing\n'
);
if (checkRustInstalled()) {
return;
}
const res = await prompts({
type: 'confirm',
message: 'We detected that you have not installed Rust. Install it now?',
name: 'value',
});
if (res.value) {
// TODO 国内有可能会超时
await installRust();
} else {
logger.error('Error: Pake needs Rust to package your webapp!!!');
process.exit(2);
}
}
async build(url: string, options: PakeAppOptions) {
logger.debug('PakeAppOptions', options);
await mergeTauriConfig(url, options, tauriConf);
const code = await shellExec(`cd ${npmDirectory} && npm run build:windows`);
// const dmgName = `${name}_${tauriConf.package.version}_universal.dmg`;
// const appPath = this.getBuildedAppPath(npmDirectory, dmgName);
// await fs.copyFile(appPath, path.resolve(`${name}_universal.dmg`));
}
getBuildedAppPath(npmDirectory: string, dmgName: string) {
return path.join(
npmDirectory,
'src-tauri/target/universal-apple-darwin/release/bundle/dmg',
dmgName
);
}
}

View File

@@ -1,4 +1,8 @@
import { PakeAppOptions } from '@/types.js';
import prompts from 'prompts';
import path from 'path';
import fs from 'fs/promises';
import { npmDirectory } from '@/utils/dir.js';
export async function promptText(message: string, initial?: string) {
const response = await prompts({
@@ -9,3 +13,39 @@ export async function promptText(message: string, initial?: string) {
});
return response.content;
}
export async function mergeTauriConfig(
url: string,
options: PakeAppOptions,
tauriConf: any
) {
const {
width,
height,
fullscreen,
transparent,
resizable,
identifier,
name,
} = options;
const tauriConfWindowOptions = {
width,
height,
fullscreen,
transparent,
resizable,
};
Object.assign(tauriConf.tauri.windows[0], { url, ...tauriConfWindowOptions });
tauriConf.package.productName = name;
tauriConf.tauri.bundle.identifier = identifier;
tauriConf.tauri.bundle.icon = [options.icon];
const configJsonPath = path.join(npmDirectory, 'src-tauri/tauri.conf.json');
await fs.writeFile(
configJsonPath,
Buffer.from(JSON.stringify(tauriConf), 'utf-8')
);
}

6
bin/cli.ts vendored
View File

@@ -1,5 +1,6 @@
import { program, createArgument } from 'commander';
import { program } from 'commander';
import log from 'loglevel';
import chalk from 'chalk';
import { DEFAULT_PAKE_OPTIONS } from './defaults.js';
import { PakeCliOptions } from './types.js';
import { validateNumberInput, validateUrlInput } from './utils/validate.js';
@@ -8,8 +9,9 @@ import BuilderFactory from './builders/BuilderFactory.js';
import { checkUpdateTips } from './helpers/updater.js';
// @ts-expect-error
import packageJson from '../../package.json';
import logger from './options/logger.js';
program.version(packageJson.version).description('A cli application can package a web page to desktop application');
program.version(packageJson.version).description('A cli application can package a web page to desktop application.');
program
.showHelpAfterError()

8
bin/helpers/rust.ts vendored
View File

@@ -1,12 +1,16 @@
import { IS_WIN } from '@/utils/platform.js';
import ora from 'ora';
import shelljs from 'shelljs';
import { shellExec } from '../utils/shell.js';
const InstallRustScript = "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y";
const RustInstallScriptFocMac =
"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y";
const RustInstallScriptForWin = 'winget install --id Rustlang.Rustup';
export async function installRust() {
const spinner = ora('Downloading Rust').start();
try {
await shellExec(InstallRustScript);
await shellExec(IS_WIN ? RustInstallScriptForWin : RustInstallScriptFocMac);
spinner.succeed();
} catch (error) {
console.error('install rust return code', error.message);

4
bin/options/icon.ts vendored
View File

@@ -5,7 +5,7 @@ import { dir } from 'tmp-promise';
import path from 'path';
import fs from 'fs/promises';
import { fileURLToPath } from 'url';
import log from 'loglevel';
import logger from './logger.js';
export async function handleIcon(options: PakeAppOptions, url: string) {
if (options.icon) {
@@ -21,7 +21,7 @@ export async function handleIcon(options: PakeAppOptions, url: string) {
}
export async function inferIcon(name: string, url: string) {
log.info('You have not provided an app icon, use the default icon(can use --icon option to assign an icon)')
logger.info('You have not provided an app icon, use the default icon.(use --icon option to assign an icon)')
const npmDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
return path.join(npmDirectory, 'pake-default.icns');
}

22
bin/options/logger.ts vendored Normal file
View File

@@ -0,0 +1,22 @@
import log from 'loglevel';
import chalk from 'chalk';
const logger = {
info(...msg: any[]) {
log.info(...msg.map((m) => chalk.blue.bold(m)));
},
debug(...msg: any[]) {
log.debug(...msg);
},
error(...msg: any[]) {
log.error(...msg.map((m) => chalk.red.bold(m)));
},
warn(...msg: any[]) {
log.info(...msg.map((m) => chalk.yellow.bold(m)));
},
success(...msg: any[]) {
log.info(...msg.map((m) => chalk.green.bold(m)));
}
};
export default logger;

8
bin/utils/dir.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
import path from 'path';
import { fileURLToPath } from 'url';
export const npmDirectory = path.join(
path.dirname(fileURLToPath(import.meta.url)),
'..'
);

View File

@@ -26,7 +26,7 @@
"build": "npm run tauri build -- --target universal-apple-darwin",
"build:windows": "npm run tauri build -- --target x86_64-pc-windows-msvc",
"build:linux": "npm run tauri build --release",
"build:all-unix":"chmod +x ./script/build.sh && ./script/build.sh",
"build:all-unix": "chmod +x ./script/build.sh && ./script/build.sh",
"build:all-windows": ".\\script\\build.bat",
"tauri": "tauri",
"cli": "rollup -c rollup.config.js --watch",
@@ -40,6 +40,7 @@
"@tauri-apps/api": "^1.2.0",
"@tauri-apps/cli": "^1.2.1",
"axios": "^1.1.3",
"chalk": "^5.1.2",
"commander": "^9.4.1",
"file-type": "^18.0.0",
"is-url": "^1.2.4",
@@ -47,7 +48,8 @@
"ora": "^6.1.2",
"prompts": "^2.4.2",
"shelljs": "^0.8.5",
"tmp-promise": "^3.0.3"
"tmp-promise": "^3.0.3",
"update-notifier": "^6.0.2"
},
"devDependencies": {
"@rollup/plugin-alias": "^4.0.2",
@@ -60,6 +62,7 @@
"@types/prompts": "^2.4.1",
"@types/shelljs": "^0.8.11",
"@types/tmp": "^0.2.3",
"@types/update-notifier": "^6.0.1",
"app-root-path": "^3.1.0",
"concurrently": "^7.5.0",
"cross-env": "^7.0.3",