refactor: 推翻舊架構, 進入 Vite 盛世!
* 所有的 CDN 依賴已全部 npm 化 * Webpack? 一邊去! Vite 太好用啦! * 將 Imports.ts 剔除 * 移除了大量的靜態文件 * 將 index.html 的部分代碼分離 * 修改 deno task * 移除了動態編譯頁面的支持 * ./static 引用全部變更為 npm 包引用
This commit is contained in:
@@ -8,7 +8,7 @@ export default abstract class BaseApi {
|
||||
this.onInit()
|
||||
}
|
||||
abstract onInit(): void
|
||||
checkArgsMissing(args: { [key: string]: unknown }, names: []) {
|
||||
checkArgsMissing(args: { [key: string]: unknown }, names: string[]) {
|
||||
for (const k of names)
|
||||
if (!(k in args))
|
||||
return true
|
||||
|
||||
@@ -11,5 +11,16 @@ export default class UserApi extends BaseApi {
|
||||
code: 401,
|
||||
}
|
||||
})
|
||||
this.registerEvent("User.login", (args) => {
|
||||
if (this.checkArgsMissing(args, ['account', 'password'])) return {
|
||||
msg: "",
|
||||
code: 400,
|
||||
}
|
||||
|
||||
return {
|
||||
msg: "",
|
||||
code: 501,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Simple File Access Library
|
||||
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
|
||||
*/
|
||||
|
||||
import fs from 'node:fs'
|
||||
|
||||
/**
|
||||
* 简单文件类
|
||||
*/
|
||||
export default class io {
|
||||
/**
|
||||
* 构建函数
|
||||
* @param { String } path
|
||||
* @param { String } mode
|
||||
*/
|
||||
constructor(path, mode) {
|
||||
this.path = path
|
||||
this.r = mode.includes('r')
|
||||
this.w = mode.includes('w')
|
||||
}
|
||||
/**
|
||||
* 构建函数
|
||||
* @param { String } path
|
||||
* @param { String } mode
|
||||
*/
|
||||
static open(path, mode) {
|
||||
if (!mode || mode == '')
|
||||
throw new Error('当前文件对象未设置属性!')
|
||||
return new io(path, mode)
|
||||
}
|
||||
/**
|
||||
* 检测文件或目录是否存在
|
||||
* @param { String } path
|
||||
* @returns { Boolean }
|
||||
*/
|
||||
static exists(path) {
|
||||
return fs.existsSync(path)
|
||||
}
|
||||
/**
|
||||
* 枚举目录下所有文件
|
||||
* @param { String } 扫描路径
|
||||
* @param { Object } extra 额外参数
|
||||
* @param { Function<String> } [extra.filter] 过滤器<文件路径>
|
||||
* @param { Boolean } [extra.recursive] 是否搜索文件夹内的文件
|
||||
* @param { Boolean } [extra.fullPath] 是否返回完整文件路径
|
||||
* @returns { String[] } 文件路径列表
|
||||
*/
|
||||
static listFiles(path, { filter, recursive = false, fullPath = true } = {}) {
|
||||
let a = fs.readdirSync(path, { recursive: recursive })
|
||||
a.forEach(function (v, index, arrayThis) {
|
||||
arrayThis[index] = `${path}//${v}`
|
||||
})
|
||||
|
||||
a = a.filter(function (v) {
|
||||
if (!fs.lstatSync(v).isFile()) return false
|
||||
|
||||
if (filter) return filter(v)
|
||||
return true
|
||||
})
|
||||
if (!fullPath)
|
||||
a.forEach(function (v, index, arrayThis) {
|
||||
arrayThis[index] = v.substring(v.lastIndexOf('/') + 1)
|
||||
})
|
||||
return a
|
||||
}
|
||||
/**
|
||||
* 枚举目录下所有文件夹
|
||||
* @param { String } 扫描路径
|
||||
* @param { Object } extra 额外参数
|
||||
* @param { Function<String> } [extra.filter] 过滤器<文件夹路径>
|
||||
* @param { Boolean } [extra.recursive] 是否搜索文件夹内的文件夹
|
||||
* @param { Boolean } [extra.fullPath] 是否返回完整文件路径
|
||||
* @returns { String[] } 文件夹路径列表
|
||||
*/
|
||||
static listFolders(path, { filter, recursive = false, fullPath = true } = {}) {
|
||||
let a = fs.readdirSync(path, { recursive: recursive })
|
||||
a.forEach(function (v, index, arrayThis) {
|
||||
arrayThis[index] = `${path}//${v}`
|
||||
})
|
||||
|
||||
a = a.filter(function (v) {
|
||||
if (!fs.lstatSync(v).isDirectory()) return false
|
||||
|
||||
if (filter) return filter(v)
|
||||
return true
|
||||
})
|
||||
if (!fullPath)
|
||||
a.forEach(function (v, index, arrayThis) {
|
||||
arrayThis[index] = v.substring(v.lastIndexOf('/') + 1)
|
||||
})
|
||||
return a
|
||||
}
|
||||
/**
|
||||
* 获取文件(夹)的全名
|
||||
* @param { String } path
|
||||
* @returns { String } name
|
||||
*/
|
||||
static getName(path) {
|
||||
let r = /\\|\//
|
||||
let s = path.search(r)
|
||||
while (s != -1) {
|
||||
path = path.substring(s + 1)
|
||||
s = path.search(r)
|
||||
}
|
||||
return path
|
||||
}
|
||||
/**
|
||||
* 获取文件(夹)的父文件夹路径
|
||||
* @param { String } path
|
||||
* @returns { String } parentPath
|
||||
*/
|
||||
static getParent(path) {
|
||||
return path.substring(0, path.lastIndexOf(this.getName(path)) - 1)
|
||||
}
|
||||
/**
|
||||
* 复制某文件夹的全部内容, 自动创建文件夹
|
||||
* @param { String } from
|
||||
* @param { String } to
|
||||
*/
|
||||
static copyDir(from, to) {
|
||||
this.mkdirs(to)
|
||||
this.listFiles(from).forEach(function (v) {
|
||||
io.open(v, 'r').pipe(io.open(`${to}//${io.getName(v)}`, 'w')).close()
|
||||
})
|
||||
this.listFolders(from).forEach(function (v) {
|
||||
io.copyDir(v, `${to}//${io.getName(v)}`)
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 删除文件
|
||||
* @param { String } path
|
||||
*/
|
||||
static remove(f) {
|
||||
fs.rmSync(f, { recursive: true })
|
||||
}
|
||||
/**
|
||||
* 移动文件
|
||||
* @param { String }} path
|
||||
* @param { String } newPath
|
||||
*/
|
||||
static move(path, newPath) {
|
||||
fs.renameSync(path, newPath)
|
||||
}
|
||||
/**
|
||||
* 创建文件夹, 有则忽略
|
||||
* @param { String } path
|
||||
* @returns { String } path
|
||||
*/
|
||||
static mkdirs(path) {
|
||||
if (!this.exists(path))
|
||||
fs.mkdirSync(path, { recursive: true })
|
||||
return path
|
||||
}
|
||||
/**
|
||||
* 将文件内容写入到另一个文件
|
||||
* @param { io } file
|
||||
* @returns { io } this
|
||||
*/
|
||||
pipe(file) {
|
||||
file.writeAll(this.readAll())
|
||||
file.close()
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 检查文件是否存在, 若无则写入, 有则忽略
|
||||
* @param { Buffer | String } 写入数据
|
||||
* @returns { io } 对象自身
|
||||
*/
|
||||
checkExistsOrWrite(data) {
|
||||
if (!io.exists(this.path))
|
||||
this.writeAll(data)
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 检查文件是否存在, 若无则写入 JSON 数据, 有则忽略
|
||||
* @param { Object } 写入数据
|
||||
* @returns { io } 对象自身
|
||||
*/
|
||||
checkExistsOrWriteJson(data) {
|
||||
if (!io.exists(this.path))
|
||||
this.writeAllJson(data)
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 读取一个文件
|
||||
* @returns { Buffer } 文件数据字节
|
||||
*/
|
||||
readAll() {
|
||||
if (this.r)
|
||||
return fs.readFileSync(this.path)
|
||||
throw new Error('当前文件对象未设置可读')
|
||||
}
|
||||
/**
|
||||
* 读取一个文件并关闭
|
||||
* @returns { Buffer } 文件数据
|
||||
*/
|
||||
readAllAndClose() {
|
||||
let r
|
||||
if (this.r)
|
||||
r = this.readAll()
|
||||
else
|
||||
throw new Error('当前文件对象未设置可读!')
|
||||
this.close()
|
||||
return r
|
||||
}
|
||||
/**
|
||||
* 写入一个文件
|
||||
* @param { Buffer | String } 写入数据
|
||||
* @returns { io } 对象自身
|
||||
*/
|
||||
writeAll(data) {
|
||||
if (this.w)
|
||||
fs.writeFileSync(this.path, data)
|
||||
else
|
||||
throw new Error('当前文件对象未设置可写!')
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 写入一个JSON文件
|
||||
* @param { Object } 写入数据
|
||||
* @returns { io } 对象自身
|
||||
*/
|
||||
writeAllJson(data) {
|
||||
if (!data instanceof Object)
|
||||
throw new Error('你只能输入一个 JSON 对象!')
|
||||
if (this.w)
|
||||
this.writeAll(JSON.stringify(data))
|
||||
else
|
||||
throw new Error('当前文件对象未设置可写!')
|
||||
return this
|
||||
}
|
||||
/**
|
||||
* 读取一个JSON文件
|
||||
* @returns { Object } 文件数据
|
||||
*/
|
||||
readAllJson() {
|
||||
if (this.r)
|
||||
return JSON.parse(this.readAll().toString())
|
||||
throw new Error('当前文件对象未设置可读!')
|
||||
}
|
||||
/**
|
||||
* 读取一个JSON文件并关闭
|
||||
* @returns { Object } 文件数据
|
||||
*/
|
||||
readAllJsonAndClose() {
|
||||
let r
|
||||
if (this.r)
|
||||
r = JSON.parse(this.readAll().toString())
|
||||
else
|
||||
throw new Error('当前文件对象未设置可读!')
|
||||
this.close()
|
||||
return r
|
||||
}
|
||||
/**
|
||||
* 回收文件对象
|
||||
*/
|
||||
close() {
|
||||
delete this.path
|
||||
delete this.r
|
||||
delete this.w
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
// @ts-types="npm:@types/babel__core"
|
||||
import babel from '@babel/core'
|
||||
import fs from 'node:fs/promises'
|
||||
import io from './io.js'
|
||||
|
||||
async function compileJs(path: string) {
|
||||
const result = await babel.transformFileAsync(path, {
|
||||
presets: [
|
||||
[
|
||||
"@babel/preset-env", {
|
||||
modules: false,
|
||||
},
|
||||
],
|
||||
"@babel/preset-react",
|
||||
[
|
||||
"@babel/preset-typescript", {
|
||||
allowDeclareFields: true,
|
||||
},
|
||||
],
|
||||
],
|
||||
targets: {
|
||||
chrome: "53",
|
||||
android: "40",
|
||||
},
|
||||
sourceMaps: true,
|
||||
})
|
||||
await fs.writeFile(path, result!.code + '\n' + `//@ sourceMappingURL=${io.getName(path)}.map`)
|
||||
await fs.writeFile(path + '.map', JSON.stringify(result!.map))
|
||||
console.log(`编译: ${path}`)
|
||||
}
|
||||
|
||||
export default async function(source: string, output: string) {
|
||||
const t = Date.now()
|
||||
io.remove(output)
|
||||
io.copyDir(source, output)
|
||||
for (const v of io.listFiles(output, {
|
||||
recursive: true,
|
||||
fullPath: true,
|
||||
}))
|
||||
if (/\.(t|j)sx?$/.test(v) && !/\.(min|static)\.(t|j)sx?$/.test(v))
|
||||
if (/\.d\.ts$/.test(v))
|
||||
await fs.writeFile(v, '')
|
||||
else
|
||||
await compileJs(v)
|
||||
return (Date.now() - t) / 1000
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
import fs from 'node:fs/promises'
|
||||
import chalk from 'chalk'
|
||||
import { cwd } from "node:process"
|
||||
|
||||
const isCompilingClient = /client(\\|\/)?$/.test(cwd())
|
||||
const prefix = isCompilingClient ? '.' : ''
|
||||
|
||||
const default_data_path = "./thewhitesilk_data"
|
||||
let config = {
|
||||
@@ -28,12 +32,12 @@ let config = {
|
||||
}
|
||||
|
||||
try {
|
||||
config = JSON.parse(await fs.readFile('thewhitesilk_config.json', 'utf-8'))
|
||||
config = JSON.parse(await fs.readFile(prefix + './thewhitesilk_config.json', 'utf-8'))
|
||||
} catch (_e) {
|
||||
console.log(chalk.yellow("配置文件貌似不存在, 正在创建..."))
|
||||
await fs.writeFile('thewhitesilk_config.json', JSON.stringify(config))
|
||||
await fs.writeFile(prefix + './thewhitesilk_config.json', JSON.stringify(config))
|
||||
}
|
||||
|
||||
await fs.mkdir(config.data_path, { recursive: true })
|
||||
await fs.mkdir(prefix + config.data_path, { recursive: true })
|
||||
|
||||
export default config
|
||||
|
||||
@@ -8,7 +8,6 @@ import http from 'node:http'
|
||||
import https from 'node:https'
|
||||
import readline from 'node:readline'
|
||||
import process from "node:process"
|
||||
import transform from './compiler/transform.ts'
|
||||
import chalk from "chalk"
|
||||
|
||||
const app = express()
|
||||
@@ -34,18 +33,13 @@ ApiManager.initEvents()
|
||||
ApiManager.initAllApis()
|
||||
|
||||
httpServer.listen(config.server.listen)
|
||||
console.log(chalk.green("API & Web 服務已經開始運作"))
|
||||
|
||||
console.log(chalk.green("Web 頁面已編譯完成, 用時 " + await transform('./client', config.data_path + '/page_compiled') + "s"))
|
||||
|
||||
console.log(chalk.yellow("===== TheWhiteSilk Server ====="))
|
||||
console.log(chalk.yellow("b - 重新編譯 Web 頁面"))
|
||||
console.log(chalk.green("API & Web 服務已經開始運作"))
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
})
|
||||
rl.on('line', async (text) => {
|
||||
if (text == "b")
|
||||
console.log(chalk.green("Web 頁面已編譯完成, 用時 " + await transform('./client', config.data_path + '/page_compiled') + "s"))
|
||||
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user