feat: 脚手架基本ok

This commit is contained in:
volare
2022-11-22 00:24:06 +08:00
parent c1981f2951
commit 22b9b2878d
29 changed files with 4001 additions and 9 deletions

1
.gitignore vendored
View File

@@ -14,6 +14,7 @@ dist-ssr
# Editor directories and files
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea
.DS_Store
*.suo

8
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"cSpell.words": [
"loglevel",
"Pake",
"tauri"
],
"typescript.preferences.importModuleSpecifierEnding": "js"
}

View File

@@ -82,8 +82,28 @@
## 注意点
- Windows 下不能安装到 C:\Program File会直接闪退。建议安装到其他目录比如 D:\Program Files。
- Linux 下暂时不能存 cookie即应用关闭后数据清空账号自动推出。
- Windows 下不能安装到 C:\Program File会直接闪退。建议安装到其他目录比如 D:\Program Files。
- Linux 下暂时不能存 cookie即应用关闭后数据清空账号自动推出。
## 使用命令行打包
Pake 提供了命令行工具,可以更快捷方便地打包。(目前仅支持 MacOS
### 安装
```bash
npm install -g pake
```
如果安装失败提示没有权限,请使用 `sudo` 运行。
### 用法
```bash
pake [options] url
```
更多用法可查看[文档](./bin//README.md)。
## 开发
@@ -114,6 +134,8 @@ chmod +x ./script/build.sh && ./script/build.sh
## 打新包
### 自己构建
1. 修改 `src-tauri` 目录下的 `tauri.conf.json` 中的 `url、productName、icon、identifier` 这 4 个字段,其中 icon 可以从 icons 目录选择一个,也可以去 [macOSicons](https://macosicons.com/#/) 下载符合产品名称的
2. 关于窗口属性设置,可以在 `tauri.conf.json` 修改 `windows` 属性对应的 `width/height`,是否全屏 `fullscreen`,是否可以调整大小 `resizable`,假如想适配 Mac 沉浸式头部,可以将 `transparent` 设置成 `true`,找到 Header 元素加一个 `padding-top` 样式即可,不想适配改成 `false` 也行
3. `npm run dev` 本地调试看看效果,此外可以使用 `npm run dev:debug` 进行容器调试
@@ -221,9 +243,9 @@ chmod +x ./script/build.sh && ./script/build.sh
## 支持
- 我有两只猫,一只叫汤圆,一只叫可乐,假如觉得 Pake 让你生活更美好,可以给汤圆可乐 <a href="https://miaoyan.app/cats.html?name=Pake" target="_blank">喂罐头 🥩🍤</a>。
- 如果你喜欢 Pake可以在 Github Star更欢迎 [推荐](https://twitter.com/intent/tweet?url=https://github.com/tw93/Pake&text=Pake%20%E4%B8%80%E4%B8%AA%E5%BE%88%E7%AE%80%E5%8D%95%E7%9A%84%E7%94%A8%20Rust%20%E6%89%93%E5%8C%85%E7%BD%91%E9%A1%B5%E7%94%9F%E6%88%90%20Mac%20App%20%E7%9A%84%E5%B7%A5%E5%85%B7%EF%BC%8C%E7%9B%B8%E6%AF%94%E4%BC%A0%E7%BB%9F%E7%9A%84%20Electron%20%E5%A5%97%E5%A3%B3%E6%89%93%E5%8C%85%EF%BC%8C%E5%A4%A7%E5%B0%8F%E8%A6%81%E5%B0%8F%E5%B0%86%E8%BF%91%2040%20%E5%80%8D%EF%BC%8C%E4%B8%80%E8%88%AC%202M%20%E5%B7%A6%E5%8F%B3%EF%BC%8C%E5%BA%95%E5%B1%82%E4%BD%BF%E7%94%A8Tauri%20%EF%BC%8C%E6%80%A7%E8%83%BD%E4%BD%93%E9%AA%8C%E8%BE%83%20JS%20%E6%A1%86%E6%9E%B6%E8%A6%81%E8%BD%BB%E5%BF%AB%E4%B8%8D%E5%B0%91%EF%BC%8C%E5%86%85%E5%AD%98%E5%B0%8F%E5%BE%88%E5%A4%9A%EF%BC%8C%E6%94%AF%E6%8C%81%E5%BE%AE%E4%BF%A1%E8%AF%BB%E4%B9%A6%E3%80%81Twitter%E3%80%81Youtube%E3%80%81RunCode%E3%80%81Flomo%E3%80%81%E8%AF%AD%E9%9B%80%E7%AD%89%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%BE%88%E6%96%B9%E4%BE%BF%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91~) 给你志同道合的朋友使用。
- 可以关注我的 [Twitter](https://twitter.com/HiTw93) 获取到最新的 Pake 更新消息,也欢迎加入 [Telegram](https://t.me/miaoyan) 聊天群。
- 我有两只猫,一只叫汤圆,一只叫可乐,假如觉得 Pake 让你生活更美好,可以给汤圆可乐 <a href="https://miaoyan.app/cats.html?name=Pake" target="_blank">喂罐头 🥩🍤</a>。
- 如果你喜欢 Pake可以在 Github Star更欢迎 [推荐](https://twitter.com/intent/tweet?url=https://github.com/tw93/Pake&text=Pake%20%E4%B8%80%E4%B8%AA%E5%BE%88%E7%AE%80%E5%8D%95%E7%9A%84%E7%94%A8%20Rust%20%E6%89%93%E5%8C%85%E7%BD%91%E9%A1%B5%E7%94%9F%E6%88%90%20Mac%20App%20%E7%9A%84%E5%B7%A5%E5%85%B7%EF%BC%8C%E7%9B%B8%E6%AF%94%E4%BC%A0%E7%BB%9F%E7%9A%84%20Electron%20%E5%A5%97%E5%A3%B3%E6%89%93%E5%8C%85%EF%BC%8C%E5%A4%A7%E5%B0%8F%E8%A6%81%E5%B0%8F%E5%B0%86%E8%BF%91%2040%20%E5%80%8D%EF%BC%8C%E4%B8%80%E8%88%AC%202M%20%E5%B7%A6%E5%8F%B3%EF%BC%8C%E5%BA%95%E5%B1%82%E4%BD%BF%E7%94%A8Tauri%20%EF%BC%8C%E6%80%A7%E8%83%BD%E4%BD%93%E9%AA%8C%E8%BE%83%20JS%20%E6%A1%86%E6%9E%B6%E8%A6%81%E8%BD%BB%E5%BF%AB%E4%B8%8D%E5%B0%91%EF%BC%8C%E5%86%85%E5%AD%98%E5%B0%8F%E5%BE%88%E5%A4%9A%EF%BC%8C%E6%94%AF%E6%8C%81%E5%BE%AE%E4%BF%A1%E8%AF%BB%E4%B9%A6%E3%80%81Twitter%E3%80%81Youtube%E3%80%81RunCode%E3%80%81Flomo%E3%80%81%E8%AF%AD%E9%9B%80%E7%AD%89%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%BE%88%E6%96%B9%E4%BE%BF%E4%BA%8C%E6%AC%A1%E5%BC%80%E5%8F%91~) 给你志同道合的朋友使用。
- 可以关注我的 [Twitter](https://twitter.com/HiTw93) 获取到最新的 Pake 更新消息,也欢迎加入 [Telegram](https://t.me/miaoyan) 聊天群。
## 最后

72
bin/README.md Normal file
View File

@@ -0,0 +1,72 @@
## 安装
```bash
npm install -g pake
```
如果安装失败提示没有权限,请使用 `sudo` 运行。
## 用法
```bash
pake [options] url
```
打包完成后的应用程序默认为当前工作目录。
Note: 打包需要用 `Rust` 环境,如果没有 `Rust`,会提示确认安装。如遇安装失败或超时,可[自行安装](https://www.rust-lang.org/tools/install)。
Note: 目前仅支持 MacOs后续会支持其他平台。
### url
url 为你需要打包的网页链接🔗,必须提供。
### [options]
提供了一些特定的选项,打包时可以传递对应参数达到定制化的效果。
#### [name]
应用名称,如输入时未指定,会提示你输入。
```shell
--name <value>
```
#### [icon]
应用icon支持本地/远程文件,默认为 Pake 自带图标。
- MacOS下必须为 `.icns`
```shell
--icon <path>
```
#### [height]
打包后的应用窗口高度,默认 `800px`
```
--height <number>
```
#### [width]
打包后的应用窗口宽度,默认 `1280px`
```
--width <number>
```
#### [transparent]
是否开启沉浸式头部,默认为 `false` 不开启。
```
--transparent
```
#### [resize]
是否可以拖动大小,默认为 `true` 可拖动。
```
--no-resizable
```
#### [fullscreen]
打开应用后是否开启全屏,默认为 `false`
```
--fullscreen <value>
```

View File

@@ -0,0 +1,12 @@
import { IS_MAC } from '@/utils/platform.js';
import { IBuilder } from './base.js';
import MacBuilder from './MacBuilder.js';
export default class BuilderFactory {
static create(): IBuilder {
if (IS_MAC) {
return new MacBuilder();
}
throw new Error('The current system does not support');
}
}

View File

View File

@@ -0,0 +1,65 @@
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';
import tauriConf from '../../src-tauri/tauri.conf.json';
import { fileURLToPath } from 'url';
import log from 'loglevel';
export default class MacBuilder implements IBuilder {
async prepare() {
if (checkRustInstalled()) {
return;
}
const res = await prompts({
type: 'confirm',
message: 'Detect you have not installed Rust, install it now?',
name: 'value',
});
if (res.value) {
// TODO 国内有可能会超时
await installRust();
} else {
log.error('Error: Pake need Rust to package your webapp!!!');
process.exit(2);
}
}
async build(url: string, options: PakeAppOptions) {
log.debug('PakeAppOptions', 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'));
const code = await shellExec(`cd ${npmDirectory} && npm run build`);
const dmgName = `${name}_${'0.2.0'}_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

16
bin/builders/base.ts Normal file
View File

@@ -0,0 +1,16 @@
import { PakeAppOptions } from '@/types.js';
/**
* Builder接口
* 不同平台打包过程需要实现 prepare 和 build 方法
*/
export interface IBuilder {
/** 前置检查 */
prepare(): Promise<void>;
/**
* 开始打包
* @param url 打包url
* @param options 配置参数
*/
build(url: string, options: PakeAppOptions): Promise<void>;
}

11
bin/builders/common.ts Normal file
View File

@@ -0,0 +1,11 @@
import prompts from 'prompts';
export async function promptText(message: string, initial?: string) {
const response = await prompts({
type: 'text',
name: 'content',
message,
initial,
});
return response.content;
}

36
bin/cli.ts Normal file
View File

@@ -0,0 +1,36 @@
import { program } from 'commander';
import { DEFAULT_PAKE_OPTIONS } from './defaults.js';
import { PakeCliOptions } from './types.js';
import { validateNumberInput, validateUrlInput } from './utils/validate.js';
import handleInputOptions from './options/index.js';
import BuilderFactory from './builders/BuilderFactory.js';
import log from 'loglevel';
program.version('0.0.1').description('A cli application can package a web page to desktop application');
program
.showHelpAfterError()
.argument('<url>', 'the web url you want to package', validateUrlInput)
.option('--name <string>', 'application name')
.option('--icon <string>', 'application icon', DEFAULT_PAKE_OPTIONS.icon)
.option('--height <number>', 'window height', validateNumberInput, DEFAULT_PAKE_OPTIONS.height)
.option('--width <number>', 'window width', validateNumberInput, DEFAULT_PAKE_OPTIONS.width)
.option('--no-resizable', 'whether the window can be resizable', DEFAULT_PAKE_OPTIONS.resizable)
.option('--fullscreen', 'makes the packaged app start in full screen', DEFAULT_PAKE_OPTIONS.fullscreen)
.option('--transparent', 'transparent title bar', DEFAULT_PAKE_OPTIONS.transparent)
.option('--debug', 'debug', DEFAULT_PAKE_OPTIONS.transparent)
.action(async (url: string, options: PakeCliOptions) => {
log.setDefaultLevel('info')
if (options.debug) {
log.setLevel('debug');
}
const builder = BuilderFactory.create();
await builder.prepare();
const appOptions = await handleInputOptions(options, url);
builder.build(url, appOptions);
});
program.parse();

13
bin/defaults.ts Normal file
View File

@@ -0,0 +1,13 @@
import { PakeCliOptions } from './types.js';
export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = {
icon: '',
height: 800,
width: 1280,
fullscreen: false,
resizable: true,
transparent: false,
debug: false,
};
export const DEFAULT_APP_NAME = 'Pake';

21
bin/helpers/rust.ts Normal file
View File

@@ -0,0 +1,21 @@
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";
export async function installRust() {
const spinner = ora('Downloading Rust').start();
try {
await shellExec(InstallRustScript);
spinner.succeed();
} catch (error) {
console.error('install rust return code', error.message);
spinner.fail();
process.exit(1);
}
}
export function checkRustInstalled() {
return shelljs.exec('rustc --version', { silent: true }).code === 0;
}

View File

@@ -0,0 +1,8 @@
import crypto from 'crypto';
export function getIdentifier(name: string, url: string) {
const hash = crypto.createHash('md5');
hash.update(url);
const postFixHash = hash.digest('hex').substring(0, 6);
return `pake-${postFixHash}`;
}

91
bin/options/icon.ts Normal file
View File

@@ -0,0 +1,91 @@
import axios from 'axios';
import { fileTypeFromBuffer } from 'file-type';
import { PakeAppOptions } from '../types.js';
import { dir } from 'tmp-promise';
import path from 'path';
import fs from 'fs/promises';
import { fileURLToPath } from 'url';
import log from 'loglevel';
export async function handleIcon(options: PakeAppOptions, url: string) {
if (options.icon) {
if (options.icon.startsWith('http')) {
return downloadIcon(options.icon);
} else {
return path.resolve(options.icon);
}
}
if (!options.icon) {
return inferIcon(options.name, url);
}
}
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)')
const npmDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
return path.join(npmDirectory, 'pake-default.icns');
}
// export async function getIconFromPageUrl(url: string) {
// const icon = await pageIcon(url);
// console.log(icon);
// if (icon.ext === '.ico') {
// const a = await ICO.parse(icon.data);
// icon.data = Buffer.from(a[0].buffer);
// }
// const iconDir = (await dir()).path;
// const iconPath = path.join(iconDir, `/icon.icns`);
// const out = png2icons.createICNS(icon.data, png2icons.BILINEAR, 0);
// await fs.writeFile(iconPath, out);
// return iconPath;
// }
// export async function getIconFromMacosIcons(name: string) {
// const data = {
// query: name,
// filters: 'approved:true',
// hitsPerPage: 10,
// page: 1,
// };
// const res = await axios.post('https://p1txh7zfb3-2.algolianet.com/1/indexes/macOSicons/query?x-algolia-agent=Algolia%20for%20JavaScript%20(4.13.1)%3B%20Browser', data, {
// headers: {
// 'x-algolia-api-key': '0ba04276e457028f3e11e38696eab32c',
// 'x-algolia-application-id': 'P1TXH7ZFB3',
// },
// });
// if (!res.data.hits.length) {
// return '';
// } else {
// return downloadIcon(res.data.hits[0].icnsUrl);
// }
// }
export async function downloadIcon(iconUrl: string) {
let iconResponse;
try {
iconResponse = await axios.get(iconUrl, {
responseType: 'arraybuffer',
});
} catch (error) {
if (error.response && error.response.status === 404) {
return null;
}
throw error;
}
const iconData = await iconResponse.data;
if (!iconData) {
return null;
}
const fileDetails = await fileTypeFromBuffer(iconData);
if (!fileDetails) {
return null;
}
const { path } = await dir();
const iconPath = `${path}/icon.${fileDetails.ext}`;
await fs.writeFile(iconPath, iconData);
return iconPath;
}

22
bin/options/index.ts Normal file
View File

@@ -0,0 +1,22 @@
import { promptText } from '@/builders/common.js';
import { getDomain } from '@/utils/url.js';
import { getIdentifier } from '../helpers/tauriConfig.js';
import { PakeAppOptions, PakeCliOptions } from '../types.js';
import { handleIcon } from './icon.js';
export default async function handleOptions(options: PakeCliOptions, url: string): Promise<PakeAppOptions> {
const appOptions: PakeAppOptions = {
...options,
identifier: '',
};
if (!appOptions.name) {
appOptions.name = await promptText('please input your application name', getDomain(url));
}
appOptions.identifier = getIdentifier(appOptions.name, url);
appOptions.icon = await handleIcon(appOptions, url);
return appOptions;
}

29
bin/types.ts Normal file
View File

@@ -0,0 +1,29 @@
export interface PakeCliOptions {
/** 应用名称 */
name?: string;
/** 应用icon */
icon: string;
/** 应用窗口宽度,默认 1280px */
width: number;
/** 应用窗口高度,默认 800px */
height: number;
/** 是否可以拖动默认true */
resizable: boolean;
/** 是否可以全屏,默认 false */
fullscreen: boolean;
/** 是否开启沉浸式头部,默认为 false 不开启 ƒ*/
transparent: boolean;
/** 调试模式,会输出更多日志 */
debug: boolean;
}
export interface PakeAppOptions extends PakeCliOptions {
identifier: string;
}

5
bin/utils/platform.ts Normal file
View File

@@ -0,0 +1,5 @@
export const IS_MAC = process.platform === 'darwin';
export const IS_WIN = process.platform === 'win32';
export const IS_LINUX = process.platform === 'linux';

13
bin/utils/shell.ts Normal file
View File

@@ -0,0 +1,13 @@
import shelljs from 'shelljs';
export function shellExec(command: string) {
return new Promise<number>((resolve, reject) => {
shelljs.exec(command, { async: true, silent: false}, (code) => {
if (code === 0) {
resolve(0);
} else {
reject(new Error(`${code}`));
}
});
});
}

1489
bin/utils/tlds.ts Normal file

File diff suppressed because it is too large Load Diff

47
bin/utils/url.ts Normal file
View File

@@ -0,0 +1,47 @@
import url from 'url';
import isurl from 'is-url';
import tlds from './tlds.js';
export function getDomain(inputUrl: string) {
const parsed = url.parse(inputUrl).host;
var parts = parsed.split('.');
if (parts[0] === 'www' && parts[1] !== 'com') {
parts.shift();
}
var ln = parts.length,
i = ln,
minLength = parts[parts.length - 1].length,
part;
// iterate backwards
while ((part = parts[--i])) {
// stop when we find a non-TLD part
if (
i === 0 || // 'asia.com' (last remaining must be the SLD)
i < ln - 2 || // TLDs only span 2 levels
part.length < minLength || // 'www.cn.com' (valid TLD as second-level domain)
tlds.indexOf(part) < 0 // officialy not a TLD
) {
return part;
}
}
}
function appendProtocol(inputUrl: string): string {
const parsed = url.parse(inputUrl);
if (!parsed.protocol) {
const urlWithProtocol = `https://${inputUrl}`;
return urlWithProtocol;
}
return inputUrl;
}
export function normalizeUrl(urlToNormalize: string): string {
const urlWithProtocol = appendProtocol(urlToNormalize);
if (isurl(urlWithProtocol)) {
return urlWithProtocol;
} else {
throw new Error(`Your url "${urlWithProtocol}" is invalid`);
}
}

18
bin/utils/validate.ts Normal file
View File

@@ -0,0 +1,18 @@
import * as Commander from 'commander';
import { normalizeUrl } from './url.js';
export function validateNumberInput(value: string) {
const parsedValue = Number(value);
if (isNaN(parsedValue)) {
throw new Commander.InvalidArgumentError('Not a number.');
}
return parsedValue;
}
export function validateUrlInput(url: string) {
try {
return normalizeUrl(url);
} catch (error) {
throw new Commander.InvalidArgumentError(error.message);
}
}

2
cli.js Executable file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env node
import './dist/cli.js';

1917
dist/cli.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,10 @@
{
"name": "pake",
"name": "pake-cli",
"version": "0.0.1",
"description": "用 Rust 来打包你的 App底层使用 Tauri当前支持微信读书、Flomo、Vercel",
"bin": {
"pake": "./cli.js"
},
"repository": {
"type": "git",
"url": "https://github.com/tw93/pake.git"
@@ -16,13 +20,42 @@
"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",
"tauri": "tauri"
"tauri": "tauri",
"cli": "rollup -c rollup.config.js --watch",
"cli:build": "rollup -c rollup.config.js"
},
"type": "module",
"exports": "./dist/pake.js",
"license": "MIT",
"dependencies": {
"@tauri-apps/api": "^1.2.0"
"@tauri-apps/api": "^1.2.0",
"@tauri-apps/cli": "^1.2.0",
"axios": "^1.1.3",
"commander": "^9.4.1",
"file-type": "^18.0.0",
"is-url": "^1.2.4",
"loglevel": "^1.8.1",
"ora": "^6.1.2",
"prompts": "^2.4.2",
"shelljs": "^0.8.5",
"tmp-promise": "^3.0.3"
},
"devDependencies": {
"@tauri-apps/cli": "^1.2.0"
"@rollup/plugin-alias": "^4.0.2",
"@rollup/plugin-commonjs": "^23.0.2",
"@rollup/plugin-json": "^5.0.1",
"@rollup/plugin-typescript": "^9.0.2",
"@types/is-url": "^1.2.30",
"@types/page-icon": "^0.3.4",
"@types/prompts": "^2.4.1",
"@types/shelljs": "^0.8.11",
"@types/tmp": "^0.2.3",
"app-root-path": "^3.1.0",
"concurrently": "^7.5.0",
"rollup": "^3.3.0",
"rollup-plugin-typescript2": "^0.34.1",
"tsc-alias": "^1.7.1",
"tslib": "^2.4.1",
"typescript": "^4.8.4"
}
}

BIN
pake-default.icns Normal file

Binary file not shown.

24
rollup.config.js Normal file
View File

@@ -0,0 +1,24 @@
import path from 'path';
import appRootPath from 'app-root-path';
import typescript from '@rollup/plugin-typescript';
import alias from '@rollup/plugin-alias';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
export default {
input: 'bin/cli.ts',
output: {
file: 'dist/cli.js',
format: 'es'
},
plugins: [
json(),
typescript({
sourceMap: false,
}),
commonjs(),
alias({
entries: [{ find: '@', replacement: path.join(appRootPath.path, 'bin') }],
}),
],
};

BIN
src-tauri/icons/icon.icns Normal file

Binary file not shown.

17
tsconfig.json Normal file
View File

@@ -0,0 +1,17 @@
{
"compilerOptions": {
"module": "Node16",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "es6",
"noImplicitAny": true,
"moduleResolution": "Node16",
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"@/*": ["bin/*"]
}
},
"include": ["bin/**/*"]
}