aplosjs 0.15.0
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/README.md +28 -0
- package/aplos.config.dist.js +30 -0
- package/bin/aplos +60 -0
- package/create-aplos/index.js +95 -0
- package/create-aplos/package.json +29 -0
- package/create-aplos/templates/minimal/README.md +38 -0
- package/create-aplos/templates/minimal/_gitignore +7 -0
- package/create-aplos/templates/minimal/aplos.config.js +13 -0
- package/create-aplos/templates/minimal/package.json +22 -0
- package/create-aplos/templates/minimal/public/favicon.svg +4 -0
- package/create-aplos/templates/minimal/src/pages/_app.tsx +6 -0
- package/create-aplos/templates/minimal/src/pages/about.tsx +24 -0
- package/create-aplos/templates/minimal/src/pages/index.tsx +40 -0
- package/create-aplos/templates/minimal/src/styles/global.css +53 -0
- package/create-aplos/templates/minimal/tsconfig.json +18 -0
- package/package.json +92 -0
- package/postcss.config.js +9 -0
- package/rspack.config.js +306 -0
- package/rspack.ssr.config.js +129 -0
- package/src/build/config.js +42 -0
- package/src/build/css-noop-loader.cjs +3 -0
- package/src/build/router.js +609 -0
- package/src/build/ssg.js +198 -0
- package/src/client/public/index.html +8 -0
- package/src/command/build.js +105 -0
- package/src/command/create.js +91 -0
- package/src/command/devServer.js +198 -0
- package/src/command/router.js +137 -0
- package/src/components/head.jsx +65 -0
- package/src/components/navigation.jsx +11 -0
- package/src/config.js +5 -0
- package/src/pages/_app.tsx +9 -0
- package/src/pages/blog/[slug].tsx +6 -0
- package/src/pages/crash.tsx +6 -0
- package/src/pages/index.tsx +10 -0
- package/src/pages/test.tsx +5 -0
- package/src/runtime/DefaultErrorPage.jsx +76 -0
- package/src/runtime/ErrorBoundary.jsx +40 -0
- package/src/runtime/MiddlewareGate.jsx +149 -0
- package/src/runtime/app-ssr.jsx +42 -0
- package/src/runtime/app.jsx +126 -0
- package/src/runtime/default-middleware.js +10 -0
- package/src/runtime/default-not-found.jsx +3 -0
- package/src/runtime/passthrough-layout.jsx +5 -0
- package/src/runtime/redirect.js +46 -0
- package/src/runtime/ssr-entry.jsx +104 -0
- package/templates/minimal/README.md +38 -0
- package/templates/minimal/_gitignore +7 -0
- package/templates/minimal/aplos.config.js +13 -0
- package/templates/minimal/package.json +22 -0
- package/templates/minimal/public/favicon.svg +4 -0
- package/templates/minimal/src/pages/_app.tsx +6 -0
- package/templates/minimal/src/pages/about.tsx +24 -0
- package/templates/minimal/src/pages/index.tsx +40 -0
- package/templates/minimal/src/styles/global.css +53 -0
- package/templates/minimal/tsconfig.json +18 -0
package/rspack.config.js
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { HtmlRspackPlugin, CssExtractRspackPlugin, CopyRspackPlugin } from "@rspack/core";
|
|
3
|
+
import ReactRefreshPlugin from "@rspack/plugin-react-refresh";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import { pathToFileURL } from "url";
|
|
7
|
+
import { merge } from "webpack-merge";
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
|
|
12
|
+
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
13
|
+
const projectDirectory = process.cwd();
|
|
14
|
+
|
|
15
|
+
// Determine HTML template path
|
|
16
|
+
// Priority: 1. public/index.html (user override), 2. default template
|
|
17
|
+
const defaultTemplate = path.resolve(__dirname, "./src/client/public/index.html");
|
|
18
|
+
const userTemplate = path.resolve(projectDirectory, "public/index.html");
|
|
19
|
+
|
|
20
|
+
let htmlTemplate = defaultTemplate;
|
|
21
|
+
if (fs.existsSync(userTemplate)) {
|
|
22
|
+
htmlTemplate = userTemplate;
|
|
23
|
+
console.log("Using custom HTML template from public/index.html");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Load project configuration
|
|
27
|
+
let headConfig = { meta: [], link: [], script: [] };
|
|
28
|
+
let reactCompilerEnabled = false;
|
|
29
|
+
const configPath = path.join(projectDirectory, 'aplos.config.js');
|
|
30
|
+
if (fs.existsSync(configPath)) {
|
|
31
|
+
try {
|
|
32
|
+
const configModule = await import(pathToFileURL(configPath).href);
|
|
33
|
+
const config = configModule.default || configModule;
|
|
34
|
+
headConfig = config.head || headConfig;
|
|
35
|
+
reactCompilerEnabled = config.reactCompiler === true;
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('Error loading configuration:', error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Custom plugin to inject head tags
|
|
42
|
+
class InjectHeadTagsPlugin {
|
|
43
|
+
constructor(config) {
|
|
44
|
+
this.headConfig = config;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
apply(compiler) {
|
|
48
|
+
compiler.hooks.thisCompilation.tap('InjectHeadTagsPlugin', (compilation) => {
|
|
49
|
+
const hooks = compilation.hooks;
|
|
50
|
+
|
|
51
|
+
hooks.processAssets.tapAsync(
|
|
52
|
+
{
|
|
53
|
+
name: 'InjectHeadTagsPlugin',
|
|
54
|
+
stage: compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE,
|
|
55
|
+
},
|
|
56
|
+
(assets, callback) => {
|
|
57
|
+
const htmlFiles = Object.keys(assets).filter(file => file.endsWith('.html'));
|
|
58
|
+
|
|
59
|
+
htmlFiles.forEach(filename => {
|
|
60
|
+
const asset = assets[filename];
|
|
61
|
+
let html = asset.source().toString();
|
|
62
|
+
|
|
63
|
+
let headTags = '';
|
|
64
|
+
|
|
65
|
+
// Add meta tags
|
|
66
|
+
if (this.headConfig.meta) {
|
|
67
|
+
this.headConfig.meta.forEach(meta => {
|
|
68
|
+
const attrs = Object.entries(meta)
|
|
69
|
+
.map(([key, value]) => `${key}="${value}"`)
|
|
70
|
+
.join(' ');
|
|
71
|
+
headTags += `\n <meta ${attrs}>`;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Add link tags
|
|
76
|
+
if (this.headConfig.link) {
|
|
77
|
+
this.headConfig.link.forEach(link => {
|
|
78
|
+
const attrs = Object.entries(link)
|
|
79
|
+
.map(([key, value]) => `${key}="${value}"`)
|
|
80
|
+
.join(' ');
|
|
81
|
+
headTags += `\n <link ${attrs}>`;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Add script tags
|
|
86
|
+
if (this.headConfig.script) {
|
|
87
|
+
this.headConfig.script.forEach(script => {
|
|
88
|
+
const attrs = Object.entries(script)
|
|
89
|
+
.map(([key, value]) => {
|
|
90
|
+
if (typeof value === 'boolean' && value) {
|
|
91
|
+
return key;
|
|
92
|
+
}
|
|
93
|
+
return typeof value !== 'boolean' ? `${key}="${value}"` : '';
|
|
94
|
+
})
|
|
95
|
+
.filter(Boolean)
|
|
96
|
+
.join(' ');
|
|
97
|
+
headTags += `\n <script ${attrs}></script>`;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Add title if configured
|
|
102
|
+
if (this.headConfig.defaultTitle) {
|
|
103
|
+
headTags = `\n <title>${this.headConfig.defaultTitle}</title>` + headTags;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Inject into HTML
|
|
107
|
+
html = html.replace('</head>', `${headTags}\n </head>`);
|
|
108
|
+
|
|
109
|
+
assets[filename] = {
|
|
110
|
+
source: () => html,
|
|
111
|
+
size: () => html.length
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
callback();
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const plugins = [
|
|
123
|
+
new HtmlRspackPlugin({
|
|
124
|
+
template: htmlTemplate,
|
|
125
|
+
minify: !isDevelopment,
|
|
126
|
+
}),
|
|
127
|
+
new InjectHeadTagsPlugin(headConfig),
|
|
128
|
+
new CssExtractRspackPlugin({
|
|
129
|
+
filename: isDevelopment ? "[name].css" : "[name].[contenthash:8].css",
|
|
130
|
+
chunkFilename: isDevelopment ? "[id].css" : "[id].[contenthash:8].css",
|
|
131
|
+
}),
|
|
132
|
+
];
|
|
133
|
+
|
|
134
|
+
if (isDevelopment) {
|
|
135
|
+
plugins.push(new ReactRefreshPlugin());
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const userPublicDir = path.resolve(projectDirectory, "public");
|
|
139
|
+
if (!isDevelopment && fs.existsSync(userPublicDir)) {
|
|
140
|
+
plugins.push(
|
|
141
|
+
new CopyRspackPlugin({
|
|
142
|
+
patterns: [
|
|
143
|
+
{
|
|
144
|
+
from: userPublicDir,
|
|
145
|
+
to: path.resolve(projectDirectory, "./public/dist"),
|
|
146
|
+
globOptions: {
|
|
147
|
+
ignore: ["**/dist/**", "**/index.html"],
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
})
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Load project's rspack.config.js if it exists
|
|
156
|
+
let userConfig = {};
|
|
157
|
+
const userConfigPath = path.resolve(projectDirectory, "rspack.config.js");
|
|
158
|
+
if (fs.existsSync(userConfigPath)) {
|
|
159
|
+
try {
|
|
160
|
+
const userModule = await import(pathToFileURL(userConfigPath).href);
|
|
161
|
+
userConfig = userModule.default || userModule;
|
|
162
|
+
console.log("Using custom rspack config from rspack.config.js");
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.error("Error loading project rspack.config.js:", error.message);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const frameworkConfig = {
|
|
169
|
+
mode: isDevelopment ? "development" : "production",
|
|
170
|
+
devtool: isDevelopment ? "eval-source-map" : "hidden-source-map",
|
|
171
|
+
cache: {
|
|
172
|
+
type: "filesystem",
|
|
173
|
+
buildDependencies: {
|
|
174
|
+
config: [path.resolve(__dirname, "rspack.config.js")],
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
stats: isDevelopment ? 'none' : 'normal',
|
|
178
|
+
infrastructureLogging: {
|
|
179
|
+
level: isDevelopment ? 'error' : 'info',
|
|
180
|
+
},
|
|
181
|
+
optimization: {
|
|
182
|
+
minimize: !isDevelopment,
|
|
183
|
+
splitChunks: !isDevelopment
|
|
184
|
+
? {
|
|
185
|
+
chunks: "all",
|
|
186
|
+
cacheGroups: {
|
|
187
|
+
vendor: {
|
|
188
|
+
test: /[\\/]node_modules[\\/]/,
|
|
189
|
+
name: "vendors",
|
|
190
|
+
chunks: "all",
|
|
191
|
+
priority: 10,
|
|
192
|
+
},
|
|
193
|
+
common: {
|
|
194
|
+
minChunks: 2,
|
|
195
|
+
name: "common",
|
|
196
|
+
chunks: "all",
|
|
197
|
+
priority: 5,
|
|
198
|
+
reuseExistingChunk: true,
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
: false,
|
|
203
|
+
usedExports: !isDevelopment,
|
|
204
|
+
sideEffects: false,
|
|
205
|
+
},
|
|
206
|
+
output: {
|
|
207
|
+
path: path.resolve(process.cwd(), "./public/dist"),
|
|
208
|
+
publicPath: "/",
|
|
209
|
+
filename: isDevelopment ? "[name].js" : "[name].[contenthash:8].js",
|
|
210
|
+
chunkFilename: isDevelopment ? "[name].js" : "[name].[contenthash:8].js",
|
|
211
|
+
clean: true,
|
|
212
|
+
},
|
|
213
|
+
module: {
|
|
214
|
+
rules: [
|
|
215
|
+
{
|
|
216
|
+
test: /\.(js|ts|jsx|tsx)$/,
|
|
217
|
+
exclude: /node_modules\/(?!aplos)|bower_components|\.aplos[\\/]cache/,
|
|
218
|
+
use: [
|
|
219
|
+
// Loaders run bottom-up: SWC transpiles first (TS/JSX → JS), then Babel
|
|
220
|
+
// applies React Compiler (opt-in) and react-refresh/babel (dev).
|
|
221
|
+
// Babel is skipped entirely when neither is needed — SWC alone is
|
|
222
|
+
// ~7x faster. Enable React Compiler via `reactCompiler: true` in
|
|
223
|
+
// aplos.config.js when auto-memoization benefits justify the cost.
|
|
224
|
+
(isDevelopment || reactCompilerEnabled) && {
|
|
225
|
+
loader: "babel-loader",
|
|
226
|
+
options: {
|
|
227
|
+
presets: [],
|
|
228
|
+
plugins: [
|
|
229
|
+
reactCompilerEnabled && ["babel-plugin-react-compiler", {}],
|
|
230
|
+
isDevelopment && "react-refresh/babel",
|
|
231
|
+
].filter(Boolean),
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
loader: "builtin:swc-loader",
|
|
236
|
+
options: {
|
|
237
|
+
jsc: {
|
|
238
|
+
parser: {
|
|
239
|
+
syntax: "typescript",
|
|
240
|
+
tsx: true,
|
|
241
|
+
},
|
|
242
|
+
transform: {
|
|
243
|
+
react: {
|
|
244
|
+
runtime: "automatic",
|
|
245
|
+
refresh: isDevelopment,
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
env: {
|
|
250
|
+
targets: "defaults",
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
].filter(Boolean),
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
test: /\.css$/,
|
|
258
|
+
use: [CssExtractRspackPlugin.loader, "css-loader", "postcss-loader"],
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
},
|
|
262
|
+
resolveLoader: {
|
|
263
|
+
modules: [
|
|
264
|
+
path.resolve(projectDirectory, "node_modules"),
|
|
265
|
+
path.resolve(__dirname, "node_modules"),
|
|
266
|
+
"node_modules",
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
resolve: {
|
|
270
|
+
alias: {
|
|
271
|
+
// Force single instance (avoid duplicates when framework != project dir).
|
|
272
|
+
// Use `$` exact-match so subpath imports (e.g. `react-router/dom`) still
|
|
273
|
+
// resolve via the package's exports map instead of being rewritten to a
|
|
274
|
+
// directory path.
|
|
275
|
+
"react$": path.resolve(projectDirectory, "node_modules/react"),
|
|
276
|
+
"react-dom$": path.resolve(projectDirectory, "node_modules/react-dom"),
|
|
277
|
+
"react-router-dom$": path.resolve(projectDirectory, "node_modules/react-router-dom"),
|
|
278
|
+
"react-router$": path.resolve(projectDirectory, "node_modules/react-router"),
|
|
279
|
+
"aplos/config": path.resolve(__dirname, "src/config.js"),
|
|
280
|
+
"aplos/navigation": path.resolve(
|
|
281
|
+
__dirname,
|
|
282
|
+
"src/components/navigation.jsx",
|
|
283
|
+
),
|
|
284
|
+
"aplos/head": path.resolve(__dirname, "src/components/head.jsx"),
|
|
285
|
+
"@": projectDirectory + "/src",
|
|
286
|
+
"~": projectDirectory + "/src",
|
|
287
|
+
"@aplos_config": projectDirectory + "/.aplos/cache/config.js",
|
|
288
|
+
"@aplos_routes": projectDirectory + "/.aplos/cache/routes.js",
|
|
289
|
+
"@aplos_pages": projectDirectory + "/.aplos/cache/pages.js",
|
|
290
|
+
"@aplos_head": projectDirectory + "/.aplos/cache/head.js",
|
|
291
|
+
"@aplos_middleware": projectDirectory + "/.aplos/cache/middleware.js",
|
|
292
|
+
"aplos/internal/passthrough-layout": path.resolve(__dirname, "src/runtime/passthrough-layout.jsx"),
|
|
293
|
+
"aplos/internal/default-not-found": path.resolve(__dirname, "src/runtime/default-not-found.jsx"),
|
|
294
|
+
"aplos/internal/default-middleware": path.resolve(__dirname, "src/runtime/default-middleware.js"),
|
|
295
|
+
"aplos/redirect": path.resolve(__dirname, "src/runtime/redirect.js"),
|
|
296
|
+
},
|
|
297
|
+
extensions: [".ts", ".tsx", ".js", ".jsx"],
|
|
298
|
+
},
|
|
299
|
+
plugins,
|
|
300
|
+
devServer: {
|
|
301
|
+
hot: true,
|
|
302
|
+
historyApiFallback: true,
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export default merge(frameworkConfig, userConfig);
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { CssExtractRspackPlugin } from "@rspack/core";
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import { merge } from "webpack-merge";
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
const projectDirectory = process.cwd();
|
|
11
|
+
|
|
12
|
+
// Inherit project aliases/loaders from the client config (e.g. `@docs` alias,
|
|
13
|
+
// `.md` loader). A dedicated `rspack.ssr.config.js` in the project can override.
|
|
14
|
+
let userConfig = {};
|
|
15
|
+
const userClientConfigPath = path.resolve(projectDirectory, "rspack.config.js");
|
|
16
|
+
if (fs.existsSync(userClientConfigPath)) {
|
|
17
|
+
try {
|
|
18
|
+
const userModule = await import(pathToFileURL(userClientConfigPath).href);
|
|
19
|
+
userConfig = userModule.default || userModule;
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error("Error loading project rspack.config.js for SSR:", error.message);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const userSSRConfigPath = path.resolve(projectDirectory, "rspack.ssr.config.js");
|
|
25
|
+
if (fs.existsSync(userSSRConfigPath)) {
|
|
26
|
+
try {
|
|
27
|
+
const userModule = await import(pathToFileURL(userSSRConfigPath).href);
|
|
28
|
+
userConfig = merge(userConfig, userModule.default || userModule);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.error("Error loading project rspack.ssr.config.js:", error.message);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const frameworkConfig = {
|
|
35
|
+
mode: "production",
|
|
36
|
+
target: "node",
|
|
37
|
+
devtool: false,
|
|
38
|
+
stats: "errors-warnings",
|
|
39
|
+
infrastructureLogging: { level: "error" },
|
|
40
|
+
output: {
|
|
41
|
+
path: path.resolve(projectDirectory, "./.aplos/cache"),
|
|
42
|
+
filename: "ssr-bundle.cjs",
|
|
43
|
+
library: { type: "commonjs2" },
|
|
44
|
+
clean: false,
|
|
45
|
+
},
|
|
46
|
+
externals: {
|
|
47
|
+
react: "commonjs react",
|
|
48
|
+
"react-dom": "commonjs react-dom",
|
|
49
|
+
"react-dom/server": "commonjs react-dom/server",
|
|
50
|
+
"react-router": "commonjs react-router",
|
|
51
|
+
"react-router-dom": "commonjs react-router-dom",
|
|
52
|
+
},
|
|
53
|
+
optimization: {
|
|
54
|
+
minimize: false,
|
|
55
|
+
splitChunks: false,
|
|
56
|
+
usedExports: false,
|
|
57
|
+
sideEffects: false,
|
|
58
|
+
},
|
|
59
|
+
module: {
|
|
60
|
+
rules: [
|
|
61
|
+
{
|
|
62
|
+
test: /\.(js|ts|jsx|tsx)$/,
|
|
63
|
+
exclude: /node_modules\/(?!aplos)|bower_components|\.aplos[\\/]cache/,
|
|
64
|
+
use: [
|
|
65
|
+
{
|
|
66
|
+
loader: "builtin:swc-loader",
|
|
67
|
+
options: {
|
|
68
|
+
jsc: {
|
|
69
|
+
parser: { syntax: "typescript", tsx: true },
|
|
70
|
+
transform: {
|
|
71
|
+
react: { runtime: "automatic", refresh: false },
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
env: { targets: { node: "18" } },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
test: /\.css$/,
|
|
81
|
+
use: [CssExtractRspackPlugin.loader, "css-loader", "postcss-loader"],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
test: /\.md$/,
|
|
85
|
+
type: "asset/source",
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
plugins: [
|
|
90
|
+
new CssExtractRspackPlugin({
|
|
91
|
+
filename: "ssr-[name].css",
|
|
92
|
+
chunkFilename: "ssr-[id].css",
|
|
93
|
+
}),
|
|
94
|
+
],
|
|
95
|
+
resolveLoader: {
|
|
96
|
+
modules: [
|
|
97
|
+
path.resolve(projectDirectory, "node_modules"),
|
|
98
|
+
path.resolve(__dirname, "node_modules"),
|
|
99
|
+
"node_modules",
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
resolve: {
|
|
103
|
+
alias: {
|
|
104
|
+
"react": path.resolve(projectDirectory, "node_modules/react"),
|
|
105
|
+
"react-dom": path.resolve(projectDirectory, "node_modules/react-dom"),
|
|
106
|
+
"react-router-dom": path.resolve(projectDirectory, "node_modules/react-router-dom"),
|
|
107
|
+
"react-router": path.resolve(projectDirectory, "node_modules/react-router"),
|
|
108
|
+
"aplos/config": path.resolve(__dirname, "src/config.js"),
|
|
109
|
+
"aplos/navigation": path.resolve(__dirname, "src/components/navigation.jsx"),
|
|
110
|
+
"aplos/head": path.resolve(__dirname, "src/components/head.jsx"),
|
|
111
|
+
// Route middleware does not run during static rendering, but a shared
|
|
112
|
+
// module may still import `redirect`. Resolve it so the SSG build does
|
|
113
|
+
// not fail on a missing module — the sentinel is inert without the
|
|
114
|
+
// client MiddlewareGate.
|
|
115
|
+
"aplos/redirect": path.resolve(__dirname, "src/runtime/redirect.js"),
|
|
116
|
+
"@": projectDirectory + "/src",
|
|
117
|
+
"~": projectDirectory + "/src",
|
|
118
|
+
"@aplos_config": projectDirectory + "/.aplos/cache/config.js",
|
|
119
|
+
"@aplos_routes": projectDirectory + "/.aplos/cache/routes.js",
|
|
120
|
+
"@aplos_pages": projectDirectory + "/.aplos/cache/pages.js",
|
|
121
|
+
"@aplos_head": projectDirectory + "/.aplos/cache/head.js",
|
|
122
|
+
"aplos/internal/passthrough-layout": path.resolve(__dirname, "src/runtime/passthrough-layout.jsx"),
|
|
123
|
+
"aplos/internal/default-not-found": path.resolve(__dirname, "src/runtime/default-not-found.jsx"),
|
|
124
|
+
},
|
|
125
|
+
extensions: [".ts", ".tsx", ".js", ".jsx"],
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export default merge(frameworkConfig, userConfig);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { pathToFileURL } from "url";
|
|
4
|
+
|
|
5
|
+
export default async () => {
|
|
6
|
+
const cacheDirectory = process.cwd() + "/.aplos/cache";
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
if (!fs.existsSync(cacheDirectory)) {
|
|
10
|
+
fs.mkdirSync(cacheDirectory, {recursive: true});
|
|
11
|
+
}
|
|
12
|
+
} catch (err) {
|
|
13
|
+
console.error(err);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let aplos = {
|
|
17
|
+
server: {
|
|
18
|
+
port: process.env.APLOS_SERVER_PORT || 3000,
|
|
19
|
+
},
|
|
20
|
+
routes: [],
|
|
21
|
+
head: {
|
|
22
|
+
defaultTitle: '',
|
|
23
|
+
titleTemplate: '',
|
|
24
|
+
meta: [],
|
|
25
|
+
link: [],
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const configPath = path.join(process.cwd(), 'aplos.config.js');
|
|
30
|
+
|
|
31
|
+
if (fs.existsSync(configPath)) {
|
|
32
|
+
try {
|
|
33
|
+
const configModule = await import(pathToFileURL(configPath).href);
|
|
34
|
+
const config = configModule.default || configModule;
|
|
35
|
+
aplos = {...aplos, ...config};
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('Error loading configuration:', error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return aplos;
|
|
42
|
+
};
|