mirror of
https://github.com/siyuan-note/plugin-sample-vite-svelte.git
synced 2025-06-08 02:46:02 +00:00
Compare commits
7 commits
Author | SHA1 | Date | |
---|---|---|---|
|
777f31761c | ||
|
38b19fdb88 | ||
|
591cf2e95e | ||
|
4aee720da5 | ||
|
19cae2eabd | ||
|
63ee8d92dc | ||
|
63cc3ac0c2 |
15 changed files with 382 additions and 138 deletions
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
@ -59,4 +59,4 @@ jobs:
|
||||||
artifactErrorsFailBuild: true
|
artifactErrorsFailBuild: true
|
||||||
artifacts: "package.zip"
|
artifacts: "package.zip"
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
prerelease: true
|
prerelease: false
|
||||||
|
|
|
@ -18,6 +18,14 @@
|
||||||
4. Provides a github action template to automatically generate package.zip and upload to new release
|
4. Provides a github action template to automatically generate package.zip and upload to new release
|
||||||
|
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> You can also use our maintained [siyuan-plugin-cli](https://www.npmjs.com/package/siyuan-plugin-cli) command-line tool to directly build plugins in your local terminal.
|
||||||
|
>
|
||||||
|
> Additionally, for the `make-link` related commands mentioned in this plugin, all future updates will be made in [siyuan-plugin-cli](https://www.npmjs.com/package/siyuan-plugin-cli).
|
||||||
|
>
|
||||||
|
> The built-in `make-link` scripts may also be removed in a future version, in favor of using the `siyuan-plugin-cli` tool, aiming to simplify the workload of maintaining multiple plugin templates.
|
||||||
|
|
||||||
|
|
||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
1. Use the <kbd>Use this template</kbd> button to make a copy of this repo as a template. Note that the repository name should match the plugin name, and the default branch must be `main`.
|
1. Use the <kbd>Use this template</kbd> button to make a copy of this repo as a template. Note that the repository name should match the plugin name, and the default branch must be `main`.
|
||||||
|
|
|
@ -26,6 +26,13 @@
|
||||||
5. 执行 `pnpm run dev` 进行实时编译
|
5. 执行 `pnpm run dev` 进行实时编译
|
||||||
6. 在思源中打开集市并在下载选项卡中启用插件
|
6. 在思源中打开集市并在下载选项卡中启用插件
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
> 你也可以使用我们维护的 [siyuan-plugin-cli](https://www.npmjs.com/package/siyuan-plugin-cli) 命令行工具,在本地终端中直接构建插件。
|
||||||
|
>
|
||||||
|
> 此外,对于本插件以下提及到的 `make-link` 相关的命令,后续所有更新将在 [siyuan-plugin-cli](https://www.npmjs.com/package/siyuan-plugin-cli) 中进行。
|
||||||
|
>
|
||||||
|
> 模板内置的 `make-link` 脚本也可能会在未来某个版本中移除,转而使用 `siyuan-plugin-cli` 工具,意在简化同时维护多个插件模板的工作量。
|
||||||
|
|
||||||
### 设置 make-link 命令的目标目录
|
### 设置 make-link 命令的目标目录
|
||||||
|
|
||||||
make-link 命令会创建符号链接将你的 `dev` 目录绑定到思源的插件目录下。你可以有三种方式来配置目标的思源工作空间并创建符号链接:
|
make-link 命令会创建符号链接将你的 `dev` 目录绑定到思源的插件目录下。你可以有三种方式来配置目标的思源工作空间并创建符号链接:
|
||||||
|
|
18
package.json
18
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "plugin-sample-vite-svelte",
|
"name": "plugin-sample-vite-svelte",
|
||||||
"version": "0.3.5",
|
"version": "0.3.6",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "This is a sample plugin based on vite and svelte for Siyuan (https://b3log.org/siyuan)",
|
"description": "This is a sample plugin based on vite and svelte for Siyuan (https://b3log.org/siyuan)",
|
||||||
"repository": "",
|
"repository": "",
|
||||||
|
@ -8,27 +8,29 @@
|
||||||
"author": "frostime",
|
"author": "frostime",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"dev": "cross-env NODE_ENV=development VITE_SOURCEMAP=inline vite build --watch",
|
||||||
|
"build": "cross-env NODE_ENV=production vite build",
|
||||||
"make-link": "node --no-warnings ./scripts/make_dev_link.js",
|
"make-link": "node --no-warnings ./scripts/make_dev_link.js",
|
||||||
"make-link-win": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File ./scripts/elevate.ps1 -scriptPath ./scripts/make_dev_link.js",
|
"make-link-win": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File ./scripts/elevate.ps1 -scriptPath ./scripts/make_dev_link.js",
|
||||||
"dev": "vite build --watch",
|
"update-version": "node --no-warnings ./scripts/update_version.js",
|
||||||
"build": "vite build",
|
|
||||||
"make-install": "vite build && node --no-warnings ./scripts/make_install.js"
|
"make-install": "vite build && node --no-warnings ./scripts/make_install.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
"@sveltejs/vite-plugin-svelte": "^3.1.0",
|
||||||
"@tsconfig/svelte": "^4.0.1",
|
"@tsconfig/svelte": "^4.0.1",
|
||||||
"@types/node": "^20.3.0",
|
"@types/node": "^20.3.0",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
"fast-glob": "^3.2.12",
|
"fast-glob": "^3.2.12",
|
||||||
"glob": "^7.2.3",
|
"glob": "^10.0.0",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"minimist": "^1.2.8",
|
"minimist": "^1.2.8",
|
||||||
"rollup-plugin-livereload": "^2.0.5",
|
"rollup-plugin-livereload": "^2.0.5",
|
||||||
"sass": "^1.63.3",
|
"sass": "^1.63.3",
|
||||||
"siyuan": "0.9.9",
|
"siyuan": "1.0.4",
|
||||||
"svelte": "^4.2.0",
|
"svelte": "^4.2.19",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^5.1.3",
|
"typescript": "^5.1.3",
|
||||||
"vite": "^5.0.0",
|
"vite": "^5.2.9",
|
||||||
"vite-plugin-static-copy": "^1.0.2",
|
"vite-plugin-static-copy": "^1.0.2",
|
||||||
"vite-plugin-zip-pack": "^1.0.5"
|
"vite-plugin-zip-pack": "^1.0.5"
|
||||||
}
|
}
|
||||||
|
|
11
plugin.json
11
plugin.json
|
@ -2,15 +2,16 @@
|
||||||
"name": "plugin-sample-vite-svelte",
|
"name": "plugin-sample-vite-svelte",
|
||||||
"author": "frostime",
|
"author": "frostime",
|
||||||
"url": "https://github.com/siyuan-note/plugin-sample-vite-svelte",
|
"url": "https://github.com/siyuan-note/plugin-sample-vite-svelte",
|
||||||
"version": "0.3.5",
|
"version": "0.3.6",
|
||||||
"minAppVersion": "3.0.12",
|
"minAppVersion": "3.0.12",
|
||||||
"backends": [
|
"backends": [
|
||||||
"windows",
|
"windows",
|
||||||
"linux",
|
"linux",
|
||||||
"darwin",
|
"darwin",
|
||||||
"docker",
|
|
||||||
"ios",
|
"ios",
|
||||||
"android"
|
"android",
|
||||||
|
"harmony",
|
||||||
|
"docker"
|
||||||
],
|
],
|
||||||
"frontends": [
|
"frontends": [
|
||||||
"desktop",
|
"desktop",
|
||||||
|
@ -37,6 +38,8 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"plugin", "sample", "插件样例"
|
"plugin",
|
||||||
|
"sample",
|
||||||
|
"插件样例"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
12
public/i18n/README.md
Normal file
12
public/i18n/README.md
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
思源支持的 i18n 文件范围,可以在控制台 `siyuan.config.langs` 中查看。以下是目前(2024-10-24)支持的语言方案:
|
||||||
|
|
||||||
|
The range of i18n files supported by SiYuan can be viewed in the console under `siyuan.config.langs`. Below are the language schemes currently supported as of now (October 24, 2024) :
|
||||||
|
|
||||||
|
```js
|
||||||
|
>>> siyuan.config.langs.map( lang => lang.name)
|
||||||
|
['de_DE', 'en_US', 'es_ES', 'fr_FR', 'he_IL', 'it_IT', 'ja_JP', 'pl_PL', 'ru_RU', 'zh_CHT', 'zh_CN']
|
||||||
|
```
|
||||||
|
|
||||||
|
在插件开发中,默认使用 JSON 格式作为国际化(i18n)的载体文件。如果您更喜欢使用 YAML 语法,可以将 JSON 文件替换为 YAML 文件(例如 `en_US.yaml`),并在其中编写 i18n 文本。本模板提供了相关的 Vite 插件,可以在编译时自动将 YAML 文件转换为 JSON 文件(请参见 `/yaml-plugin.js`)。本 MD 文件 和 YAML 文件会在 `npm run build` 时自动从 `dist` 目录下删除,仅保留必要的 JSON 文件共插件系统使用。
|
||||||
|
|
||||||
|
In plugin development, JSON format is used by default as the carrier file for internationalization (i18n). If you prefer to use YAML syntax, you can replace the JSON file with a YAML file (e.g., `en_US.yaml`) and write the i18n text within it. This template provides a related Vite plugin that can automatically convert YAML files to JSON files during the compilation process (see `/yaml-plugin.js`). This markdown file and YAML files will be automatically removed from the `dist` directory during `npm run build`, leaving only the necessary JSON files for plugin system to use.
|
20
public/i18n/zh_CN.json
Normal file
20
public/i18n/zh_CN.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"addTopBarIcon": "使用插件添加一个顶栏按钮",
|
||||||
|
"cancel": "取消",
|
||||||
|
"save": "保存",
|
||||||
|
"byeMenu": "再见,菜单!",
|
||||||
|
"helloPlugin": "你好,插件!",
|
||||||
|
"byePlugin": "再见,插件!",
|
||||||
|
"showDialog": "弹出一个对话框",
|
||||||
|
"removedData": "数据已删除",
|
||||||
|
"confirmRemove": "确认删除 ${name} 中的数据?",
|
||||||
|
"insertEmoji": "插入表情",
|
||||||
|
"removeSpace": "移除空格",
|
||||||
|
"getTab": "在日志中打印出已打开的所有自定义页签",
|
||||||
|
"name": "思源",
|
||||||
|
"hello": {
|
||||||
|
"makesure": "使用这个模板之前,请阅读<a href=\"https://github.com/siyuan-note/plugin-sample\">官方教程</a>, 确保自己已经理解了插件的基本开发流程。"
|
||||||
|
},
|
||||||
|
"hintTitle": "关于",
|
||||||
|
"hintDesc": "<a href='https://github.com/siyuan-note/plugin-sample-vite-svelte'>🔗 plugin-sample-vite-svelte</a><br>💻 @frostime<br>💻 @88250<br>💻 @zxkmm"
|
||||||
|
}
|
|
@ -1,21 +0,0 @@
|
||||||
---
|
|
||||||
addTopBarIcon: 使用插件添加一个顶栏按钮
|
|
||||||
cancel: 取消
|
|
||||||
save: 保存
|
|
||||||
byeMenu: 再见,菜单!
|
|
||||||
helloPlugin: 你好,插件!
|
|
||||||
byePlugin: 再见,插件!
|
|
||||||
showDialog: 弹出一个对话框
|
|
||||||
removedData: 数据已删除
|
|
||||||
confirmRemove: 确认删除 ${name} 中的数据?
|
|
||||||
insertEmoji: 插入表情
|
|
||||||
removeSpace: 移除空格
|
|
||||||
getTab: 在日志中打印出已打开的所有自定义页签
|
|
||||||
name: 思源
|
|
||||||
hello:
|
|
||||||
makesure: 使用这个模板之前,请阅读<a href="https://github.com/siyuan-note/plugin-sample">官方教程</a>,
|
|
||||||
确保自己已经理解了插件的基本开发流程。
|
|
||||||
hintTitle: 关于
|
|
||||||
hintDesc: "<a href='https://github.com/siyuan-note/plugin-sample-vite-svelte'>\U0001F517
|
|
||||||
plugin-sample-vite-svelte</a><br>\U0001F4BB @frostime<br>\U0001F4BB @88250<br>\U0001F4BB
|
|
||||||
@zxkmm"
|
|
141
scripts/update_version.js
Normal file
141
scripts/update_version.js
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
// const fs = require('fs');
|
||||||
|
// const path = require('path');
|
||||||
|
// const readline = require('readline');
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
import readline from 'node:readline';
|
||||||
|
|
||||||
|
// Utility to read JSON file
|
||||||
|
function readJsonFile(filePath) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(filePath, 'utf8', (err, data) => {
|
||||||
|
if (err) return reject(err);
|
||||||
|
try {
|
||||||
|
const jsonData = JSON.parse(data);
|
||||||
|
resolve(jsonData);
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility to write JSON file
|
||||||
|
function writeJsonFile(filePath, jsonData) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.writeFile(filePath, JSON.stringify(jsonData, null, 2), 'utf8', (err) => {
|
||||||
|
if (err) return reject(err);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility to prompt the user for input
|
||||||
|
function promptUser(query) {
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
});
|
||||||
|
return new Promise((resolve) => rl.question(query, (answer) => {
|
||||||
|
rl.close();
|
||||||
|
resolve(answer);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to parse the version string
|
||||||
|
function parseVersion(version) {
|
||||||
|
const [major, minor, patch] = version.split('.').map(Number);
|
||||||
|
return { major, minor, patch };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to auto-increment version parts
|
||||||
|
function incrementVersion(version, type) {
|
||||||
|
let { major, minor, patch } = parseVersion(version);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'major':
|
||||||
|
major++;
|
||||||
|
minor = 0;
|
||||||
|
patch = 0;
|
||||||
|
break;
|
||||||
|
case 'minor':
|
||||||
|
minor++;
|
||||||
|
patch = 0;
|
||||||
|
break;
|
||||||
|
case 'patch':
|
||||||
|
patch++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${major}.${minor}.${patch}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main script
|
||||||
|
(async function () {
|
||||||
|
try {
|
||||||
|
const pluginJsonPath = path.join(process.cwd(), 'plugin.json');
|
||||||
|
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
||||||
|
|
||||||
|
// Read both JSON files
|
||||||
|
const pluginData = await readJsonFile(pluginJsonPath);
|
||||||
|
const packageData = await readJsonFile(packageJsonPath);
|
||||||
|
|
||||||
|
// Get the current version from both files (assuming both have the same version)
|
||||||
|
const currentVersion = pluginData.version || packageData.version;
|
||||||
|
console.log(`\n🌟 Current version: \x1b[36m${currentVersion}\x1b[0m\n`);
|
||||||
|
|
||||||
|
// Calculate potential new versions for auto-update
|
||||||
|
const newPatchVersion = incrementVersion(currentVersion, 'patch');
|
||||||
|
const newMinorVersion = incrementVersion(currentVersion, 'minor');
|
||||||
|
const newMajorVersion = incrementVersion(currentVersion, 'major');
|
||||||
|
|
||||||
|
// Prompt the user with formatted options
|
||||||
|
console.log('🔄 How would you like to update the version?\n');
|
||||||
|
console.log(` 1️⃣ Auto update \x1b[33mpatch\x1b[0m version (new version: \x1b[32m${newPatchVersion}\x1b[0m)`);
|
||||||
|
console.log(` 2️⃣ Auto update \x1b[33mminor\x1b[0m version (new version: \x1b[32m${newMinorVersion}\x1b[0m)`);
|
||||||
|
console.log(` 3️⃣ Auto update \x1b[33mmajor\x1b[0m version (new version: \x1b[32m${newMajorVersion}\x1b[0m)`);
|
||||||
|
console.log(` 4️⃣ Input version \x1b[33mmanually\x1b[0m`);
|
||||||
|
// Press 0 to skip version update
|
||||||
|
console.log(' 0️⃣ Quit without updating\n');
|
||||||
|
|
||||||
|
const updateChoice = await promptUser('👉 Please choose (1/2/3/4): ');
|
||||||
|
|
||||||
|
let newVersion;
|
||||||
|
|
||||||
|
switch (updateChoice.trim()) {
|
||||||
|
case '1':
|
||||||
|
newVersion = newPatchVersion;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
newVersion = newMinorVersion;
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
newVersion = newMajorVersion;
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
newVersion = await promptUser('✍️ Please enter the new version (in a.b.c format): ');
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
console.log('\n🛑 Skipping version update.');
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
console.log('\n❌ Invalid option, no version update.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the version in both plugin.json and package.json
|
||||||
|
pluginData.version = newVersion;
|
||||||
|
packageData.version = newVersion;
|
||||||
|
|
||||||
|
// Write the updated JSON back to files
|
||||||
|
await writeJsonFile(pluginJsonPath, pluginData);
|
||||||
|
await writeJsonFile(packageJsonPath, packageData);
|
||||||
|
|
||||||
|
console.log(`\n✅ Version successfully updated to: \x1b[32m${newVersion}\x1b[0m\n`);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Error:', error);
|
||||||
|
}
|
||||||
|
})();
|
|
@ -1,3 +1,11 @@
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2024 by frostime. All Rights Reserved.
|
||||||
|
Author : frostime
|
||||||
|
Date : 2023-11-19 12:30:45
|
||||||
|
FilePath : /src/hello.svelte
|
||||||
|
LastEditTime : 2024-10-16 14:37:50
|
||||||
|
Description :
|
||||||
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onDestroy, onMount } from "svelte";
|
import { onDestroy, onMount } from "svelte";
|
||||||
import { version, sql as query } from "@/api";
|
import { version, sql as query } from "@/api";
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
#helloPanel {
|
|
||||||
border: 1px rgb(189, 119, 119) dashed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plugin-sample {
|
|
||||||
&__custom-tab {
|
|
||||||
background-color: var(--b3-theme-background);
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__custom-dock {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__time {
|
|
||||||
background: var(--b3-card-info-background);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 2px 8px;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@
|
||||||
* @Author : frostime
|
* @Author : frostime
|
||||||
* @Date : 2024-03-23 21:37:33
|
* @Date : 2024-03-23 21:37:33
|
||||||
* @FilePath : /src/libs/dialog.ts
|
* @FilePath : /src/libs/dialog.ts
|
||||||
* @LastEditTime : 2024-07-19 15:34:39
|
* @LastEditTime : 2024-10-16 14:31:04
|
||||||
* @Description : Kits about dialogs
|
* @Description : Kits about dialogs
|
||||||
*/
|
*/
|
||||||
import { Dialog } from "siyuan";
|
import { Dialog } from "siyuan";
|
||||||
|
@ -135,7 +135,10 @@ export const simpleDialog = (args: {
|
||||||
destroyCallback: args.callback
|
destroyCallback: args.callback
|
||||||
});
|
});
|
||||||
dialog.element.querySelector(".dialog-content").appendChild(args.ele);
|
dialog.element.querySelector(".dialog-content").appendChild(args.ele);
|
||||||
return dialog;
|
return {
|
||||||
|
dialog,
|
||||||
|
close: dialog.destroy.bind(dialog)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,9 +150,15 @@ export const svelteDialog = (args: {
|
||||||
let container = document.createElement('div')
|
let container = document.createElement('div')
|
||||||
container.style.display = 'contents';
|
container.style.display = 'contents';
|
||||||
let component = args.constructor(container);
|
let component = args.constructor(container);
|
||||||
simpleDialog({...args, ele: container, callback: () => {
|
const { dialog, close } = simpleDialog({
|
||||||
component.$destroy();
|
...args, ele: container, callback: () => {
|
||||||
if (args.callback) args.callback();;
|
component.$destroy();
|
||||||
}});
|
if (args.callback) args.callback();
|
||||||
return component;
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
component,
|
||||||
|
dialog,
|
||||||
|
close
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
48
src/libs/promise-pool.ts
Normal file
48
src/libs/promise-pool.ts
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
export default class PromiseLimitPool<T> {
|
||||||
|
private maxConcurrent: number;
|
||||||
|
private currentRunning = 0;
|
||||||
|
private queue: (() => void)[] = [];
|
||||||
|
private promises: Promise<T>[] = [];
|
||||||
|
|
||||||
|
constructor(maxConcurrent: number) {
|
||||||
|
this.maxConcurrent = maxConcurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(fn: () => Promise<T>): void {
|
||||||
|
const promise = new Promise<T>((resolve, reject) => {
|
||||||
|
const run = async () => {
|
||||||
|
try {
|
||||||
|
this.currentRunning++;
|
||||||
|
const result = await fn();
|
||||||
|
resolve(result);
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
} finally {
|
||||||
|
this.currentRunning--;
|
||||||
|
this.next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.currentRunning < this.maxConcurrent) {
|
||||||
|
run();
|
||||||
|
} else {
|
||||||
|
this.queue.push(run);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.promises.push(promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
async awaitAll(): Promise<T[]> {
|
||||||
|
return Promise.all(this.promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the next task in the queue.
|
||||||
|
*/
|
||||||
|
private next(): void {
|
||||||
|
if (this.queue.length > 0 && this.currentRunning < this.maxConcurrent) {
|
||||||
|
const nextRun = this.queue.shift()!;
|
||||||
|
nextRun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,7 +47,8 @@
|
||||||
"src/**/*.ts",
|
"src/**/*.ts",
|
||||||
"src/**/*.d.ts",
|
"src/**/*.d.ts",
|
||||||
"src/**/*.tsx",
|
"src/**/*.tsx",
|
||||||
"src/**/*.vue"
|
"src/**/*.vue",
|
||||||
|
"src/**/*.svelte"
|
||||||
],
|
],
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
|
|
170
vite.config.ts
170
vite.config.ts
|
@ -1,6 +1,5 @@
|
||||||
import { resolve } from "path"
|
import { resolve } from "path"
|
||||||
import { defineConfig, loadEnv } from "vite"
|
import { defineConfig, loadEnv } from "vite"
|
||||||
import minimist from "minimist"
|
|
||||||
import { viteStaticCopy } from "vite-plugin-static-copy"
|
import { viteStaticCopy } from "vite-plugin-static-copy"
|
||||||
import livereload from "rollup-plugin-livereload"
|
import livereload from "rollup-plugin-livereload"
|
||||||
import { svelte } from "@sveltejs/vite-plugin-svelte"
|
import { svelte } from "@sveltejs/vite-plugin-svelte"
|
||||||
|
@ -9,13 +8,15 @@ import fg from 'fast-glob';
|
||||||
|
|
||||||
import vitePluginYamlI18n from './yaml-plugin';
|
import vitePluginYamlI18n from './yaml-plugin';
|
||||||
|
|
||||||
const args = minimist(process.argv.slice(2))
|
const env = process.env;
|
||||||
const isWatch = args.watch || args.w || false
|
const isSrcmap = env.VITE_SOURCEMAP === 'inline';
|
||||||
const devDistDir = "dev"
|
const isDev = env.NODE_ENV === 'development';
|
||||||
const distDir = isWatch ? devDistDir : "dist"
|
|
||||||
|
|
||||||
console.log("isWatch=>", isWatch)
|
const outputDir = isDev ? "dev" : "dist";
|
||||||
console.log("distDir=>", distDir)
|
|
||||||
|
console.log("isDev=>", isDev);
|
||||||
|
console.log("isSrcmap=>", isSrcmap);
|
||||||
|
console.log("outputDir=>", outputDir);
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
resolve: {
|
resolve: {
|
||||||
|
@ -29,92 +30,67 @@ export default defineConfig({
|
||||||
|
|
||||||
vitePluginYamlI18n({
|
vitePluginYamlI18n({
|
||||||
inDir: 'public/i18n',
|
inDir: 'public/i18n',
|
||||||
outDir: `${distDir}/i18n`
|
outDir: `${outputDir}/i18n`
|
||||||
}),
|
}),
|
||||||
|
|
||||||
viteStaticCopy({
|
viteStaticCopy({
|
||||||
targets: [
|
targets: [
|
||||||
{
|
{ src: "./README*.md", dest: "./" },
|
||||||
src: "./README*.md",
|
{ src: "./plugin.json", dest: "./" },
|
||||||
dest: "./",
|
{ src: "./preview.png", dest: "./" },
|
||||||
},
|
{ src: "./icon.png", dest: "./" }
|
||||||
{
|
|
||||||
src: "./plugin.json",
|
|
||||||
dest: "./",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "./preview.png",
|
|
||||||
dest: "./",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: "./icon.png",
|
|
||||||
dest: "./",
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
// https://github.com/vitejs/vite/issues/1930
|
|
||||||
// https://vitejs.dev/guide/env-and-mode.html#env-files
|
|
||||||
// https://github.com/vitejs/vite/discussions/3058#discussioncomment-2115319
|
|
||||||
// 在这里自定义变量
|
|
||||||
define: {
|
define: {
|
||||||
"process.env.DEV_MODE": `"${isWatch}"`,
|
"process.env.DEV_MODE": JSON.stringify(isDev),
|
||||||
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
|
"process.env.NODE_ENV": JSON.stringify(env.NODE_ENV)
|
||||||
},
|
},
|
||||||
|
|
||||||
build: {
|
build: {
|
||||||
// 输出路径
|
outDir: outputDir,
|
||||||
outDir: distDir,
|
|
||||||
emptyOutDir: false,
|
emptyOutDir: false,
|
||||||
|
minify: true,
|
||||||
// 构建后是否生成 source map 文件
|
sourcemap: isSrcmap ? 'inline' : false,
|
||||||
sourcemap: isWatch ? 'inline' : false,
|
|
||||||
|
|
||||||
// 设置为 false 可以禁用最小化混淆
|
|
||||||
// 或是用来指定是应用哪种混淆器
|
|
||||||
// boolean | 'terser' | 'esbuild'
|
|
||||||
// 不压缩,用于调试
|
|
||||||
minify: !isWatch,
|
|
||||||
|
|
||||||
lib: {
|
lib: {
|
||||||
// Could also be a dictionary or array of multiple entry points
|
|
||||||
entry: resolve(__dirname, "src/index.ts"),
|
entry: resolve(__dirname, "src/index.ts"),
|
||||||
// the proper extensions will be added
|
|
||||||
fileName: "index",
|
fileName: "index",
|
||||||
formats: ["cjs"],
|
formats: ["cjs"],
|
||||||
},
|
},
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
plugins: [
|
plugins: [
|
||||||
...(
|
...(isDev ? [
|
||||||
isWatch ? [
|
livereload(outputDir),
|
||||||
livereload(devDistDir),
|
{
|
||||||
{
|
name: 'watch-external',
|
||||||
//监听静态资源文件
|
async buildStart() {
|
||||||
name: 'watch-external',
|
const files = await fg([
|
||||||
async buildStart() {
|
'public/i18n/**',
|
||||||
const files = await fg([
|
'./README*.md',
|
||||||
'public/i18n/**',
|
'./plugin.json'
|
||||||
'./README*.md',
|
]);
|
||||||
'./plugin.json'
|
for (let file of files) {
|
||||||
]);
|
this.addWatchFile(file);
|
||||||
for (let file of files) {
|
|
||||||
this.addWatchFile(file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
] : [
|
}
|
||||||
zipPack({
|
] : [
|
||||||
inDir: './dist',
|
// Clean up unnecessary files under dist dir
|
||||||
outDir: './',
|
cleanupDistFiles({
|
||||||
outFileName: 'package.zip'
|
patterns: ['i18n/*.yaml', 'i18n/*.md'],
|
||||||
})
|
distDir: outputDir
|
||||||
]
|
}),
|
||||||
)
|
zipPack({
|
||||||
|
inDir: './dist',
|
||||||
|
outDir: './',
|
||||||
|
outFileName: 'package.zip'
|
||||||
|
})
|
||||||
|
])
|
||||||
],
|
],
|
||||||
|
|
||||||
// make sure to externalize deps that shouldn't be bundled
|
|
||||||
// into your library
|
|
||||||
external: ["siyuan", "process"],
|
external: ["siyuan", "process"],
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
|
@ -128,4 +104,60 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up some dist files after compiled
|
||||||
|
* @author frostime
|
||||||
|
* @param options:
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function cleanupDistFiles(options: { patterns: string[], distDir: string }) {
|
||||||
|
const {
|
||||||
|
patterns,
|
||||||
|
distDir
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: 'rollup-plugin-cleanup',
|
||||||
|
enforce: 'post',
|
||||||
|
writeBundle: {
|
||||||
|
sequential: true,
|
||||||
|
order: 'post' as 'post',
|
||||||
|
async handler() {
|
||||||
|
const fg = await import('fast-glob');
|
||||||
|
const fs = await import('fs');
|
||||||
|
// const path = await import('path');
|
||||||
|
|
||||||
|
// 使用 glob 语法,确保能匹配到文件
|
||||||
|
const distPatterns = patterns.map(pat => `${distDir}/${pat}`);
|
||||||
|
console.debug('Cleanup searching patterns:', distPatterns);
|
||||||
|
|
||||||
|
const files = await fg.default(distPatterns, {
|
||||||
|
dot: true,
|
||||||
|
absolute: true,
|
||||||
|
onlyFiles: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.info('Files to be cleaned up:', files);
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
try {
|
||||||
|
if (fs.default.existsSync(file)) {
|
||||||
|
const stat = fs.default.statSync(file);
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
fs.default.rmSync(file, { recursive: true });
|
||||||
|
} else {
|
||||||
|
fs.default.unlinkSync(file);
|
||||||
|
}
|
||||||
|
console.log(`Cleaned up: ${file}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to clean up ${file}:`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue