Skip to content

Commit

Permalink
feat: 优化插件系统加载
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Feb 24, 2023
1 parent da1c055 commit a74a9d8
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 91 deletions.
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,64 @@
- 整合热门挂件以及其他小工具,提供统一的入口
- 天生支持插件系统

## 快速上手

直接在思源笔记 `集市` 下载 `zhi` 主题,然后在 <kbd>设置</kbd> - <kbd>外观</kbd> - <kbd>主题</kbd> 选择 `zhi` 主题即可

## 本地调试

1. 下载压缩包,解压到主题目录。主题目录在 <kbd>设置</kbd> - <kbd>外观</kbd> - <kbd>主题</kbd> - <kbd>打开主题文件夹</kbd>

2. 安装依赖,构建项目

```bash
npm i -g pnpm
pnpm install
pnpm build
```

3. <kbd>设置</kbd> - <kbd>外观</kbd> - <kbd>主题</kbd> 选择 `zhi` 主题即可

## 项目结构

Vite + React + TypeScript + SWC

```
.
├── README.md
├── dist 构建后的目录,可直接部署到Nginx等静态服务器
├── index.html 内置文章预览等功能的统一入口
├── node_modules
├── package.json
├── public
│   ├── lib 思源内部加载的依赖,使用cjs,可以直接使用fs,可直接require思源内部支持的库,但是不可依赖任何自定义类库,也不能参与编译
├── src 源码根路径,除非特别说明,均参与编译类型检查,不可依赖node独有类库,例如fs等
│   ├── App.css
│   ├── App.tsx
│   ├── assets
│   │   └── react.svg
│   ├── index.css
│   ├── main.tsx
│   ├── utils
│   │   ├── otherlib 参与编译,但是编译期间不参与类型检查,可以直接依赖ts或者js库,但不可依赖node独有类库,例如fs等
│   │   ├── strUtil.ts
│   │   └── sysUtil.ts
│   ├── vite-env.d.ts
│   ├── zhi
│   │   ├── Lifecycle.ts
│   │   └── bootstrap.ts
│   ├── zhi-theme.sass zhi 核心样式sass源码
│   └── zhi-theme.ts zhi 核心加载逻辑
├── theme.css 思源笔记样式入口
├── theme.js 思源笔记脚本入口
├── theme.json
├── tsconfig.json
├── tsconfig.node.json
├── typings
│   └── custom.d.ts
└── vite.config.ts vite项目配置
```

## 感谢

感谢 [zuoez02](https://github.com/zuoez02/siyuan-plugin-system) 提供的插件系统
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "zhi",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
Expand Down
76 changes: 76 additions & 0 deletions public/lib/plugin/plugin-system.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2023, Terwer . All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Terwer designates this
* particular file as subject to the "Classpath" exception as provided
* by Terwer in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Terwer, Shenzhen, Guangdong, China, youweics@163.com
* or visit www.terwer.space if you need additional information or have any
* questions.
*/

// 警告1⚠️:请勿在非思源笔记Electron环境调用此文件中的任何方法
// 警告2⚠️:此文件请勿引用其他任何需要编译的类库

const getCrossPlatformAppDataFolder = () => {
const path = window.require("path")

let configFilePath
if (window.process.platform === "darwin") {
configFilePath = path.join(
window.process.env.HOME,
"/Library/Application Support"
)
} else if (window.process.platform === "win32") {
// Roaming包含在APPDATA中了
configFilePath = window.process.env.APPDATA
} else if (window.process.platform === "linux") {
configFilePath = window.process.env.HOME
}
return configFilePath
}

const initPluginSystem = async () => {
const path = window.require("path")
try {
const data = window
.require("fs")
.readFileSync(
path.join(getCrossPlatformAppDataFolder(), ".siyuan", "plugin.js")
)
const script = data.toString("utf8")
console.log("local plugin system found, loading...")
eval(script)
} catch (e) {
console.log("local plugin system not found, load online")
return fetch(
"https://gitee.com/zuoez02/siyuan-plugin-system/raw/main/main.js",
{ cache: "no-cache" }
)
.then((res) => res.text())
.then((sc) => {
window.siyuanPluginScript = sc
eval(sc)
})
}
}

const pluginSystem = {
initPluginSystem
}

module.exports = pluginSystem
99 changes: 99 additions & 0 deletions src/utils/otherlib/loadOtherlib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2023, Terwer . All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Terwer designates this
* particular file as subject to the "Classpath" exception as provided
* by Terwer in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Terwer, Shenzhen, Guangdong, China, youweics@163.com
* or visit www.terwer.space if you need additional information or have any
* questions.
*/

/**
* 获取数据目录
*
* @author terwer
* @since 0.0.1
*/
export const getSiyuanDataDir = () => {
return window.siyuan.config.system.dataDir
}
/**
* 获取数据目录
*
* @author terwer
* @since 0.0.1
*/
export const getSiyuanConfDir = () => {
return window.siyuan.config.system.confDir
}

/**
* 获取zhi主题构建路径目录
*
* @author terwer
* @since 0.0.1
*/
export const getZhiDir = () => {
return `${getSiyuanConfDir()}/appearance/themes/zhi/dist`
}

/**
* 获取构建后的otherlib目录
*
* @author terwer
* @since 0.0.1
*/
export const getOtherlibDir = () => {
return `${getZhiDir()}/lib`
}

/**
* 引入otherlib依赖
*
* @param entryName 运行模式名称
* @param libfile 依赖名称,otherlib下面
* @param alias 依赖别名
* @author terwer
* @since 0.0.1
*/
const requireOtherlib = (entryName, libfile, alias) => {
const path = window.require("path")
const libpath = path.join(getOtherlibDir(), libfile)
console.log(entryName + " 将要从以下位置引入 " + alias, libpath)
return window.require(libpath)
}

// -------------------------------------------------------------------------

/**
* 加载插件系统
*
* @author terwer
* @since 0.0.1
*/
const loadPluginSystemScript = async () => {
const pluginSystem = requireOtherlib("zhi", "plugin/plugin-system.js", "插件系统")
console.log(pluginSystem)
await pluginSystem.initPluginSystem()
}

const loadOtherlib = {
loadPluginSystemScript
}

export default loadOtherlib
14 changes: 0 additions & 14 deletions src/utils/sysUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,7 @@
*/
class SysUtil {
public getCrossPlatformAppDataFolder = () => {
const path = window.require("path")

let configFilePath
if (window.process.platform === "darwin") {
configFilePath = path.join(
window.process.env.HOME,
"/Library/Application Support"
)
} else if (window.process.platform === "win32") {
// Roaming包含在APPDATA中了
configFilePath = window.process.env.APPDATA
} else if (window.process.platform === "linux") {
configFilePath = window.process.env.HOME
}
return configFilePath
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/zhi-theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
* questions.
*/

import strUtil from "./utils/strUtil"
import { Bootstrap } from "./zhi/bootstrap"
import { version } from "../package.json"
import strUtil from "~/src/utils/strUtil"
import { Bootstrap } from "~/src/zhi/bootstrap"
import { version } from "~/package.json"


(async () => {
/**
Expand Down
30 changes: 2 additions & 28 deletions src/zhi/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* questions.
*/

import sysUtil from "../utils/sysUtil"
import loadOtherlib from "~/src/utils/otherlib/loadOtherlib"

/**
* zhi主题统一生命周期管理
Expand All @@ -46,33 +46,7 @@ class Lifecycle {
* @private
*/
private async loadPluginSystem() {
const path = window.require("path")
try {
const data = window
.require("fs")
.readFileSync(
path.join(
sysUtil.getCrossPlatformAppDataFolder(),
".siyuan",
"plugin.js"
)
)
const script = data.toString("utf8")
console.log("local plugin system found, loading...")
eval(script)
} catch (e) {
console.log("local plugin system not found, load online")
return fetch(
"https://gitee.com/zuoez02/siyuan-plugin-system/raw/main/main.js",
{ cache: "no-cache" }
)
.then((res) => res.text())
.then((sc) => {
// @ts-ignore
window.siyuanPluginScript = sc
eval(sc)
})
}
await loadOtherlib.loadPluginSystemScript()
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/zhi/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* questions.
*/

import Lifecycle from "./Lifecycle"
import Lifecycle from "~/src/zhi/Lifecycle"

/**
* zhi主题唯一激活入口
Expand Down
10 changes: 8 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"paths": {
"~/*": [
"./*"
]
}
},
"include": [
"src"
"src",
"typings/*.d.ts"
],
"references": [
{
Expand Down
36 changes: 36 additions & 0 deletions typings/custom.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2022-2023, Terwer . All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Terwer designates this
* particular file as subject to the "Classpath" exception as provided
* by Terwer in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Terwer, Shenzhen, Guangdong, China, youweics@163.com
* or visit www.terwer.space if you need additional information or have any
* questions.
*/

declare module "~/src/utils/otherlib/loadOtherlib" {
/**
* 加载插件系统脚本
*
* 此脚本在Electron环境执行,非Electron环境无法使用
*
* @author terwer
* @since 0.0.1
*/
export function loadPluginSystemScript(): any
}
Loading

0 comments on commit a74a9d8

Please sign in to comment.