Merge pull request #535 from tw93/dev
merge: Cli support inject js/css files to app and set app safe domains - Inject css/js files to app - Support setting app safeDomains - More comfortable development mode for CLI power users
This commit is contained in:
7
bin/builders/BaseBuilder.ts
vendored
7
bin/builders/BaseBuilder.ts
vendored
@@ -71,6 +71,10 @@ export default abstract class BaseBuilder {
|
||||
await this.buildAndCopy(url, this.options.targets);
|
||||
}
|
||||
|
||||
async start(url: string) {
|
||||
await mergeConfig(url, this.options, tauriConfig);
|
||||
}
|
||||
|
||||
async buildAndCopy(url: string, target: string) {
|
||||
const { name } = this.options;
|
||||
await mergeConfig(url, this.options, tauriConfig);
|
||||
@@ -98,7 +102,8 @@ export default abstract class BaseBuilder {
|
||||
abstract getFileName(): string;
|
||||
|
||||
protected getBuildCommand(): string {
|
||||
return 'npm run build';
|
||||
// the debug option should support `--debug` and `--release`
|
||||
return this.options.debug ? 'npm run build:debug' : 'npm run build';
|
||||
}
|
||||
|
||||
protected getBasePath(): string {
|
||||
|
||||
2
bin/cli.ts
vendored
2
bin/cli.ts
vendored
@@ -38,6 +38,8 @@ program
|
||||
.option('--iter-copy-file', 'Copy files when URL is a local file', DEFAULT.iterCopyFile)
|
||||
.option('--multi-arch', 'Only for Mac, supports both Intel and M1', DEFAULT.multiArch)
|
||||
.option('--targets <string>', 'Only for Linux, option "deb" or "appimage"', DEFAULT.targets)
|
||||
.option('--inject [injects...]', 'Inject .js or .css for this app', DEFAULT.inject)
|
||||
.option('--safe-domain [domains...]', 'Please enter the security domains that need to be configured', DEFAULT.safeDomain)
|
||||
.option('--debug', 'Debug mode', DEFAULT.debug)
|
||||
.version(packageJson.version, '-v, --version', 'Output the current version')
|
||||
.action(async (url: string, options: PakeCliOptions) => {
|
||||
|
||||
9
bin/defaults.ts
vendored
9
bin/defaults.ts
vendored
@@ -15,4 +15,13 @@ export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = {
|
||||
iterCopyFile: false,
|
||||
systemTrayIcon: '',
|
||||
debug: false,
|
||||
inject: [],
|
||||
safeDomain: [],
|
||||
};
|
||||
|
||||
// just for cli development
|
||||
export const DEFAULT_DEV_PAKE_OPTIONS: PakeCliOptions & {url: string} = {
|
||||
...DEFAULT_PAKE_OPTIONS,
|
||||
url: 'https://weread.qq.com',
|
||||
name: 'Weread',
|
||||
}
|
||||
17
bin/dev.ts
vendored
Normal file
17
bin/dev.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import log from 'loglevel';
|
||||
import {DEFAULT_DEV_PAKE_OPTIONS} from './defaults';
|
||||
import handleInputOptions from './options/index';
|
||||
import BuilderProvider from './builders/BuilderProvider';
|
||||
|
||||
async function startBuild() {
|
||||
log.setDefaultLevel('debug');
|
||||
|
||||
const appOptions = await handleInputOptions(DEFAULT_DEV_PAKE_OPTIONS, DEFAULT_DEV_PAKE_OPTIONS.url);
|
||||
log.debug('PakeAppOptions', appOptions);
|
||||
|
||||
const builder = BuilderProvider.create(appOptions);
|
||||
await builder.prepare();
|
||||
await builder.start(DEFAULT_DEV_PAKE_OPTIONS.url);
|
||||
}
|
||||
|
||||
startBuild();
|
||||
75
bin/helpers/merge.ts
vendored
75
bin/helpers/merge.ts
vendored
@@ -2,8 +2,10 @@ import path from 'path';
|
||||
import fsExtra from 'fs-extra';
|
||||
|
||||
import { npmDirectory } from '@/utils/dir';
|
||||
import combineFiles from '@/utils/combine';
|
||||
import logger from '@/options/logger';
|
||||
import { PakeAppOptions, PlatformMap } from '@/types';
|
||||
import { tauriConfigDirectory } from '../utils/dir';
|
||||
|
||||
export async function mergeConfig(url: string, options: PakeAppOptions, tauriConf: any) {
|
||||
const {
|
||||
@@ -19,6 +21,8 @@ export async function mergeConfig(url: string, options: PakeAppOptions, tauriCon
|
||||
identifier,
|
||||
name,
|
||||
resizable = true,
|
||||
inject,
|
||||
safeDomain,
|
||||
} = options;
|
||||
|
||||
const { platform } = process;
|
||||
@@ -57,9 +61,7 @@ export async function mergeConfig(url: string, options: PakeAppOptions, tauriCon
|
||||
|
||||
const filesToCopyBack = ['cli.js', 'about_pake.html'];
|
||||
await Promise.all(
|
||||
filesToCopyBack.map(file =>
|
||||
fsExtra.copy(path.join(distBakDir, file), path.join(distDir, file)),
|
||||
),
|
||||
filesToCopyBack.map(file => fsExtra.copy(path.join(distBakDir, file), path.join(distDir, file))),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -68,7 +70,24 @@ export async function mergeConfig(url: string, options: PakeAppOptions, tauriCon
|
||||
} else {
|
||||
tauriConf.pake.windows[0].url_type = 'web';
|
||||
// Set the secure domain for calling window.__TAURI__ to the application domain that has been set.
|
||||
tauriConf.tauri.security.dangerousRemoteDomainIpcAccess[0].domain = new URL(url).hostname;
|
||||
tauriConf.tauri.security.dangerousRemoteDomainIpcAccess = [
|
||||
{
|
||||
domain: new URL(url).hostname,
|
||||
windows: ['pake'],
|
||||
enableTauriAPI: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (safeDomain.length > 0) {
|
||||
tauriConf.tauri.security.dangerousRemoteDomainIpcAccess = [
|
||||
...tauriConf.tauri.security.dangerousRemoteDomainIpcAccess,
|
||||
...safeDomain.map(domain => ({
|
||||
domain,
|
||||
windows: ['pake'],
|
||||
enableTauriAPI: true,
|
||||
})),
|
||||
];
|
||||
}
|
||||
|
||||
const platformMap: PlatformMap = {
|
||||
@@ -90,12 +109,9 @@ export async function mergeConfig(url: string, options: PakeAppOptions, tauriCon
|
||||
delete tauriConf.tauri.bundle.deb.files;
|
||||
const validTargets = ['all', 'deb', 'appimage'];
|
||||
if (validTargets.includes(options.targets)) {
|
||||
tauriConf.tauri.bundle.targets =
|
||||
options.targets === 'all' ? ['deb', 'appimage'] : [options.targets];
|
||||
tauriConf.tauri.bundle.targets = options.targets === 'all' ? ['deb', 'appimage'] : [options.targets];
|
||||
} else {
|
||||
logger.warn(
|
||||
`✼ The target must be one of ${validTargets.join(', ')}, the default 'deb' will be used.`,
|
||||
);
|
||||
logger.warn(`✼ The target must be one of ${validTargets.join(', ')}, the default 'deb' will be used.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,10 +170,7 @@ export async function mergeConfig(url: string, options: PakeAppOptions, tauriCon
|
||||
// 需要判断图标格式,默认只支持ico和png两种
|
||||
let iconExt = path.extname(systemTrayIcon).toLowerCase();
|
||||
if (iconExt == '.png' || iconExt == '.ico') {
|
||||
const trayIcoPath = path.join(
|
||||
npmDirectory,
|
||||
`src-tauri/png/${name.toLowerCase()}${iconExt}`,
|
||||
);
|
||||
const trayIcoPath = path.join(npmDirectory, `src-tauri/png/${name.toLowerCase()}${iconExt}`);
|
||||
trayIconPath = `png/${name.toLowerCase()}${iconExt}`;
|
||||
await fsExtra.copy(systemTrayIcon, trayIcoPath);
|
||||
} else {
|
||||
@@ -171,24 +184,40 @@ export async function mergeConfig(url: string, options: PakeAppOptions, tauriCon
|
||||
}
|
||||
|
||||
tauriConf.tauri.systemTray.iconPath = trayIconPath;
|
||||
const injectFilePath = path.join(npmDirectory, `src-tauri/src/inject/custom.js`);
|
||||
// inject js or css files
|
||||
if (inject?.length > 0) {
|
||||
if (!inject.every(item => item.endsWith('.css') || item.endsWith('.js'))) {
|
||||
logger.error('The injected file must be in either CSS or JS format.');
|
||||
return;
|
||||
}
|
||||
const files = inject.map(filepath => path.isAbsolute(filepath) ? filepath : path.join(process.cwd(), filepath));
|
||||
tauriConf.pake.inject = files;
|
||||
await combineFiles(files, injectFilePath);
|
||||
} else {
|
||||
tauriConf.pake.inject = [];
|
||||
await fsExtra.writeFile(injectFilePath, '');
|
||||
}
|
||||
|
||||
// Save config file.
|
||||
const platformConfigPaths: PlatformMap = {
|
||||
win32: 'src-tauri/tauri.windows.conf.json',
|
||||
darwin: 'src-tauri/tauri.macos.conf.json',
|
||||
linux: 'src-tauri/tauri.linux.conf.json',
|
||||
win32: 'tauri.windows.conf.json',
|
||||
darwin: 'tauri.macos.conf.json',
|
||||
linux: 'tauri.linux.conf.json',
|
||||
};
|
||||
const configPath = path.join(npmDirectory, platformConfigPaths[platform]);
|
||||
const configPath = path.join(tauriConfigDirectory, platformConfigPaths[platform]);
|
||||
|
||||
const bundleConf = { tauri: { bundle: tauriConf.tauri.bundle } };
|
||||
await fsExtra.writeJson(configPath, bundleConf, { spaces: 4 });
|
||||
|
||||
const pakeConfigPath = path.join(npmDirectory, 'src-tauri/pake.json');
|
||||
await fsExtra.writeJson(pakeConfigPath, tauriConf.pake, { spaces: 4 });
|
||||
await fsExtra.outputJSON(configPath, bundleConf, { spaces: 4 });
|
||||
const pakeConfigPath = path.join(tauriConfigDirectory, 'pake.json');
|
||||
await fsExtra.outputJSON(pakeConfigPath, tauriConf.pake, { spaces: 4 });
|
||||
|
||||
let tauriConf2 = JSON.parse(JSON.stringify(tauriConf));
|
||||
delete tauriConf2.pake;
|
||||
delete tauriConf2.tauri.bundle;
|
||||
const configJsonPath = path.join(npmDirectory, 'src-tauri/tauri.conf.json');
|
||||
await fsExtra.writeJson(configJsonPath, tauriConf2, { spaces: 4 });
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
tauriConf2.tauri.bundle = bundleConf.tauri.bundle;
|
||||
}
|
||||
const configJsonPath = path.join(tauriConfigDirectory, 'tauri.conf.json');
|
||||
await fsExtra.outputJSON(configJsonPath, tauriConf2, { spaces: 4 });
|
||||
}
|
||||
|
||||
6
bin/types.ts
vendored
6
bin/types.ts
vendored
@@ -47,6 +47,12 @@ export interface PakeCliOptions {
|
||||
|
||||
// Debug mode, outputs more logs
|
||||
debug: boolean;
|
||||
|
||||
/** 需要注入页面的外部脚本 */
|
||||
inject: string[];
|
||||
|
||||
/* the domain that can use ipc or tauri javascript sdk */
|
||||
safeDomain: string[];
|
||||
}
|
||||
|
||||
export interface PakeAppOptions extends PakeCliOptions {
|
||||
|
||||
14
bin/utils/combine.ts
vendored
Normal file
14
bin/utils/combine.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import fs from 'fs';
|
||||
|
||||
export default async function combineFiles(files: string[], output: string) {
|
||||
const contents = files.map(file => {
|
||||
const fileContent = fs.readFileSync(file);
|
||||
if (file.endsWith('.css')) {
|
||||
return "window.addEventListener('DOMContentLoaded', (_event) => { const css = `" + fileContent + "`; const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); });";
|
||||
}
|
||||
|
||||
return "window.addEventListener('DOMContentLoaded', (_event) => { " + fileContent + " });";
|
||||
});
|
||||
fs.writeFileSync(output, contents.join('\n'));
|
||||
return files;
|
||||
}
|
||||
2
bin/utils/dir.ts
vendored
2
bin/utils/dir.ts
vendored
@@ -6,3 +6,5 @@ const currentModulePath = fileURLToPath(import.meta.url);
|
||||
|
||||
// Resolve the parent directory of the current module
|
||||
export const npmDirectory = path.join(path.dirname(currentModulePath), '..');
|
||||
|
||||
export const tauriConfigDirectory = process.env.NODE_ENV === 'development' ? path.join(npmDirectory, 'src-tauri', '.pake') : path.join(npmDirectory, 'src-tauri');
|
||||
Reference in New Issue
Block a user