@rpgjs/vite 5.0.0-alpha.9 → 5.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/LICENSE +19 -0
- package/dist/compatibility-v4/flag-transform.d.ts +6 -0
- package/dist/compatibility-v4/index.d.ts +22 -0
- package/dist/compatibility-v4/load-config-file.d.ts +2 -0
- package/dist/compatibility-v4/require-transform.d.ts +2 -0
- package/dist/compatibility-v4/utils.d.ts +55 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10232 -7505
- package/dist/index.js.map +1 -1
- package/dist/mmorpg-build-plugin.d.ts +8 -0
- package/dist/rpgjs-plugin.d.ts +9 -3
- package/dist/server-plugin.d.ts +2 -149
- package/package.json +22 -13
- package/src/compatibility-v4/flag-transform.ts +61 -0
- package/src/compatibility-v4/index.ts +713 -0
- package/src/compatibility-v4/load-config-file.ts +38 -0
- package/src/compatibility-v4/require-transform.ts +67 -0
- package/src/compatibility-v4/utils.ts +170 -0
- package/src/index.ts +2 -1
- package/src/mmorpg-build-plugin.ts +123 -0
- package/src/module-config.ts +13 -0
- package/src/rpgjs-plugin.ts +36 -4
- package/src/server-plugin.ts +15 -436
- package/tests/compatibility-v4.spec.ts +105 -0
- package/tests/fixtures/v4-game/rpg.toml +11 -0
- package/tests/fixtures/v4-game/src/modules/main/characters/assets/hero.svg +2 -0
- package/tests/fixtures/v4-game/src/modules/main/characters/hero.ts +2 -0
- package/tests/fixtures/v4-game/src/modules/main/client.ts +4 -0
- package/tests/fixtures/v4-game/src/modules/main/database/potion.ts +6 -0
- package/tests/fixtures/v4-game/src/modules/main/events/npc.ts +4 -0
- package/tests/fixtures/v4-game/src/modules/main/gui/menu.vue +2 -0
- package/tests/fixtures/v4-game/src/modules/main/maps/map.tmx +2 -0
- package/tests/fixtures/v4-game/src/modules/main/maps/map.ts +7 -0
- package/tests/fixtures/v4-game/src/modules/main/player.ts +4 -0
- package/tests/fixtures/v4-game/src/modules/main/scene-map.ts +4 -0
- package/tests/fixtures/v4-game/src/modules/main/server.ts +4 -0
- package/tests/fixtures/v4-game/src/modules/main/sounds/theme.ogg +2 -0
- package/tests/fixtures/v4-game/src/modules/main/sounds/theme.ts +5 -0
- package/tests/fixtures/v4-game/src/modules/main/sprite.ts +4 -0
- package/tests/fixtures/v4-game/src/modules/main/worlds/maps/world-map.tmx +6 -0
- package/tests/fixtures/v4-game/src/modules/main/worlds/world.world +13 -0
- package/tests/latency-simulation.spec.ts +209 -0
- package/tests/remove-imports-plugin.spec.ts +56 -0
- package/tsconfig.json +2 -2
- package/vite.config.ts +7 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { loadEnv } from "vite";
|
|
4
|
+
import toml from "@iarna/toml";
|
|
5
|
+
import { Config, replaceEnvVars } from "./utils";
|
|
6
|
+
|
|
7
|
+
export function loadConfigFileSync(mode = "development", root = process.cwd()): Config {
|
|
8
|
+
const tomlFile = path.resolve(root, "rpg.toml");
|
|
9
|
+
const jsonFile = path.resolve(root, "rpg.json");
|
|
10
|
+
let config: any = {};
|
|
11
|
+
|
|
12
|
+
if (fs.existsSync(tomlFile)) {
|
|
13
|
+
config = toml.parse(fs.readFileSync(tomlFile, "utf8"));
|
|
14
|
+
} else if (fs.existsSync(jsonFile)) {
|
|
15
|
+
config = JSON.parse(fs.readFileSync(jsonFile, "utf8"));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
config = replaceEnvVars(config, loadEnv(mode, root, ""));
|
|
19
|
+
config.autostart = config.autostart ?? true;
|
|
20
|
+
config.modulesRoot = config.modulesRoot ?? "";
|
|
21
|
+
config.compilerOptions ??= {};
|
|
22
|
+
config.compilerOptions.build ??= {};
|
|
23
|
+
config.compilerOptions.build.pwaEnabled ??= true;
|
|
24
|
+
config.compilerOptions.build.outputDir ??= "dist";
|
|
25
|
+
|
|
26
|
+
if (config.modules) {
|
|
27
|
+
config.modules = config.modules.map((module: string) => {
|
|
28
|
+
if (module.startsWith(".")) {
|
|
29
|
+
return "./" + path.join(config.modulesRoot, module);
|
|
30
|
+
}
|
|
31
|
+
return module;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
config.startMap = config.startMap || config.start?.map;
|
|
36
|
+
return config as Config;
|
|
37
|
+
}
|
|
38
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as parser from "@babel/parser";
|
|
2
|
+
import _traverse from "@babel/traverse";
|
|
3
|
+
import _generate from "@babel/generator";
|
|
4
|
+
import { importDeclaration, importDefaultSpecifier, identifier, stringLiteral } from "@babel/types";
|
|
5
|
+
import type { Plugin } from "vite";
|
|
6
|
+
|
|
7
|
+
const traverse = (_traverse as any).default ?? _traverse;
|
|
8
|
+
const generate = (_generate as any).default ?? _generate;
|
|
9
|
+
|
|
10
|
+
function readStaticRequireArg(arg: any, ast: any): string {
|
|
11
|
+
if (!arg) return "";
|
|
12
|
+
if (arg.type === "StringLiteral") return arg.value;
|
|
13
|
+
if (arg.type === "Identifier") {
|
|
14
|
+
let value = "";
|
|
15
|
+
traverse(ast, {
|
|
16
|
+
VariableDeclarator(path: any) {
|
|
17
|
+
if (path.node.id?.name === arg.name && path.node.init?.type === "StringLiteral") {
|
|
18
|
+
value = path.node.init.value;
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
if (arg.type === "BinaryExpression" && arg.operator === "+") {
|
|
25
|
+
const left = readStaticRequireArg(arg.left, ast);
|
|
26
|
+
const right = readStaticRequireArg(arg.right, ast);
|
|
27
|
+
return left && right ? left + right : "";
|
|
28
|
+
}
|
|
29
|
+
return "";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default function vitePluginRequire(): Plugin {
|
|
33
|
+
return {
|
|
34
|
+
name: "rpgjs-v4-require-transform",
|
|
35
|
+
transform(code, id) {
|
|
36
|
+
const fileRegex = /(.jsx?|.tsx?)(\?.*)?$/;
|
|
37
|
+
const allowRegex = /^(?!.*node_modules(?:\/|\\)(?!rpgjs-|@rpgjs)).*$/;
|
|
38
|
+
if (!fileRegex.test(id) || !allowRegex.test(id)) {
|
|
39
|
+
return { code, map: null };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const ast = parser.parse(code, {
|
|
43
|
+
sourceType: "module",
|
|
44
|
+
plugins: ["typescript", "jsx", "decorators-legacy", "classProperties"],
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
let changed = false;
|
|
48
|
+
traverse(ast, {
|
|
49
|
+
CallExpression(path: any) {
|
|
50
|
+
if (!path.node.callee || path.node.callee.type !== "Identifier" || path.node.callee.name !== "require") return;
|
|
51
|
+
|
|
52
|
+
const request = readStaticRequireArg(path.node.arguments[0], ast);
|
|
53
|
+
if (!request) return;
|
|
54
|
+
|
|
55
|
+
const variableName = `__rpgjs_v4_require_${path.scope.generateUidIdentifier("asset").name}`;
|
|
56
|
+
ast.program.body.unshift(importDeclaration([importDefaultSpecifier(identifier(variableName))], stringLiteral(request)));
|
|
57
|
+
path.replaceWith(identifier(variableName));
|
|
58
|
+
changed = true;
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (!changed) return { code, map: null };
|
|
63
|
+
return { code: generate(ast, {}).code, map: null };
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
export interface ClientBuildConfigOptions {
|
|
5
|
+
serveMode?: boolean;
|
|
6
|
+
side?: "client" | "server";
|
|
7
|
+
type?: "rpg" | "mmorpg";
|
|
8
|
+
mode?: string;
|
|
9
|
+
config?: Config;
|
|
10
|
+
tiledMapBasePath?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface Config {
|
|
14
|
+
modules?: string[];
|
|
15
|
+
modulesRoot?: string;
|
|
16
|
+
startMap?: string;
|
|
17
|
+
start?: {
|
|
18
|
+
map?: string;
|
|
19
|
+
graphic?: string;
|
|
20
|
+
hitbox?: [number, number];
|
|
21
|
+
};
|
|
22
|
+
inputs?: Record<string, { bind: string | string[] }>;
|
|
23
|
+
spritesheetDirectories?: string[];
|
|
24
|
+
compilerOptions?: {
|
|
25
|
+
alias?: Record<string, string>;
|
|
26
|
+
build?: {
|
|
27
|
+
outputDir?: string;
|
|
28
|
+
pwaEnabled?: boolean;
|
|
29
|
+
assetsPath?: string;
|
|
30
|
+
serverUrl?: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
autostart?: boolean;
|
|
34
|
+
type?: "rpg" | "mmorpg";
|
|
35
|
+
vite?: any;
|
|
36
|
+
[key: string]: any;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface ImportObject {
|
|
40
|
+
importString: string;
|
|
41
|
+
variablesString: string;
|
|
42
|
+
folder: string;
|
|
43
|
+
relativePath: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function dedent(strings: TemplateStringsArray, ...values: unknown[]) {
|
|
47
|
+
const fullString = strings.reduce((acc, str, i) => acc + str + (values[i] ?? ""), "");
|
|
48
|
+
const lines = fullString.split("\n");
|
|
49
|
+
let minIndent = Infinity;
|
|
50
|
+
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
if (!line.trim()) continue;
|
|
53
|
+
minIndent = Math.min(minIndent, line.match(/^\s*/)?.[0].length ?? 0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (minIndent === Infinity) return fullString.trim();
|
|
57
|
+
|
|
58
|
+
return lines
|
|
59
|
+
.map((line) => line.trim() ? line.slice(minIndent) : line)
|
|
60
|
+
.join("\n")
|
|
61
|
+
.trim();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function warn(message: string) {
|
|
65
|
+
console.warn(`[RPG-JS v4 compatibility] ${message}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function toPosix(value: string) {
|
|
69
|
+
return value.replace(/\\/g, "/");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function formatVariableName(value: string) {
|
|
73
|
+
return value.replace(/\./g, "").replace(/[.@/\\ -]/g, "_").replace(/[^A-Za-z0-9_$]/g, "_");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function transformPathIfModule(moduleName: string) {
|
|
77
|
+
if (moduleName.startsWith("@rpgjs") || moduleName.startsWith("rpgjs-")) {
|
|
78
|
+
return path.join("node_modules", moduleName);
|
|
79
|
+
}
|
|
80
|
+
return moduleName;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function resolveModuleImport(moduleName: string) {
|
|
84
|
+
return moduleName.replace(/^\.\//, "");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function getAllFiles(dirPath: string): string[] {
|
|
88
|
+
if (!fs.existsSync(dirPath)) return [];
|
|
89
|
+
const files: string[] = [];
|
|
90
|
+
const dirents = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
91
|
+
|
|
92
|
+
for (const dirent of dirents) {
|
|
93
|
+
const fullPath = path.join(dirPath, dirent.name);
|
|
94
|
+
if (dirent.isDirectory()) {
|
|
95
|
+
files.push(...getAllFiles(fullPath));
|
|
96
|
+
} else {
|
|
97
|
+
files.push(fullPath);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return files;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function importPathForFile(file: string, root: string) {
|
|
105
|
+
const srcPath = path.join(root, "src");
|
|
106
|
+
if (file.startsWith(srcPath + path.sep)) {
|
|
107
|
+
return `@/${toPosix(path.relative(srcPath, file))}`;
|
|
108
|
+
}
|
|
109
|
+
return `./${toPosix(path.relative(root, file))}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function importString(modulePath: string, fileName: string, variableName = fileName, projectRoot = process.cwd()) {
|
|
113
|
+
const file = path.resolve(projectRoot, transformPathIfModule(modulePath), `${fileName}.ts`);
|
|
114
|
+
if (!fs.existsSync(file)) return "";
|
|
115
|
+
return `import ${variableName} from '${importPathForFile(file, projectRoot)}'`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function searchFolderAndTransformToImportString(
|
|
119
|
+
folderPath: string,
|
|
120
|
+
modulePath: string,
|
|
121
|
+
extensionFilter: string | string[],
|
|
122
|
+
returnCb?: (file: string, variableName: string, absoluteFile: string) => string,
|
|
123
|
+
options?: {
|
|
124
|
+
customFilter?: (file: string) => boolean;
|
|
125
|
+
},
|
|
126
|
+
projectRoot = process.cwd()
|
|
127
|
+
): ImportObject {
|
|
128
|
+
const folder = path.resolve(projectRoot, transformPathIfModule(modulePath), folderPath);
|
|
129
|
+
if (!fs.existsSync(folder)) {
|
|
130
|
+
return { variablesString: "", importString: "", folder: "", relativePath: "" };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const extensions = Array.isArray(extensionFilter) ? extensionFilter : [extensionFilter];
|
|
134
|
+
let importString = "";
|
|
135
|
+
let relativePath = "";
|
|
136
|
+
const variablesString = getAllFiles(folder)
|
|
137
|
+
.filter((file) => extensions.some((ext) => file.endsWith(ext)))
|
|
138
|
+
.filter((file) => options?.customFilter ? options.customFilter(file) : true)
|
|
139
|
+
.map((file) => {
|
|
140
|
+
const importPath = importPathForFile(file, projectRoot);
|
|
141
|
+
const variableName = formatVariableName(importPath);
|
|
142
|
+
relativePath = importPath;
|
|
143
|
+
importString += `\nimport ${variableName} from '${importPath}'`;
|
|
144
|
+
return returnCb ? returnCb(importPath, variableName, file) : variableName;
|
|
145
|
+
})
|
|
146
|
+
.join(",");
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
variablesString,
|
|
150
|
+
importString,
|
|
151
|
+
folder,
|
|
152
|
+
relativePath,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function replaceEnvVars(obj: any, envs: Record<string, string | undefined>): any {
|
|
157
|
+
if (obj == null) return obj;
|
|
158
|
+
if (typeof obj === "string" && obj.startsWith("$ENV:")) {
|
|
159
|
+
return envs[obj.slice(5)];
|
|
160
|
+
}
|
|
161
|
+
if (Array.isArray(obj)) return obj.map((item) => replaceEnvVars(item, envs));
|
|
162
|
+
if (typeof obj === "object") {
|
|
163
|
+
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, replaceEnvVars(value, envs)]));
|
|
164
|
+
}
|
|
165
|
+
return obj;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function assetsFolder(outputDir: string) {
|
|
169
|
+
return path.join(outputDir, "assets");
|
|
170
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -5,4 +5,5 @@ export { removeImportsPlugin, type RemoveImportsPluginOptions } from './remove-i
|
|
|
5
5
|
export { replaceConfigImport } from './replace-config-import';
|
|
6
6
|
export { rpgjs } from './rpgjs-plugin';
|
|
7
7
|
export { serverPlugin } from './server-plugin';
|
|
8
|
-
export { entryPointPlugin, type EntryPointPluginOptions } from './entry-point-plugin';
|
|
8
|
+
export { entryPointPlugin, type EntryPointPluginOptions } from './entry-point-plugin';
|
|
9
|
+
export { default as compatibilityV4Plugin } from './compatibility-v4';
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { existsSync, rmSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { build as viteBuild, type Plugin, type ResolvedConfig } from "vite";
|
|
4
|
+
|
|
5
|
+
interface MmorpgBuildPluginOptions {
|
|
6
|
+
rpgType: string;
|
|
7
|
+
serverEntry: string;
|
|
8
|
+
adapterEntries?: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function isBareImport(id: string): boolean {
|
|
12
|
+
return !id.startsWith(".") && !id.startsWith("/") && !id.startsWith("\0");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function resolveEntry(root: string, entry: string): string {
|
|
16
|
+
return resolve(root, entry);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function collectServerEntries(
|
|
20
|
+
root: string,
|
|
21
|
+
serverEntry: string,
|
|
22
|
+
adapterEntries: Record<string, string>,
|
|
23
|
+
): Record<string, string> {
|
|
24
|
+
const entries: Record<string, string> = {};
|
|
25
|
+
const resolvedServerEntry = resolveEntry(root, serverEntry);
|
|
26
|
+
|
|
27
|
+
if (!existsSync(resolvedServerEntry)) {
|
|
28
|
+
throw new Error(`[rpgjs:mmorpg-build] Missing server entry: ${serverEntry}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
entries.server = resolvedServerEntry;
|
|
32
|
+
|
|
33
|
+
for (const [name, entry] of Object.entries(adapterEntries)) {
|
|
34
|
+
const resolvedAdapterEntry = resolveEntry(root, entry);
|
|
35
|
+
if (!existsSync(resolvedAdapterEntry)) {
|
|
36
|
+
throw new Error(`[rpgjs:mmorpg-build] Missing adapter entry "${name}": ${entry}`);
|
|
37
|
+
}
|
|
38
|
+
entries[name] = resolvedAdapterEntry;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return entries;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function mmorpgBuildPlugin({
|
|
45
|
+
rpgType,
|
|
46
|
+
serverEntry,
|
|
47
|
+
adapterEntries = {},
|
|
48
|
+
}: MmorpgBuildPluginOptions): Plugin {
|
|
49
|
+
let config: ResolvedConfig;
|
|
50
|
+
let didBuildServer = false;
|
|
51
|
+
let didCleanDist = false;
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
name: "rpgjs:mmorpg-build",
|
|
55
|
+
apply: "build",
|
|
56
|
+
enforce: "post",
|
|
57
|
+
config(_, env) {
|
|
58
|
+
if (env.command !== "build" || rpgType !== "mmorpg") {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
build: {
|
|
64
|
+
outDir: "dist/client",
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
configResolved(resolvedConfig) {
|
|
69
|
+
config = resolvedConfig;
|
|
70
|
+
},
|
|
71
|
+
buildStart() {
|
|
72
|
+
if (rpgType !== "mmorpg" || didCleanDist) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
didCleanDist = true;
|
|
76
|
+
rmSync(resolve(config.root, "dist"), { recursive: true, force: true });
|
|
77
|
+
},
|
|
78
|
+
async closeBundle() {
|
|
79
|
+
if (rpgType !== "mmorpg" || didBuildServer) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
didBuildServer = true;
|
|
83
|
+
|
|
84
|
+
const entries = collectServerEntries(config.root, serverEntry, adapterEntries);
|
|
85
|
+
console.log(
|
|
86
|
+
`[rpgjs:mmorpg-build] Building server bundle(s): ${Object.keys(entries).join(", ")}`,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
await viteBuild({
|
|
90
|
+
configFile: false,
|
|
91
|
+
root: config.root,
|
|
92
|
+
define: config.define,
|
|
93
|
+
resolve: {
|
|
94
|
+
alias: config.resolve.alias,
|
|
95
|
+
dedupe: config.resolve.dedupe,
|
|
96
|
+
extensions: config.resolve.extensions,
|
|
97
|
+
mainFields: config.resolve.mainFields,
|
|
98
|
+
conditions: config.resolve.conditions,
|
|
99
|
+
},
|
|
100
|
+
publicDir: false,
|
|
101
|
+
build: {
|
|
102
|
+
emptyOutDir: true,
|
|
103
|
+
minify: false,
|
|
104
|
+
outDir: "dist/server",
|
|
105
|
+
sourcemap: config.build.sourcemap,
|
|
106
|
+
target: "node18",
|
|
107
|
+
lib: {
|
|
108
|
+
entry: entries,
|
|
109
|
+
formats: ["es"],
|
|
110
|
+
},
|
|
111
|
+
rollupOptions: {
|
|
112
|
+
external(id) {
|
|
113
|
+
return isBareImport(id);
|
|
114
|
+
},
|
|
115
|
+
output: {
|
|
116
|
+
entryFileNames: "[name].js",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
package/src/module-config.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { defineConfig, build } from "vite";
|
|
2
2
|
import canvasengine from "@canvasengine/compiler";
|
|
3
3
|
import dts from "vite-plugin-dts";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { resolve } from "node:path";
|
|
4
6
|
import { directivePlugin, removeImportsPlugin } from "./index";
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -22,6 +24,14 @@ import { directivePlugin, removeImportsPlugin } from "./index";
|
|
|
22
24
|
*/
|
|
23
25
|
function createBuildConfig({ side, watch }: { side: 'client' | 'server', watch: boolean }) {
|
|
24
26
|
const isClient = side === 'client';
|
|
27
|
+
const runtimeDir = resolve(process.cwd(), "runtime");
|
|
28
|
+
const resolveOptions = existsSync(runtimeDir)
|
|
29
|
+
? {
|
|
30
|
+
alias: {
|
|
31
|
+
"@common": runtimeDir,
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
: undefined;
|
|
25
35
|
|
|
26
36
|
const plugins = isClient
|
|
27
37
|
? [
|
|
@@ -36,6 +46,7 @@ function createBuildConfig({ side, watch }: { side: 'client' | 'server', watch:
|
|
|
36
46
|
|
|
37
47
|
return {
|
|
38
48
|
configFile: false as const, // Prevent using this config file
|
|
49
|
+
resolve: resolveOptions,
|
|
39
50
|
plugins: [
|
|
40
51
|
...plugins,
|
|
41
52
|
dts({
|
|
@@ -57,7 +68,9 @@ function createBuildConfig({ side, watch }: { side: 'client' | 'server', watch:
|
|
|
57
68
|
rollupOptions: {
|
|
58
69
|
external: [
|
|
59
70
|
/@rpgjs/,
|
|
71
|
+
/@signestack/,
|
|
60
72
|
"canvasengine",
|
|
73
|
+
"pixi.js",
|
|
61
74
|
"esbuild",
|
|
62
75
|
"@canvasengine/presets",
|
|
63
76
|
"rxjs",
|
package/src/rpgjs-plugin.ts
CHANGED
|
@@ -2,12 +2,37 @@ import canvasengine from "@canvasengine/compiler";
|
|
|
2
2
|
import { replaceConfigImport } from "./replace-config-import";
|
|
3
3
|
import { serverPlugin } from "./server-plugin";
|
|
4
4
|
import { entryPointPlugin } from "./entry-point-plugin";
|
|
5
|
+
import { mmorpgBuildPlugin } from "./mmorpg-build-plugin";
|
|
6
|
+
|
|
7
|
+
type MmorpgEntryPoints =
|
|
8
|
+
| string
|
|
9
|
+
| {
|
|
10
|
+
client?: string;
|
|
11
|
+
server?: string;
|
|
12
|
+
adapters?: Record<string, string>;
|
|
13
|
+
};
|
|
5
14
|
|
|
6
15
|
interface RpgjsPluginOptions {
|
|
7
16
|
server: any;
|
|
8
17
|
entryPoints?: {
|
|
9
|
-
rpg
|
|
10
|
-
mmorpg
|
|
18
|
+
rpg?: string;
|
|
19
|
+
mmorpg?: MmorpgEntryPoints;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function normalizeMmorpgEntryPoints(entryPoints?: MmorpgEntryPoints) {
|
|
24
|
+
if (!entryPoints || typeof entryPoints === "string") {
|
|
25
|
+
return {
|
|
26
|
+
client: entryPoints ?? "./src/client.ts",
|
|
27
|
+
server: "./src/server.ts",
|
|
28
|
+
adapters: {},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
client: entryPoints.client ?? "./src/client.ts",
|
|
34
|
+
server: entryPoints.server ?? "./src/server.ts",
|
|
35
|
+
adapters: entryPoints.adapters ?? {},
|
|
11
36
|
};
|
|
12
37
|
}
|
|
13
38
|
|
|
@@ -15,15 +40,22 @@ export function rpgjs({
|
|
|
15
40
|
server,
|
|
16
41
|
entryPoints
|
|
17
42
|
}: RpgjsPluginOptions) {
|
|
43
|
+
const mmorpgEntryPoints = normalizeMmorpgEntryPoints(entryPoints?.mmorpg);
|
|
44
|
+
|
|
18
45
|
return [
|
|
19
46
|
canvasengine(),
|
|
20
47
|
replaceConfigImport(),
|
|
21
48
|
serverPlugin(server),
|
|
49
|
+
mmorpgBuildPlugin({
|
|
50
|
+
rpgType: process.env.RPG_TYPE || "rpg",
|
|
51
|
+
serverEntry: mmorpgEntryPoints.server,
|
|
52
|
+
adapterEntries: mmorpgEntryPoints.adapters,
|
|
53
|
+
}),
|
|
22
54
|
entryPointPlugin({
|
|
23
55
|
entryPoints: {
|
|
24
56
|
rpg: entryPoints?.rpg ?? './src/standalone.ts',
|
|
25
|
-
mmorpg:
|
|
57
|
+
mmorpg: mmorpgEntryPoints.client,
|
|
26
58
|
}
|
|
27
59
|
})
|
|
28
60
|
]
|
|
29
|
-
}
|
|
61
|
+
}
|