xpine 0.0.20 → 0.0.22
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/TODO +0 -2
- package/dist/index.js +357 -128
- package/dist/src/build/esbuild/addDotJS.d.ts +5 -0
- package/dist/src/build/esbuild/addDotJS.d.ts.map +1 -0
- package/dist/src/build/esbuild/getDataFiles.d.ts +5 -0
- package/dist/src/build/esbuild/getDataFiles.d.ts.map +1 -0
- package/dist/src/build/esbuild/transformTSXFiles.d.ts +6 -0
- package/dist/src/build/esbuild/transformTSXFiles.d.ts.map +1 -0
- package/dist/src/express.d.ts +3 -0
- package/dist/src/express.d.ts.map +1 -1
- package/dist/src/runDevServer.d.ts.map +1 -1
- package/dist/src/scripts/build.d.ts +5 -1
- package/dist/src/scripts/build.d.ts.map +1 -1
- package/dist/src/scripts/xpine-build.js +249 -104
- package/dist/src/scripts/xpine-dev.js +294 -114
- package/dist/src/static/spa.js +2 -1
- package/dist/src/util/config-file.d.ts +6 -0
- package/dist/src/util/config-file.d.ts.map +1 -0
- package/dist/src/util/constants.d.ts +3 -0
- package/dist/src/util/constants.d.ts.map +1 -0
- package/dist/src/util/get-config.d.ts.map +1 -1
- package/dist/src/util/postcss/remove-layers.d.ts +1 -1
- package/dist/src/util/regex.d.ts +11 -0
- package/dist/src/util/regex.d.ts.map +1 -0
- package/dist/src/util/require.d.ts.map +1 -1
- package/dist/types.d.ts +31 -2
- package/dist/types.d.ts.map +1 -1
- package/eslint.config.mjs +27 -0
- package/package.json +18 -5
- package/tests/e2e/alpine.spec.ts +14 -0
- package/tests/e2e/app-build.spec.ts +73 -0
- package/tests/e2e/spa.spec.ts +23 -0
- package/tests/e2e/tests-examples/demo-todo-app.spec.ts +437 -0
- package/tests/eslint.config.mjs +27 -0
- package/tests/package-lock.json +8941 -0
- package/tests/package.json +89 -0
- package/tests/playwright.config.ts +81 -0
- package/tests/tsconfig.json +46 -0
- package/tests/xpine.config.mjs +1 -0
- package/types.ts +34 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addDotJS.d.ts","sourceRoot":"","sources":["../../../../src/build/esbuild/addDotJS.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO;;;EA0B3F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getDataFiles.d.ts","sourceRoot":"","sources":["../../../../src/build/esbuild/getDataFiles.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,SAAS,EAAE,GAAG,EAAE;;;EAiBpD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformTSXFiles.d.ts","sourceRoot":"","sources":["../../../../src/build/esbuild/transformTSXFiles.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,aAAa,EAAE,aAAa,EAAE,EAAE,eAAe,EAAE,MAAM,EAAE;;;EA2BlG"}
|
package/dist/src/express.d.ts
CHANGED
|
@@ -4,4 +4,7 @@ export declare function createRouter(): Promise<{
|
|
|
4
4
|
routeResults: any[];
|
|
5
5
|
}>;
|
|
6
6
|
export declare function createXPineRouter(app: any, beforeErrorRoute?: (app: Express) => void): Promise<void>;
|
|
7
|
+
export declare function routeHasStaticPath(route: string, params: {
|
|
8
|
+
[key: string]: string;
|
|
9
|
+
}): string | false;
|
|
7
10
|
//# sourceMappingURL=express.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/express.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAgB,OAAO,EAAqB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/express.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAgB,OAAO,EAAqB,MAAM,SAAS,CAAC;AAY5E,wBAAsB,YAAY;;;GAqGjC;AAiBD,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,iBA6B1F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,KAAK,CAWnG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runDevServer.d.ts","sourceRoot":"","sources":["../../src/runDevServer.ts"],"names":[],"mappings":"AAYA,wBAAsB,YAAY,
|
|
1
|
+
{"version":3,"file":"runDevServer.d.ts","sourceRoot":"","sources":["../../src/runDevServer.ts"],"names":[],"mappings":"AAYA,wBAAsB,YAAY,kBA6DjC"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { ConfigFile, ComponentData } from '../../types';
|
|
2
|
+
export declare function buildApp(isDev?: boolean, removePreviousBuild?: boolean): Promise<void>;
|
|
2
3
|
export declare function buildCSS(): Promise<void>;
|
|
3
4
|
export declare function buildPublicFolderSymlinks(): Promise<void>;
|
|
4
5
|
export declare function logSize(pathName: string, type: 'app' | 'client' | 'css', validExtensions?: string[]): Promise<void>;
|
|
6
|
+
export declare function buildFilesWithConfigs(componentData: ComponentData[]): Promise<void>;
|
|
7
|
+
export declare function buildStaticFiles(config: ConfigFile, component: ComponentData, componentImport: any, builtComponentPath: string): Promise<void>;
|
|
8
|
+
export declare function getComponentDynamicPaths(componentPath: string): string[];
|
|
5
9
|
//# sourceMappingURL=build.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/scripts/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/scripts/build.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,UAAU,EAA2B,aAAa,EAAE,MAAM,aAAa,CAAC;AASjF,wBAAsB,QAAQ,CAAC,KAAK,UAAQ,EAAE,mBAAmB,UAAQ,iBAgBxE;AA2ID,wBAAsB,QAAQ,kBAW7B;AAGD,wBAAsB,yBAAyB,kBAgB9C;AAED,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,EAAE,eAAe,WAAkB,iBAahH;AAED,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,aAAa,EAAE,iBAezE;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,iBA4DpI;AAED,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAQxE"}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/scripts/build.ts
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import path5 from "path";
|
|
5
|
+
import fs5 from "fs-extra";
|
|
6
6
|
import { build } from "esbuild";
|
|
7
|
-
import
|
|
8
|
-
import ts2 from "typescript";
|
|
7
|
+
import ts3 from "typescript";
|
|
9
8
|
|
|
10
9
|
// src/build/typescript-builder.ts
|
|
11
10
|
import ts from "typescript";
|
|
@@ -109,17 +108,6 @@ function removeClientScriptInTSXFile(pathName, source) {
|
|
|
109
108
|
clientDataStart
|
|
110
109
|
};
|
|
111
110
|
}
|
|
112
|
-
function createStaticFile(pathName, source) {
|
|
113
|
-
source.forEachChild((child) => {
|
|
114
|
-
if (child.kind === ts.SyntaxKind.ExpressionStatement) {
|
|
115
|
-
const text = child.getText(source);
|
|
116
|
-
const cleanedText = text.replace(/["';]/g, "");
|
|
117
|
-
if (cleanedText === "xpine-static") {
|
|
118
|
-
console.log("make this file static", pathName);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
111
|
|
|
124
112
|
// src/scripts/build.ts
|
|
125
113
|
import { globSync } from "glob";
|
|
@@ -135,6 +123,10 @@ var require_default = createRequire(import.meta.url);
|
|
|
135
123
|
function getXPineDistDir() {
|
|
136
124
|
const dir = import.meta.dirname;
|
|
137
125
|
const splitDir = dir.split("/xpine/dist");
|
|
126
|
+
if (splitDir.length === 1) {
|
|
127
|
+
const splitDirSingle = dir.split("/xpine/");
|
|
128
|
+
return splitDirSingle[0] + "/xpine/dist";
|
|
129
|
+
}
|
|
138
130
|
return splitDir[0] + "/xpine/dist";
|
|
139
131
|
}
|
|
140
132
|
|
|
@@ -176,6 +168,9 @@ var configDefaults = {
|
|
|
176
168
|
get pagesDir() {
|
|
177
169
|
return path2.join(this.srcDir, "./pages");
|
|
178
170
|
},
|
|
171
|
+
get distPagesDir() {
|
|
172
|
+
return path2.join(this.distDir, "./pages");
|
|
173
|
+
},
|
|
179
174
|
get publicDir() {
|
|
180
175
|
return path2.join(this.srcDir, "./public");
|
|
181
176
|
},
|
|
@@ -211,21 +206,152 @@ var plugin = (opts = {}) => {
|
|
|
211
206
|
plugin.postcss = true;
|
|
212
207
|
var remove_layers_default = plugin;
|
|
213
208
|
|
|
209
|
+
// src/build/esbuild/transformTSXFiles.ts
|
|
210
|
+
import fs2 from "fs-extra";
|
|
211
|
+
import ts2 from "typescript";
|
|
212
|
+
|
|
213
|
+
// src/util/regex.ts
|
|
214
|
+
var regex_default = {
|
|
215
|
+
dotTsx: /.tsx/,
|
|
216
|
+
hasLetters: /[A-Za-z0-9]/g,
|
|
217
|
+
configFile: /\+config\.[tj]sx?/g,
|
|
218
|
+
dynamicRoutes: /(\[)(.*?)(\])/g,
|
|
219
|
+
isDynamicRoute: /\[(.*)\]/g,
|
|
220
|
+
endsWithTSX: /\.tsx$/,
|
|
221
|
+
endsWithJSX: /\.jsx$/
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
// src/util/config-file.ts
|
|
225
|
+
import path3 from "path";
|
|
226
|
+
function sourcePathToDistPath(sourcePath) {
|
|
227
|
+
return sourcePath?.replace(config.srcDir, config.distDir)?.replace(/\.ts$/, ".js")?.replace(/\.tsx$/, ".js");
|
|
228
|
+
}
|
|
229
|
+
function getConfigFiles(pathName, pageConfigFiles, returnDistPaths = true) {
|
|
230
|
+
const configs = [];
|
|
231
|
+
for (const configFile of pageConfigFiles) {
|
|
232
|
+
const result = path3.relative(pathName, configFile)?.replace(regex_default.configFile, "");
|
|
233
|
+
const hasLetters = result.match(regex_default.hasLetters);
|
|
234
|
+
if (!hasLetters) {
|
|
235
|
+
configs.push(returnDistPaths ? sourcePathToDistPath(configFile) : configFile);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (!configs.length) return null;
|
|
239
|
+
return configs.sort((a, b) => b.length - a.length);
|
|
240
|
+
}
|
|
241
|
+
async function getCompleteConfig(configFiles, cacheKey) {
|
|
242
|
+
let config2 = {};
|
|
243
|
+
for (const configFile of configFiles) {
|
|
244
|
+
config2 = {
|
|
245
|
+
...(await import(configFile + `?cache=${cacheKey}`)).default,
|
|
246
|
+
...config2
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
return config2;
|
|
250
|
+
}
|
|
251
|
+
function isAConfigFile(pathName) {
|
|
252
|
+
return !!pathName.match(regex_default.configFile);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// src/build/esbuild/transformTSXFiles.ts
|
|
256
|
+
function transformTSXFiles(componentData, pageConfigFiles) {
|
|
257
|
+
return {
|
|
258
|
+
name: "transform-tsx-files",
|
|
259
|
+
setup(build2) {
|
|
260
|
+
build2.onLoad({ filter: regex_default.dotTsx }, async (args) => {
|
|
261
|
+
const content = fs2.readFileSync(args.path, "utf-8");
|
|
262
|
+
const source = ts2.createSourceFile(
|
|
263
|
+
args.path,
|
|
264
|
+
content,
|
|
265
|
+
ts2.ScriptTarget.Latest
|
|
266
|
+
);
|
|
267
|
+
const cleanedContent = removeClientScriptInTSXFile(args.path, source);
|
|
268
|
+
const htmlImportStart = "import { html } from 'xpine';\n";
|
|
269
|
+
const newContent = `${htmlImportStart}${cleanedContent.content}`;
|
|
270
|
+
componentData.push({
|
|
271
|
+
...args,
|
|
272
|
+
contents: `${htmlImportStart}${cleanedContent.fullContent}`,
|
|
273
|
+
clientContent: cleanedContent.clientContent,
|
|
274
|
+
configFiles: isAConfigFile(args?.path) ? null : getConfigFiles(args.path, pageConfigFiles)
|
|
275
|
+
});
|
|
276
|
+
return {
|
|
277
|
+
contents: newContent,
|
|
278
|
+
loader: "tsx"
|
|
279
|
+
};
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/build/esbuild/addDotJS.ts
|
|
286
|
+
import fs3 from "fs-extra";
|
|
287
|
+
import path4 from "path";
|
|
288
|
+
import builtinModules from "builtin-modules";
|
|
289
|
+
function addDotJS(allPackages2, extensions2, isDev) {
|
|
290
|
+
const allPackagesIncludingNode = allPackages2.concat(builtinModules);
|
|
291
|
+
return {
|
|
292
|
+
name: "add-dot-js",
|
|
293
|
+
setup(build2) {
|
|
294
|
+
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
295
|
+
const hasAtSign = args.path.startsWith("@");
|
|
296
|
+
const isPackage = hasAtSign ? allPackagesIncludingNode.includes(args.path) : allPackagesIncludingNode.includes(args.path.split("/").shift());
|
|
297
|
+
if (args.importer && !isPackage) {
|
|
298
|
+
const calculatedDir = path4.join(args.resolveDir, args.path);
|
|
299
|
+
let existsAsFile = false;
|
|
300
|
+
for (const extension of extensions2) {
|
|
301
|
+
const asFile = calculatedDir + extension;
|
|
302
|
+
const exists = fs3.existsSync(asFile);
|
|
303
|
+
if (exists) existsAsFile = true;
|
|
304
|
+
}
|
|
305
|
+
let outputPath = args.path + (existsAsFile ? "" : "/index") + ".js";
|
|
306
|
+
outputPath = args.path.endsWith(".js") || args.path.endsWith(".mjs") ? args.path : outputPath;
|
|
307
|
+
return { path: outputPath + (isDev ? `?cache=${Date.now()}` : ""), external: true };
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// src/build/esbuild/getDataFiles.ts
|
|
315
|
+
import fs4 from "fs-extra";
|
|
316
|
+
function getDataFiles(dataFiles) {
|
|
317
|
+
return {
|
|
318
|
+
name: "get-data-files",
|
|
319
|
+
setup(build2) {
|
|
320
|
+
build2.onLoad({ filter: /\.data\.(js|mjs|ts)$/ }, (args) => {
|
|
321
|
+
const contents = fs4.readFileSync(args.path, "utf-8");
|
|
322
|
+
dataFiles.push({
|
|
323
|
+
...args,
|
|
324
|
+
contents
|
|
325
|
+
});
|
|
326
|
+
return {
|
|
327
|
+
contents,
|
|
328
|
+
loader: "ts"
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// src/util/constants.ts
|
|
336
|
+
var doctypeHTML = "<!DOCTYPE html>";
|
|
337
|
+
var staticComment = "<!-- static -->";
|
|
338
|
+
|
|
214
339
|
// src/scripts/build.ts
|
|
215
340
|
var extensions = [".ts", ".tsx"];
|
|
216
|
-
var packageJson = JSON.parse(
|
|
341
|
+
var packageJson = JSON.parse(fs5.readFileSync(config.packageJsonPath, "utf-8"));
|
|
217
342
|
var allPackages = Object.keys(packageJson.devDependencies).concat(Object.keys(packageJson.dependencies));
|
|
218
|
-
var allPackagesIncludingNode = allPackages.concat(builtinModules);
|
|
219
343
|
var xpineDistDir = getXPineDistDir();
|
|
220
|
-
async function buildApp(isDev = false) {
|
|
344
|
+
async function buildApp(isDev = false, removePreviousBuild = false) {
|
|
221
345
|
try {
|
|
346
|
+
if (removePreviousBuild) fs5.removeSync(config.distDir);
|
|
222
347
|
const srcDirFiles = globSync(config.srcDir + "/**/*.{js,ts,tsx,jsx}");
|
|
223
348
|
const { componentData, dataFiles } = await buildAppFiles(srcDirFiles, isDev);
|
|
224
349
|
const alpineDataFile = await buildAlpineDataFile(componentData, dataFiles);
|
|
225
350
|
await buildClientSideFiles([alpineDataFile], isDev);
|
|
226
|
-
|
|
351
|
+
fs5.removeSync(config.distTempFolder);
|
|
227
352
|
await buildCSS();
|
|
228
353
|
await buildPublicFolderSymlinks();
|
|
354
|
+
if (!isDev) await buildFilesWithConfigs(componentData);
|
|
229
355
|
} catch (err) {
|
|
230
356
|
console.error("Build failed");
|
|
231
357
|
console.error(err);
|
|
@@ -234,8 +360,12 @@ async function buildApp(isDev = false) {
|
|
|
234
360
|
async function buildAppFiles(files, isDev) {
|
|
235
361
|
const componentData = [];
|
|
236
362
|
const dataFiles = [];
|
|
363
|
+
const pageConfigFiles = files.filter((file) => {
|
|
364
|
+
const fileName = file.split("/").at(-1).split(".").shift();
|
|
365
|
+
return fileName === "+config";
|
|
366
|
+
});
|
|
237
367
|
const backendFiles = files.filter((file) => extensions.find((ext) => file.endsWith(ext))).filter((file) => !file.startsWith(config.publicDir));
|
|
238
|
-
|
|
368
|
+
fs5.ensureDirSync(config.distDir);
|
|
239
369
|
await build({
|
|
240
370
|
entryPoints: backendFiles,
|
|
241
371
|
format: "esm",
|
|
@@ -247,69 +377,9 @@ async function buildAppFiles(files, isDev) {
|
|
|
247
377
|
jsx: "transform",
|
|
248
378
|
minify: !isDev,
|
|
249
379
|
plugins: [
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
build2.onResolve({ filter: /.*/ }, (args) => {
|
|
254
|
-
const hasAtSign = args.path.startsWith("@");
|
|
255
|
-
const isPackage = hasAtSign ? allPackagesIncludingNode.includes(args.path) : allPackagesIncludingNode.includes(args.path.split("/").shift());
|
|
256
|
-
if (args.importer && !isPackage) {
|
|
257
|
-
const calculatedDir = path3.join(args.resolveDir, args.path);
|
|
258
|
-
let existsAsFile = false;
|
|
259
|
-
for (const extension of extensions) {
|
|
260
|
-
const asFile = calculatedDir + extension;
|
|
261
|
-
const exists = fs2.existsSync(asFile);
|
|
262
|
-
if (exists) existsAsFile = true;
|
|
263
|
-
}
|
|
264
|
-
let outputPath = args.path + (existsAsFile ? "" : "/index") + ".js";
|
|
265
|
-
outputPath = args.path.endsWith(".js") || args.path.endsWith(".mjs") ? args.path : outputPath;
|
|
266
|
-
return { path: outputPath + (isDev ? `?cache=${Date.now()}` : ""), external: true };
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
name: "insert-html-banner-and-remove-client-scripts",
|
|
273
|
-
setup(build2) {
|
|
274
|
-
build2.onLoad({ filter: /.tsx/ }, (args) => {
|
|
275
|
-
const content = fs2.readFileSync(args.path, "utf-8");
|
|
276
|
-
const source = ts2.createSourceFile(
|
|
277
|
-
args.path,
|
|
278
|
-
content,
|
|
279
|
-
ts2.ScriptTarget.Latest
|
|
280
|
-
);
|
|
281
|
-
const cleanedContent = removeClientScriptInTSXFile(args.path, source);
|
|
282
|
-
createStaticFile(args.path, source);
|
|
283
|
-
const htmlImportStart = "import { html } from 'xpine';\n";
|
|
284
|
-
const newContent = `${htmlImportStart}${cleanedContent.content}`;
|
|
285
|
-
componentData.push({
|
|
286
|
-
...args,
|
|
287
|
-
contents: `${htmlImportStart}${cleanedContent.fullContent}`,
|
|
288
|
-
clientContent: cleanedContent.clientContent
|
|
289
|
-
});
|
|
290
|
-
return {
|
|
291
|
-
contents: newContent,
|
|
292
|
-
loader: "tsx"
|
|
293
|
-
};
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
name: "get-data-files",
|
|
299
|
-
setup(build2) {
|
|
300
|
-
build2.onLoad({ filter: /\.data\.(js|mjs|ts)$/ }, (args) => {
|
|
301
|
-
const contents = fs2.readFileSync(args.path, "utf-8");
|
|
302
|
-
dataFiles.push({
|
|
303
|
-
...args,
|
|
304
|
-
contents
|
|
305
|
-
});
|
|
306
|
-
return {
|
|
307
|
-
contents,
|
|
308
|
-
loader: "ts"
|
|
309
|
-
};
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
}
|
|
380
|
+
addDotJS(allPackages, extensions, isDev),
|
|
381
|
+
transformTSXFiles(componentData, pageConfigFiles),
|
|
382
|
+
getDataFiles(dataFiles)
|
|
313
383
|
]
|
|
314
384
|
});
|
|
315
385
|
await logSize(config.distDir, "app");
|
|
@@ -319,8 +389,8 @@ async function buildAppFiles(files, isDev) {
|
|
|
319
389
|
};
|
|
320
390
|
}
|
|
321
391
|
async function buildClientSideFiles(alpineDataFiles = [], isDev) {
|
|
322
|
-
const tempFilePath =
|
|
323
|
-
|
|
392
|
+
const tempFilePath = path5.join(config.distTempFolder, "./app.ts");
|
|
393
|
+
fs5.ensureFileSync(tempFilePath);
|
|
324
394
|
const pagesScriptsGlob = config.publicDir + "/scripts/pages/**/*.{js,ts}";
|
|
325
395
|
const clientFiles = globSync(
|
|
326
396
|
config.publicDir + "/**/*.{js,ts}",
|
|
@@ -349,16 +419,14 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev) {
|
|
|
349
419
|
await logSize(config.distPublicDir, "client");
|
|
350
420
|
}
|
|
351
421
|
function writeDevServerClientSideCode(tempFilePath) {
|
|
352
|
-
const devServerPath =
|
|
353
|
-
const content =
|
|
354
|
-
|
|
355
|
-
` + content);
|
|
422
|
+
const devServerPath = path5.join(xpineDistDir, "./src/static/dev-server.js");
|
|
423
|
+
const content = fs5.readFileSync(devServerPath, "utf-8");
|
|
424
|
+
fs5.appendFileSync(tempFilePath, "\n" + content);
|
|
356
425
|
}
|
|
357
426
|
function writeSpaClientSideCode(tempFilePath) {
|
|
358
|
-
const spaPath =
|
|
359
|
-
const content =
|
|
360
|
-
|
|
361
|
-
` + content);
|
|
427
|
+
const spaPath = path5.join(xpineDistDir, "./src/static/spa.js");
|
|
428
|
+
const content = fs5.readFileSync(spaPath, "utf-8");
|
|
429
|
+
fs5.appendFileSync(tempFilePath, "\n" + content);
|
|
362
430
|
}
|
|
363
431
|
async function buildAlpineDataFile(componentData, dataFiles) {
|
|
364
432
|
const output = {
|
|
@@ -377,10 +445,10 @@ async function buildAlpineDataFile(componentData, dataFiles) {
|
|
|
377
445
|
};
|
|
378
446
|
const componentsAndDataFiles = componentData.concat(dataFiles);
|
|
379
447
|
for (const component of componentsAndDataFiles) {
|
|
380
|
-
const sourceFile =
|
|
448
|
+
const sourceFile = ts3.createSourceFile(
|
|
381
449
|
component.path,
|
|
382
450
|
component.contents,
|
|
383
|
-
|
|
451
|
+
ts3.ScriptTarget.Latest
|
|
384
452
|
);
|
|
385
453
|
const dataFunctionResult = findDataAttributesAndFunctions(sourceFile, sourceFile);
|
|
386
454
|
dataFunctionResults.foundDataAttributes.push(...dataFunctionResult.foundDataAttributes);
|
|
@@ -402,18 +470,18 @@ async function buildAlpineDataFile(componentData, dataFiles) {
|
|
|
402
470
|
output.code.push(`Alpine.data('${dataFunction.name}', ${dataFunction.name});`);
|
|
403
471
|
}
|
|
404
472
|
const result = output.imports.join("\n") + "\n" + output.code.join("\n") + "\n" + output.end.join("\n");
|
|
405
|
-
|
|
406
|
-
|
|
473
|
+
fs5.ensureFileSync(config.alpineDataPath);
|
|
474
|
+
fs5.writeFileSync(config.alpineDataPath, result);
|
|
407
475
|
return config.alpineDataPath;
|
|
408
476
|
}
|
|
409
477
|
async function buildCSS() {
|
|
410
478
|
const cssFiles = globSync(config.srcDir + "/**/*.css");
|
|
411
479
|
for (const file of cssFiles) {
|
|
412
|
-
const fileContents =
|
|
480
|
+
const fileContents = fs5.readFileSync(file, "utf-8");
|
|
413
481
|
const result = await postcss([tailwindPostcss(), remove_layers_default()]).process(fileContents, { from: file });
|
|
414
482
|
const newPath = file.replace(config.srcDir, config.distDir);
|
|
415
|
-
|
|
416
|
-
|
|
483
|
+
fs5.ensureFileSync(newPath);
|
|
484
|
+
fs5.writeFileSync(newPath, result.css);
|
|
417
485
|
}
|
|
418
486
|
logSize(config.distPublicDir, "css");
|
|
419
487
|
}
|
|
@@ -427,8 +495,8 @@ async function buildPublicFolderSymlinks() {
|
|
|
427
495
|
const splitNewPath = newPath.split("/");
|
|
428
496
|
splitNewPath.pop();
|
|
429
497
|
const newDir = splitNewPath.join("/");
|
|
430
|
-
|
|
431
|
-
|
|
498
|
+
fs5.ensureDirSync(newDir);
|
|
499
|
+
fs5.symlinkSync(file, newPath);
|
|
432
500
|
} catch {
|
|
433
501
|
}
|
|
434
502
|
}
|
|
@@ -439,7 +507,7 @@ async function logSize(pathName, type, validExtensions = [".js", ".css"]) {
|
|
|
439
507
|
if (!validExtensions.find((ext) => file.endsWith(ext))) return false;
|
|
440
508
|
return {
|
|
441
509
|
file,
|
|
442
|
-
size:
|
|
510
|
+
size: fs5.statSync(file).size / (1024 * 1e3)
|
|
443
511
|
};
|
|
444
512
|
}).filter(Boolean);
|
|
445
513
|
const totalSize = fileSizes.reduce((total, current) => {
|
|
@@ -447,6 +515,83 @@ async function logSize(pathName, type, validExtensions = [".js", ".css"]) {
|
|
|
447
515
|
}, 0);
|
|
448
516
|
console.info(`[${totalSize.toFixed(3)} MB] Built ${type}`);
|
|
449
517
|
}
|
|
518
|
+
async function buildFilesWithConfigs(componentData) {
|
|
519
|
+
const now = Date.now();
|
|
520
|
+
const componentsWithConfigs = componentData.filter((item) => item.configFiles);
|
|
521
|
+
for (const component of componentsWithConfigs) {
|
|
522
|
+
let config2 = await getCompleteConfig(component.configFiles, now);
|
|
523
|
+
const builtComponentPath = sourcePathToDistPath(component.path);
|
|
524
|
+
const componentImport = await import(builtComponentPath + `?cache=${Date.now()}`);
|
|
525
|
+
if (componentImport?.config) {
|
|
526
|
+
config2 = {
|
|
527
|
+
...config2,
|
|
528
|
+
...componentImport.config
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
if (config2?.staticPaths) buildStaticFiles(config2, component, componentImport, builtComponentPath);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
async function buildStaticFiles(config2, component, componentImport, builtComponentPath) {
|
|
535
|
+
if (!config2?.staticPaths) return;
|
|
536
|
+
let componentFileName = component.path.split("/").pop().replace(regex_default.endsWithJSX, "").replace(regex_default.endsWithTSX, "");
|
|
537
|
+
const isDynamicRoute = component.path.match(regex_default.isDynamicRoute);
|
|
538
|
+
if (isDynamicRoute) {
|
|
539
|
+
componentFileName = component.path.split("/").filter((dir) => dir.match(regex_default.isDynamicRoute)).join("/").replace(regex_default.endsWithJSX, "").replace(regex_default.endsWithTSX, "");
|
|
540
|
+
}
|
|
541
|
+
const componentDynamicPaths = getComponentDynamicPaths(componentFileName);
|
|
542
|
+
const componentFn = componentImport.default;
|
|
543
|
+
const outputPath = componentDynamicPaths?.length ? componentDynamicPaths.reduce((total, current) => {
|
|
544
|
+
return total.replace(`/[${current}]`, "");
|
|
545
|
+
}, path5.dirname(builtComponentPath)) : path5.dirname(builtComponentPath);
|
|
546
|
+
if (typeof config2?.staticPaths === "boolean") {
|
|
547
|
+
try {
|
|
548
|
+
const req = { params: {} };
|
|
549
|
+
const data = config2?.data ? await config2.data(req) : null;
|
|
550
|
+
const staticComponentOutput = await componentFn({ data });
|
|
551
|
+
fs5.writeFileSync(
|
|
552
|
+
path5.join(outputPath, "./index.html"),
|
|
553
|
+
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
|
|
554
|
+
);
|
|
555
|
+
} catch (err) {
|
|
556
|
+
console.error(err);
|
|
557
|
+
console.log("Could not build static component", component.path);
|
|
558
|
+
}
|
|
559
|
+
} else if (typeof config2?.staticPaths === "function") {
|
|
560
|
+
const dynamicPaths = await config2.staticPaths();
|
|
561
|
+
for (const dynamicPath of dynamicPaths) {
|
|
562
|
+
try {
|
|
563
|
+
const req = {
|
|
564
|
+
params: {
|
|
565
|
+
...componentDynamicPaths?.length ? dynamicPath : {}
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
const data = config2?.data ? await config2.data(req) : null;
|
|
569
|
+
const staticComponentOutput = await componentFn({ req, data });
|
|
570
|
+
const updatedOutDir = path5.join(outputPath, `./${componentDynamicPaths.map((key) => dynamicPath[key]).join("/")}`);
|
|
571
|
+
fs5.ensureDirSync(updatedOutDir);
|
|
572
|
+
fs5.writeFileSync(
|
|
573
|
+
path5.join(updatedOutDir, "./index.html"),
|
|
574
|
+
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
|
|
575
|
+
);
|
|
576
|
+
} catch (err) {
|
|
577
|
+
console.log("Could not build static component", component.path);
|
|
578
|
+
console.error(err);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
function getComponentDynamicPaths(componentPath) {
|
|
584
|
+
const matches = [...componentPath.matchAll(regex_default.dynamicRoutes)];
|
|
585
|
+
if (!matches?.length) return null;
|
|
586
|
+
const output = [];
|
|
587
|
+
for (const match of matches) {
|
|
588
|
+
output.push(match[2]);
|
|
589
|
+
}
|
|
590
|
+
return output;
|
|
591
|
+
}
|
|
450
592
|
|
|
451
593
|
// src/scripts/xpine-build.ts
|
|
452
|
-
|
|
594
|
+
import yargs from "yargs";
|
|
595
|
+
import { hideBin } from "yargs/helpers";
|
|
596
|
+
var argv = yargs(hideBin(process.argv)).argv;
|
|
597
|
+
buildApp(argv?.isDev || false, argv?.removePreviousBuild || false);
|