mirror of
https://github.com/siyuan-note/plugin-sample-vite-svelte.git
synced 2025-06-07 18:46:01 +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
|
||||
artifacts: "package.zip"
|
||||
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
|
||||
|
||||
|
||||
> [!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
|
||||
|
||||
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` 进行实时编译
|
||||
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 命令会创建符号链接将你的 `dev` 目录绑定到思源的插件目录下。你可以有三种方式来配置目标的思源工作空间并创建符号链接:
|
||||
|
|
20
package.json
20
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "plugin-sample-vite-svelte",
|
||||
"version": "0.3.5",
|
||||
"version": "0.3.6",
|
||||
"type": "module",
|
||||
"description": "This is a sample plugin based on vite and svelte for Siyuan (https://b3log.org/siyuan)",
|
||||
"repository": "",
|
||||
|
@ -8,28 +8,30 @@
|
|||
"author": "frostime",
|
||||
"license": "MIT",
|
||||
"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-win": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File ./scripts/elevate.ps1 -scriptPath ./scripts/make_dev_link.js",
|
||||
"dev": "vite build --watch",
|
||||
"build": "vite build",
|
||||
"update-version": "node --no-warnings ./scripts/update_version.js",
|
||||
"make-install": "vite build && node --no-warnings ./scripts/make_install.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.0",
|
||||
"@tsconfig/svelte": "^4.0.1",
|
||||
"@types/node": "^20.3.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"fast-glob": "^3.2.12",
|
||||
"glob": "^7.2.3",
|
||||
"glob": "^10.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"minimist": "^1.2.8",
|
||||
"rollup-plugin-livereload": "^2.0.5",
|
||||
"sass": "^1.63.3",
|
||||
"siyuan": "0.9.9",
|
||||
"svelte": "^4.2.0",
|
||||
"siyuan": "1.0.4",
|
||||
"svelte": "^4.2.19",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.1.3",
|
||||
"vite": "^5.0.0",
|
||||
"vite": "^5.2.9",
|
||||
"vite-plugin-static-copy": "^1.0.2",
|
||||
"vite-plugin-zip-pack": "^1.0.5"
|
||||
}
|
||||
}
|
||||
}
|
11
plugin.json
11
plugin.json
|
@ -2,15 +2,16 @@
|
|||
"name": "plugin-sample-vite-svelte",
|
||||
"author": "frostime",
|
||||
"url": "https://github.com/siyuan-note/plugin-sample-vite-svelte",
|
||||
"version": "0.3.5",
|
||||
"version": "0.3.6",
|
||||
"minAppVersion": "3.0.12",
|
||||
"backends": [
|
||||
"windows",
|
||||
"linux",
|
||||
"darwin",
|
||||
"docker",
|
||||
"ios",
|
||||
"android"
|
||||
"android",
|
||||
"harmony",
|
||||
"docker"
|
||||
],
|
||||
"frontends": [
|
||||
"desktop",
|
||||
|
@ -37,6 +38,8 @@
|
|||
]
|
||||
},
|
||||
"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">
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
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
|
||||
* @Date : 2024-03-23 21:37:33
|
||||
* @FilePath : /src/libs/dialog.ts
|
||||
* @LastEditTime : 2024-07-19 15:34:39
|
||||
* @LastEditTime : 2024-10-16 14:31:04
|
||||
* @Description : Kits about dialogs
|
||||
*/
|
||||
import { Dialog } from "siyuan";
|
||||
|
@ -135,7 +135,10 @@ export const simpleDialog = (args: {
|
|||
destroyCallback: args.callback
|
||||
});
|
||||
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')
|
||||
container.style.display = 'contents';
|
||||
let component = args.constructor(container);
|
||||
simpleDialog({...args, ele: container, callback: () => {
|
||||
component.$destroy();
|
||||
if (args.callback) args.callback();;
|
||||
}});
|
||||
return component;
|
||||
const { dialog, close } = simpleDialog({
|
||||
...args, ele: container, callback: () => {
|
||||
component.$destroy();
|
||||
if (args.callback) args.callback();
|
||||
}
|
||||
});
|
||||
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/**/*.d.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue"
|
||||
"src/**/*.vue",
|
||||
"src/**/*.svelte"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
|
|
170
vite.config.ts
170
vite.config.ts
|
@ -1,6 +1,5 @@
|
|||
import { resolve } from "path"
|
||||
import { defineConfig, loadEnv } from "vite"
|
||||
import minimist from "minimist"
|
||||
import { viteStaticCopy } from "vite-plugin-static-copy"
|
||||
import livereload from "rollup-plugin-livereload"
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte"
|
||||
|
@ -9,13 +8,15 @@ import fg from 'fast-glob';
|
|||
|
||||
import vitePluginYamlI18n from './yaml-plugin';
|
||||
|
||||
const args = minimist(process.argv.slice(2))
|
||||
const isWatch = args.watch || args.w || false
|
||||
const devDistDir = "dev"
|
||||
const distDir = isWatch ? devDistDir : "dist"
|
||||
const env = process.env;
|
||||
const isSrcmap = env.VITE_SOURCEMAP === 'inline';
|
||||
const isDev = env.NODE_ENV === 'development';
|
||||
|
||||
console.log("isWatch=>", isWatch)
|
||||
console.log("distDir=>", distDir)
|
||||
const outputDir = isDev ? "dev" : "dist";
|
||||
|
||||
console.log("isDev=>", isDev);
|
||||
console.log("isSrcmap=>", isSrcmap);
|
||||
console.log("outputDir=>", outputDir);
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
|
@ -29,92 +30,67 @@ export default defineConfig({
|
|||
|
||||
vitePluginYamlI18n({
|
||||
inDir: 'public/i18n',
|
||||
outDir: `${distDir}/i18n`
|
||||
outDir: `${outputDir}/i18n`
|
||||
}),
|
||||
|
||||
viteStaticCopy({
|
||||
targets: [
|
||||
{
|
||||
src: "./README*.md",
|
||||
dest: "./",
|
||||
},
|
||||
{
|
||||
src: "./plugin.json",
|
||||
dest: "./",
|
||||
},
|
||||
{
|
||||
src: "./preview.png",
|
||||
dest: "./",
|
||||
},
|
||||
{
|
||||
src: "./icon.png",
|
||||
dest: "./",
|
||||
}
|
||||
{ src: "./README*.md", 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: {
|
||||
"process.env.DEV_MODE": `"${isWatch}"`,
|
||||
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
|
||||
"process.env.DEV_MODE": JSON.stringify(isDev),
|
||||
"process.env.NODE_ENV": JSON.stringify(env.NODE_ENV)
|
||||
},
|
||||
|
||||
build: {
|
||||
// 输出路径
|
||||
outDir: distDir,
|
||||
outDir: outputDir,
|
||||
emptyOutDir: false,
|
||||
|
||||
// 构建后是否生成 source map 文件
|
||||
sourcemap: isWatch ? 'inline' : false,
|
||||
|
||||
// 设置为 false 可以禁用最小化混淆
|
||||
// 或是用来指定是应用哪种混淆器
|
||||
// boolean | 'terser' | 'esbuild'
|
||||
// 不压缩,用于调试
|
||||
minify: !isWatch,
|
||||
minify: true,
|
||||
sourcemap: isSrcmap ? 'inline' : false,
|
||||
|
||||
lib: {
|
||||
// Could also be a dictionary or array of multiple entry points
|
||||
entry: resolve(__dirname, "src/index.ts"),
|
||||
// the proper extensions will be added
|
||||
fileName: "index",
|
||||
formats: ["cjs"],
|
||||
},
|
||||
rollupOptions: {
|
||||
plugins: [
|
||||
...(
|
||||
isWatch ? [
|
||||
livereload(devDistDir),
|
||||
{
|
||||
//监听静态资源文件
|
||||
name: 'watch-external',
|
||||
async buildStart() {
|
||||
const files = await fg([
|
||||
'public/i18n/**',
|
||||
'./README*.md',
|
||||
'./plugin.json'
|
||||
]);
|
||||
for (let file of files) {
|
||||
this.addWatchFile(file);
|
||||
}
|
||||
...(isDev ? [
|
||||
livereload(outputDir),
|
||||
{
|
||||
name: 'watch-external',
|
||||
async buildStart() {
|
||||
const files = await fg([
|
||||
'public/i18n/**',
|
||||
'./README*.md',
|
||||
'./plugin.json'
|
||||
]);
|
||||
for (let file of files) {
|
||||
this.addWatchFile(file);
|
||||
}
|
||||
}
|
||||
] : [
|
||||
zipPack({
|
||||
inDir: './dist',
|
||||
outDir: './',
|
||||
outFileName: 'package.zip'
|
||||
})
|
||||
]
|
||||
)
|
||||
}
|
||||
] : [
|
||||
// Clean up unnecessary files under dist dir
|
||||
cleanupDistFiles({
|
||||
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"],
|
||||
|
||||
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