xpine 0.0.47 → 0.0.49
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 +27 -1
- package/dist/index.js +51 -13
- package/dist/src/build/typescript-builder.d.ts +6 -3
- package/dist/src/build/typescript-builder.d.ts.map +1 -1
- package/dist/src/scripts/build.d.ts +1 -1
- package/dist/src/scripts/build.d.ts.map +1 -1
- package/dist/src/scripts/xpine-build.js +51 -13
- package/dist/src/scripts/xpine-dev.js +51 -13
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -426,4 +426,30 @@ setupEnv also supports AWS secrets manager. Simply add SECRETS_NAME=your_aws_sec
|
|
|
426
426
|
|
|
427
427
|
1. Add script to src/public/scripts/pages/your_script.ts
|
|
428
428
|
2. Import script into page HTML (e.g. `<script src="/scripts/pages/your_script.ts">`)
|
|
429
|
-
3. To unload event listeners, use `window.addEventListener('spa-update-page-url', () => { remove event listeners here})` in the code
|
|
429
|
+
3. To unload event listeners, use `window.addEventListener('spa-update-page-url', () => { remove event listeners here})` in the code
|
|
430
|
+
|
|
431
|
+
### Separate client side bundles
|
|
432
|
+
|
|
433
|
+
You can create separate client side bundles in xpine.config.mjs like this:
|
|
434
|
+
|
|
435
|
+
```
|
|
436
|
+
export default {
|
|
437
|
+
bundles: [
|
|
438
|
+
{
|
|
439
|
+
id: 'site',
|
|
440
|
+
excludePaths: [
|
|
441
|
+
// Excludes SecretPageData
|
|
442
|
+
'/**/pages/secret/**/*.{js,ts,tsx,jsx}',
|
|
443
|
+
'/**/pages/secret/*.{js,ts,tsx,jsx}',
|
|
444
|
+
],
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
id: 'secret-page',
|
|
448
|
+
includePaths: [
|
|
449
|
+
// Only uses Alpine data coming from paths in this directory
|
|
450
|
+
'/**/pages/secret/**/*.{js,ts,tsx,jsx}',
|
|
451
|
+
]
|
|
452
|
+
}
|
|
453
|
+
]
|
|
454
|
+
}
|
|
455
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import chokidar from "chokidar";
|
|
|
9
9
|
import path6 from "path";
|
|
10
10
|
import fs7 from "fs-extra";
|
|
11
11
|
import { build } from "esbuild";
|
|
12
|
+
import micromatch from "micromatch";
|
|
12
13
|
|
|
13
14
|
// src/build/typescript-builder.ts
|
|
14
15
|
import ts from "typescript";
|
|
@@ -238,7 +239,10 @@ function removeClientScriptInTSXFile(pathName, source) {
|
|
|
238
239
|
clientDataStart
|
|
239
240
|
};
|
|
240
241
|
}
|
|
241
|
-
function
|
|
242
|
+
function pathExistsAsIndex(pathName) {
|
|
243
|
+
return fs.existsSync(path2.join(pathName, "./index.js")) || fs.existsSync(path2.join(pathName, "./index.ts")) || fs.existsSync(path2.join(pathName, "./index.jsx")) || fs.existsSync(path2.join(pathName, "./index.tsx"));
|
|
244
|
+
}
|
|
245
|
+
function getImportsToAbsolutePaths(child, source, pathName, convertPathsToJS = false) {
|
|
242
246
|
const output = [];
|
|
243
247
|
child.forEachChild((child2) => {
|
|
244
248
|
if (child2.kind === ts.SyntaxKind.StringLiteral) {
|
|
@@ -246,15 +250,23 @@ function getImportsToAbsolutePaths(child, source, pathName) {
|
|
|
246
250
|
const importPath = text.replace(/[\"\']/g, "");
|
|
247
251
|
const isRelativeImport = importPath.startsWith(".") || importPath.startsWith("/");
|
|
248
252
|
if (!isRelativeImport) return;
|
|
253
|
+
let result = path2.join(path2.dirname(pathName), importPath);
|
|
254
|
+
if (convertPathsToJS) {
|
|
255
|
+
if (pathExistsAsIndex(result)) {
|
|
256
|
+
result = path2.join(result, "./index.js");
|
|
257
|
+
} else {
|
|
258
|
+
result += ".js";
|
|
259
|
+
}
|
|
260
|
+
}
|
|
249
261
|
output.push({
|
|
250
262
|
old: importPath,
|
|
251
|
-
new:
|
|
263
|
+
new: result
|
|
252
264
|
});
|
|
253
265
|
}
|
|
254
266
|
});
|
|
255
267
|
return output;
|
|
256
268
|
}
|
|
257
|
-
function getXpineOnLoadFunction(pathName, source,
|
|
269
|
+
function getXpineOnLoadFunction(pathName, source, options) {
|
|
258
270
|
const value = {
|
|
259
271
|
imports: "",
|
|
260
272
|
fn: ""
|
|
@@ -262,7 +274,7 @@ function getXpineOnLoadFunction(pathName, source, onLoadFileResult) {
|
|
|
262
274
|
source.forEachChild((child) => {
|
|
263
275
|
if (child.kind == ts.SyntaxKind.ImportDeclaration) {
|
|
264
276
|
let importText = child.getText(source);
|
|
265
|
-
const importOutput = getImportsToAbsolutePaths(child, source, pathName);
|
|
277
|
+
const importOutput = getImportsToAbsolutePaths(child, source, pathName, options?.convertPathsToJS);
|
|
266
278
|
for (const importItem of importOutput) {
|
|
267
279
|
importText = importText.replace(importItem.old, importItem.new);
|
|
268
280
|
}
|
|
@@ -769,8 +781,27 @@ async function buildApp(args) {
|
|
|
769
781
|
if (removePreviousBuild) fs7.removeSync(config.distDir);
|
|
770
782
|
const srcDirFiles = globSync3(config.srcDir + "/**/*.{js,ts,tsx,jsx}");
|
|
771
783
|
const { componentData, dataFiles } = await buildAppFiles(srcDirFiles, isDev2);
|
|
784
|
+
const clientSideBundles = [];
|
|
785
|
+
if (config?.bundles?.length) {
|
|
786
|
+
for (const bundle of config.bundles) {
|
|
787
|
+
const matchingComponentData = componentData?.filter((item) => {
|
|
788
|
+
return !micromatch([item.path], bundle?.excludePaths || [])?.length;
|
|
789
|
+
})?.filter((item) => {
|
|
790
|
+
if (!bundle?.includePaths?.length) return true;
|
|
791
|
+
return micromatch([item.path], bundle?.includePaths || [])?.length;
|
|
792
|
+
});
|
|
793
|
+
const matchingDataFiles = dataFiles?.filter((item) => {
|
|
794
|
+
return !micromatch([item.path], bundle?.excludePaths || [])?.length;
|
|
795
|
+
})?.filter((item) => {
|
|
796
|
+
if (!bundle?.includePaths?.length) return true;
|
|
797
|
+
return micromatch([item.path], bundle?.includePaths || [])?.length;
|
|
798
|
+
});
|
|
799
|
+
const alpineDataFile2 = await buildAlpineDataFile(matchingComponentData, matchingDataFiles, bundle.id);
|
|
800
|
+
await buildClientSideFiles([alpineDataFile2], isDev2, `./${bundle.id}.ts`, bundle.id);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
772
803
|
const alpineDataFile = await buildAlpineDataFile(componentData, dataFiles);
|
|
773
|
-
await buildClientSideFiles([alpineDataFile], isDev2);
|
|
804
|
+
await buildClientSideFiles([alpineDataFile, ...clientSideBundles], isDev2);
|
|
774
805
|
fs7.removeSync(config.distTempFolder);
|
|
775
806
|
await buildCSS(disableTailwind);
|
|
776
807
|
await buildPublicFolderSymlinks();
|
|
@@ -814,8 +845,8 @@ async function buildAppFiles(files, isDev2) {
|
|
|
814
845
|
dataFiles
|
|
815
846
|
};
|
|
816
847
|
}
|
|
817
|
-
async function buildClientSideFiles(alpineDataFiles = [], isDev2) {
|
|
818
|
-
const tempFilePath = path6.join(config.distTempFolder, "./app.ts");
|
|
848
|
+
async function buildClientSideFiles(alpineDataFiles = [], isDev2, tempClientSidePath, id) {
|
|
849
|
+
const tempFilePath = path6.join(config.distTempFolder, tempClientSidePath || "./app.ts");
|
|
819
850
|
fs7.ensureFileSync(tempFilePath);
|
|
820
851
|
const pagesScriptsGlob = config.publicDir + "/scripts/pages/**/*.{js,ts}";
|
|
821
852
|
const clientFiles = globSync3(
|
|
@@ -842,7 +873,7 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev2) {
|
|
|
842
873
|
minify: !isDev2,
|
|
843
874
|
sourcemap: isDev2 ? "inline" : false
|
|
844
875
|
});
|
|
845
|
-
await logSize(config.distPublicDir, "client");
|
|
876
|
+
await logSize(config.distPublicDir, id ? `client bundle: ${id}.js` : "client bundle: app.js");
|
|
846
877
|
}
|
|
847
878
|
function writeDevServerClientSideCode(tempFilePath) {
|
|
848
879
|
const devServerPath = path6.join(xpineDistDir, "./src/static/dev-server.js");
|
|
@@ -854,7 +885,7 @@ function writeSpaClientSideCode(tempFilePath) {
|
|
|
854
885
|
const content = fs7.readFileSync(spaPath, "utf-8");
|
|
855
886
|
fs7.appendFileSync(tempFilePath, "\n" + content);
|
|
856
887
|
}
|
|
857
|
-
async function buildAlpineDataFile(componentData, dataFiles) {
|
|
888
|
+
async function buildAlpineDataFile(componentData, dataFiles, bundleID) {
|
|
858
889
|
const output = {
|
|
859
890
|
imports: [
|
|
860
891
|
"import Alpine from 'alpinejs';"
|
|
@@ -898,9 +929,16 @@ async function buildAlpineDataFile(componentData, dataFiles) {
|
|
|
898
929
|
output.code.push(`Alpine.data('${dataFunction.name}', ${dataFunction.name});`);
|
|
899
930
|
}
|
|
900
931
|
const result = output.imports.join("\n") + "\n" + output.code.join("\n") + "\n" + output.end.join("\n");
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
932
|
+
if (bundleID) {
|
|
933
|
+
const bundlePath = path6.join(config.distTempFolder, `./alpine-data-${bundleID}.ts`);
|
|
934
|
+
fs7.ensureFileSync(bundlePath);
|
|
935
|
+
fs7.writeFileSync(bundlePath, result);
|
|
936
|
+
return bundlePath;
|
|
937
|
+
} else {
|
|
938
|
+
fs7.ensureFileSync(config.alpineDataPath);
|
|
939
|
+
fs7.writeFileSync(config.alpineDataPath, result);
|
|
940
|
+
return config.alpineDataPath;
|
|
941
|
+
}
|
|
904
942
|
}
|
|
905
943
|
async function buildPublicFolderSymlinks() {
|
|
906
944
|
const files = globSync3(config.publicDir + "/**/*.*", {
|
|
@@ -1033,7 +1071,7 @@ async function buildOnLoadFile(componentData, isDev2) {
|
|
|
1033
1071
|
return a.path.localeCompare(b.path);
|
|
1034
1072
|
});
|
|
1035
1073
|
for (const file of onLoadFiles) {
|
|
1036
|
-
const result = getXpineOnLoadFunction(file.path, file.source,
|
|
1074
|
+
const result = getXpineOnLoadFunction(file.path, file.source, { convertPathsToJS: true });
|
|
1037
1075
|
onLoadFileResult.fn += result.fn;
|
|
1038
1076
|
onLoadFileResult.imports += result.imports;
|
|
1039
1077
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import { OnLoadFileResult } from '../scripts/build';
|
|
3
2
|
type ImportDeclaration = {
|
|
4
3
|
node: ts.Node;
|
|
5
4
|
importPath: string;
|
|
@@ -26,9 +25,13 @@ export declare function removeClientScriptInTSXFile(pathName: string, source: ts
|
|
|
26
25
|
clientDataStart: number;
|
|
27
26
|
};
|
|
28
27
|
export declare function createStaticFile(pathName: string, source: ts.SourceFile): void;
|
|
29
|
-
export declare function
|
|
28
|
+
export declare function pathExistsAsIndex(pathName: string): any;
|
|
29
|
+
export declare function getImportsToAbsolutePaths(child: ts.Node, source: ts.SourceFile, pathName: string, convertPathsToJS?: boolean): any[];
|
|
30
30
|
export declare function printRecursiveFrom(node: ts.Node, indentLevel: number, sourceFile: ts.SourceFile): void;
|
|
31
|
-
|
|
31
|
+
type GetXpineOnLoadFunctionOptions = {
|
|
32
|
+
convertPathsToJS?: boolean;
|
|
33
|
+
};
|
|
34
|
+
export declare function getXpineOnLoadFunction(pathName: string, source: ts.SourceFile, options?: GetXpineOnLoadFunctionOptions): {
|
|
32
35
|
imports: string;
|
|
33
36
|
fn: string;
|
|
34
37
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typescript-builder.d.ts","sourceRoot":"","sources":["../../../src/build/typescript-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"typescript-builder.d.ts","sourceRoot":"","sources":["../../../src/build/typescript-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAO5B,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAA;AAGD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,EAAE,kBAAkB,GAAE,iBAAiB,EAAO,uBAiB/H;AAED,wBAAgB,yBAAyB,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,UAO3H;AAED,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAA;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,mBAAmB,GAAE,MAAM,EAAO,EAClC,cAAc,GAAE,mBAAmB,EAAO;;;EA0B3C;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,EAAE,CAMxF;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,mBAAmB,CAkBzG;AAGD,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,MAAM,QAO1F;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,UAAU;;;;;;EAmClF;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,UAAU,QAUvE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,OAKjD;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,GAAE,OAAe,SAwBnI;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,QAU9D;AAED,KAAK,6BAA6B,GAAG;IACnC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAA;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,EAAE,CAAC,UAAU,EACrB,OAAO,CAAC,EAAE,6BAA6B;;;EA2BxC;AAED,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,OAAe,iBAMhE"}
|
|
@@ -6,7 +6,7 @@ type BuildAppArgs = {
|
|
|
6
6
|
};
|
|
7
7
|
export declare function buildApp(args: BuildAppArgs): Promise<void>;
|
|
8
8
|
export declare function buildPublicFolderSymlinks(): Promise<void>;
|
|
9
|
-
export declare function logSize(pathName: string, type:
|
|
9
|
+
export declare function logSize(pathName: string, type: string, validExtensions?: string[]): Promise<void>;
|
|
10
10
|
export declare function buildFilesWithConfigs(componentData: ComponentData[]): Promise<void>;
|
|
11
11
|
export declare function buildStaticFiles(config: ConfigFile, component: ComponentData, componentImport: any, builtComponentPath: string): Promise<void>;
|
|
12
12
|
export declare function getComponentDynamicPaths(componentPath: string): string[];
|
|
@@ -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":"AAmBA,OAAO,EAAE,UAAU,EAA2B,aAAa,EAAE,MAAM,aAAa,CAAC;AAajF,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAA;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,iBA+ChD;AAwJD,wBAAsB,yBAAyB,kBAgB9C;AAED,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,WAAkB,iBAa9F;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,iBAyEpI;AAED,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAQxE;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAA;AAGD,wBAAsB,eAAe,CAAC,aAAa,EAAE,aAAa,EAAE,EAAE,KAAK,CAAC,EAAE,OAAO,iBAoDpF"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import path5 from "path";
|
|
5
5
|
import fs7 from "fs-extra";
|
|
6
6
|
import { build } from "esbuild";
|
|
7
|
+
import micromatch from "micromatch";
|
|
7
8
|
|
|
8
9
|
// src/build/typescript-builder.ts
|
|
9
10
|
import ts from "typescript";
|
|
@@ -233,7 +234,10 @@ function removeClientScriptInTSXFile(pathName, source) {
|
|
|
233
234
|
clientDataStart
|
|
234
235
|
};
|
|
235
236
|
}
|
|
236
|
-
function
|
|
237
|
+
function pathExistsAsIndex(pathName) {
|
|
238
|
+
return fs.existsSync(path2.join(pathName, "./index.js")) || fs.existsSync(path2.join(pathName, "./index.ts")) || fs.existsSync(path2.join(pathName, "./index.jsx")) || fs.existsSync(path2.join(pathName, "./index.tsx"));
|
|
239
|
+
}
|
|
240
|
+
function getImportsToAbsolutePaths(child, source, pathName, convertPathsToJS = false) {
|
|
237
241
|
const output = [];
|
|
238
242
|
child.forEachChild((child2) => {
|
|
239
243
|
if (child2.kind === ts.SyntaxKind.StringLiteral) {
|
|
@@ -241,15 +245,23 @@ function getImportsToAbsolutePaths(child, source, pathName) {
|
|
|
241
245
|
const importPath = text.replace(/[\"\']/g, "");
|
|
242
246
|
const isRelativeImport = importPath.startsWith(".") || importPath.startsWith("/");
|
|
243
247
|
if (!isRelativeImport) return;
|
|
248
|
+
let result = path2.join(path2.dirname(pathName), importPath);
|
|
249
|
+
if (convertPathsToJS) {
|
|
250
|
+
if (pathExistsAsIndex(result)) {
|
|
251
|
+
result = path2.join(result, "./index.js");
|
|
252
|
+
} else {
|
|
253
|
+
result += ".js";
|
|
254
|
+
}
|
|
255
|
+
}
|
|
244
256
|
output.push({
|
|
245
257
|
old: importPath,
|
|
246
|
-
new:
|
|
258
|
+
new: result
|
|
247
259
|
});
|
|
248
260
|
}
|
|
249
261
|
});
|
|
250
262
|
return output;
|
|
251
263
|
}
|
|
252
|
-
function getXpineOnLoadFunction(pathName, source,
|
|
264
|
+
function getXpineOnLoadFunction(pathName, source, options) {
|
|
253
265
|
const value = {
|
|
254
266
|
imports: "",
|
|
255
267
|
fn: ""
|
|
@@ -257,7 +269,7 @@ function getXpineOnLoadFunction(pathName, source, onLoadFileResult) {
|
|
|
257
269
|
source.forEachChild((child) => {
|
|
258
270
|
if (child.kind == ts.SyntaxKind.ImportDeclaration) {
|
|
259
271
|
let importText = child.getText(source);
|
|
260
|
-
const importOutput = getImportsToAbsolutePaths(child, source, pathName);
|
|
272
|
+
const importOutput = getImportsToAbsolutePaths(child, source, pathName, options?.convertPathsToJS);
|
|
261
273
|
for (const importItem of importOutput) {
|
|
262
274
|
importText = importText.replace(importItem.old, importItem.new);
|
|
263
275
|
}
|
|
@@ -562,8 +574,27 @@ async function buildApp(args) {
|
|
|
562
574
|
if (removePreviousBuild2) fs7.removeSync(config.distDir);
|
|
563
575
|
const srcDirFiles = globSync3(config.srcDir + "/**/*.{js,ts,tsx,jsx}");
|
|
564
576
|
const { componentData, dataFiles } = await buildAppFiles(srcDirFiles, isDev3);
|
|
577
|
+
const clientSideBundles = [];
|
|
578
|
+
if (config?.bundles?.length) {
|
|
579
|
+
for (const bundle of config.bundles) {
|
|
580
|
+
const matchingComponentData = componentData?.filter((item) => {
|
|
581
|
+
return !micromatch([item.path], bundle?.excludePaths || [])?.length;
|
|
582
|
+
})?.filter((item) => {
|
|
583
|
+
if (!bundle?.includePaths?.length) return true;
|
|
584
|
+
return micromatch([item.path], bundle?.includePaths || [])?.length;
|
|
585
|
+
});
|
|
586
|
+
const matchingDataFiles = dataFiles?.filter((item) => {
|
|
587
|
+
return !micromatch([item.path], bundle?.excludePaths || [])?.length;
|
|
588
|
+
})?.filter((item) => {
|
|
589
|
+
if (!bundle?.includePaths?.length) return true;
|
|
590
|
+
return micromatch([item.path], bundle?.includePaths || [])?.length;
|
|
591
|
+
});
|
|
592
|
+
const alpineDataFile2 = await buildAlpineDataFile(matchingComponentData, matchingDataFiles, bundle.id);
|
|
593
|
+
await buildClientSideFiles([alpineDataFile2], isDev3, `./${bundle.id}.ts`, bundle.id);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
565
596
|
const alpineDataFile = await buildAlpineDataFile(componentData, dataFiles);
|
|
566
|
-
await buildClientSideFiles([alpineDataFile], isDev3);
|
|
597
|
+
await buildClientSideFiles([alpineDataFile, ...clientSideBundles], isDev3);
|
|
567
598
|
fs7.removeSync(config.distTempFolder);
|
|
568
599
|
await buildCSS(disableTailwind2);
|
|
569
600
|
await buildPublicFolderSymlinks();
|
|
@@ -607,8 +638,8 @@ async function buildAppFiles(files, isDev3) {
|
|
|
607
638
|
dataFiles
|
|
608
639
|
};
|
|
609
640
|
}
|
|
610
|
-
async function buildClientSideFiles(alpineDataFiles = [], isDev3) {
|
|
611
|
-
const tempFilePath = path5.join(config.distTempFolder, "./app.ts");
|
|
641
|
+
async function buildClientSideFiles(alpineDataFiles = [], isDev3, tempClientSidePath, id) {
|
|
642
|
+
const tempFilePath = path5.join(config.distTempFolder, tempClientSidePath || "./app.ts");
|
|
612
643
|
fs7.ensureFileSync(tempFilePath);
|
|
613
644
|
const pagesScriptsGlob = config.publicDir + "/scripts/pages/**/*.{js,ts}";
|
|
614
645
|
const clientFiles = globSync3(
|
|
@@ -635,7 +666,7 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev3) {
|
|
|
635
666
|
minify: !isDev3,
|
|
636
667
|
sourcemap: isDev3 ? "inline" : false
|
|
637
668
|
});
|
|
638
|
-
await logSize(config.distPublicDir, "client");
|
|
669
|
+
await logSize(config.distPublicDir, id ? `client bundle: ${id}.js` : "client bundle: app.js");
|
|
639
670
|
}
|
|
640
671
|
function writeDevServerClientSideCode(tempFilePath) {
|
|
641
672
|
const devServerPath = path5.join(xpineDistDir, "./src/static/dev-server.js");
|
|
@@ -647,7 +678,7 @@ function writeSpaClientSideCode(tempFilePath) {
|
|
|
647
678
|
const content = fs7.readFileSync(spaPath, "utf-8");
|
|
648
679
|
fs7.appendFileSync(tempFilePath, "\n" + content);
|
|
649
680
|
}
|
|
650
|
-
async function buildAlpineDataFile(componentData, dataFiles) {
|
|
681
|
+
async function buildAlpineDataFile(componentData, dataFiles, bundleID) {
|
|
651
682
|
const output = {
|
|
652
683
|
imports: [
|
|
653
684
|
"import Alpine from 'alpinejs';"
|
|
@@ -691,9 +722,16 @@ async function buildAlpineDataFile(componentData, dataFiles) {
|
|
|
691
722
|
output.code.push(`Alpine.data('${dataFunction.name}', ${dataFunction.name});`);
|
|
692
723
|
}
|
|
693
724
|
const result = output.imports.join("\n") + "\n" + output.code.join("\n") + "\n" + output.end.join("\n");
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
725
|
+
if (bundleID) {
|
|
726
|
+
const bundlePath = path5.join(config.distTempFolder, `./alpine-data-${bundleID}.ts`);
|
|
727
|
+
fs7.ensureFileSync(bundlePath);
|
|
728
|
+
fs7.writeFileSync(bundlePath, result);
|
|
729
|
+
return bundlePath;
|
|
730
|
+
} else {
|
|
731
|
+
fs7.ensureFileSync(config.alpineDataPath);
|
|
732
|
+
fs7.writeFileSync(config.alpineDataPath, result);
|
|
733
|
+
return config.alpineDataPath;
|
|
734
|
+
}
|
|
697
735
|
}
|
|
698
736
|
async function buildPublicFolderSymlinks() {
|
|
699
737
|
const files = globSync3(config.publicDir + "/**/*.*", {
|
|
@@ -826,7 +864,7 @@ async function buildOnLoadFile(componentData, isDev3) {
|
|
|
826
864
|
return a.path.localeCompare(b.path);
|
|
827
865
|
});
|
|
828
866
|
for (const file of onLoadFiles) {
|
|
829
|
-
const result = getXpineOnLoadFunction(file.path, file.source,
|
|
867
|
+
const result = getXpineOnLoadFunction(file.path, file.source, { convertPathsToJS: true });
|
|
830
868
|
onLoadFileResult.fn += result.fn;
|
|
831
869
|
onLoadFileResult.imports += result.imports;
|
|
832
870
|
}
|
|
@@ -11,6 +11,7 @@ import chokidar from "chokidar";
|
|
|
11
11
|
import path5 from "path";
|
|
12
12
|
import fs7 from "fs-extra";
|
|
13
13
|
import { build } from "esbuild";
|
|
14
|
+
import micromatch from "micromatch";
|
|
14
15
|
|
|
15
16
|
// src/build/typescript-builder.ts
|
|
16
17
|
import ts from "typescript";
|
|
@@ -240,7 +241,10 @@ function removeClientScriptInTSXFile(pathName, source) {
|
|
|
240
241
|
clientDataStart
|
|
241
242
|
};
|
|
242
243
|
}
|
|
243
|
-
function
|
|
244
|
+
function pathExistsAsIndex(pathName) {
|
|
245
|
+
return fs.existsSync(path2.join(pathName, "./index.js")) || fs.existsSync(path2.join(pathName, "./index.ts")) || fs.existsSync(path2.join(pathName, "./index.jsx")) || fs.existsSync(path2.join(pathName, "./index.tsx"));
|
|
246
|
+
}
|
|
247
|
+
function getImportsToAbsolutePaths(child, source, pathName, convertPathsToJS = false) {
|
|
244
248
|
const output = [];
|
|
245
249
|
child.forEachChild((child2) => {
|
|
246
250
|
if (child2.kind === ts.SyntaxKind.StringLiteral) {
|
|
@@ -248,15 +252,23 @@ function getImportsToAbsolutePaths(child, source, pathName) {
|
|
|
248
252
|
const importPath = text.replace(/[\"\']/g, "");
|
|
249
253
|
const isRelativeImport = importPath.startsWith(".") || importPath.startsWith("/");
|
|
250
254
|
if (!isRelativeImport) return;
|
|
255
|
+
let result = path2.join(path2.dirname(pathName), importPath);
|
|
256
|
+
if (convertPathsToJS) {
|
|
257
|
+
if (pathExistsAsIndex(result)) {
|
|
258
|
+
result = path2.join(result, "./index.js");
|
|
259
|
+
} else {
|
|
260
|
+
result += ".js";
|
|
261
|
+
}
|
|
262
|
+
}
|
|
251
263
|
output.push({
|
|
252
264
|
old: importPath,
|
|
253
|
-
new:
|
|
265
|
+
new: result
|
|
254
266
|
});
|
|
255
267
|
}
|
|
256
268
|
});
|
|
257
269
|
return output;
|
|
258
270
|
}
|
|
259
|
-
function getXpineOnLoadFunction(pathName, source,
|
|
271
|
+
function getXpineOnLoadFunction(pathName, source, options) {
|
|
260
272
|
const value = {
|
|
261
273
|
imports: "",
|
|
262
274
|
fn: ""
|
|
@@ -264,7 +276,7 @@ function getXpineOnLoadFunction(pathName, source, onLoadFileResult) {
|
|
|
264
276
|
source.forEachChild((child) => {
|
|
265
277
|
if (child.kind == ts.SyntaxKind.ImportDeclaration) {
|
|
266
278
|
let importText = child.getText(source);
|
|
267
|
-
const importOutput = getImportsToAbsolutePaths(child, source, pathName);
|
|
279
|
+
const importOutput = getImportsToAbsolutePaths(child, source, pathName, options?.convertPathsToJS);
|
|
268
280
|
for (const importItem of importOutput) {
|
|
269
281
|
importText = importText.replace(importItem.old, importItem.new);
|
|
270
282
|
}
|
|
@@ -569,8 +581,27 @@ async function buildApp(args) {
|
|
|
569
581
|
if (removePreviousBuild) fs7.removeSync(config.distDir);
|
|
570
582
|
const srcDirFiles = globSync3(config.srcDir + "/**/*.{js,ts,tsx,jsx}");
|
|
571
583
|
const { componentData, dataFiles } = await buildAppFiles(srcDirFiles, isDev2);
|
|
584
|
+
const clientSideBundles = [];
|
|
585
|
+
if (config?.bundles?.length) {
|
|
586
|
+
for (const bundle of config.bundles) {
|
|
587
|
+
const matchingComponentData = componentData?.filter((item) => {
|
|
588
|
+
return !micromatch([item.path], bundle?.excludePaths || [])?.length;
|
|
589
|
+
})?.filter((item) => {
|
|
590
|
+
if (!bundle?.includePaths?.length) return true;
|
|
591
|
+
return micromatch([item.path], bundle?.includePaths || [])?.length;
|
|
592
|
+
});
|
|
593
|
+
const matchingDataFiles = dataFiles?.filter((item) => {
|
|
594
|
+
return !micromatch([item.path], bundle?.excludePaths || [])?.length;
|
|
595
|
+
})?.filter((item) => {
|
|
596
|
+
if (!bundle?.includePaths?.length) return true;
|
|
597
|
+
return micromatch([item.path], bundle?.includePaths || [])?.length;
|
|
598
|
+
});
|
|
599
|
+
const alpineDataFile2 = await buildAlpineDataFile(matchingComponentData, matchingDataFiles, bundle.id);
|
|
600
|
+
await buildClientSideFiles([alpineDataFile2], isDev2, `./${bundle.id}.ts`, bundle.id);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
572
603
|
const alpineDataFile = await buildAlpineDataFile(componentData, dataFiles);
|
|
573
|
-
await buildClientSideFiles([alpineDataFile], isDev2);
|
|
604
|
+
await buildClientSideFiles([alpineDataFile, ...clientSideBundles], isDev2);
|
|
574
605
|
fs7.removeSync(config.distTempFolder);
|
|
575
606
|
await buildCSS(disableTailwind);
|
|
576
607
|
await buildPublicFolderSymlinks();
|
|
@@ -614,8 +645,8 @@ async function buildAppFiles(files, isDev2) {
|
|
|
614
645
|
dataFiles
|
|
615
646
|
};
|
|
616
647
|
}
|
|
617
|
-
async function buildClientSideFiles(alpineDataFiles = [], isDev2) {
|
|
618
|
-
const tempFilePath = path5.join(config.distTempFolder, "./app.ts");
|
|
648
|
+
async function buildClientSideFiles(alpineDataFiles = [], isDev2, tempClientSidePath, id) {
|
|
649
|
+
const tempFilePath = path5.join(config.distTempFolder, tempClientSidePath || "./app.ts");
|
|
619
650
|
fs7.ensureFileSync(tempFilePath);
|
|
620
651
|
const pagesScriptsGlob = config.publicDir + "/scripts/pages/**/*.{js,ts}";
|
|
621
652
|
const clientFiles = globSync3(
|
|
@@ -642,7 +673,7 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev2) {
|
|
|
642
673
|
minify: !isDev2,
|
|
643
674
|
sourcemap: isDev2 ? "inline" : false
|
|
644
675
|
});
|
|
645
|
-
await logSize(config.distPublicDir, "client");
|
|
676
|
+
await logSize(config.distPublicDir, id ? `client bundle: ${id}.js` : "client bundle: app.js");
|
|
646
677
|
}
|
|
647
678
|
function writeDevServerClientSideCode(tempFilePath) {
|
|
648
679
|
const devServerPath = path5.join(xpineDistDir, "./src/static/dev-server.js");
|
|
@@ -654,7 +685,7 @@ function writeSpaClientSideCode(tempFilePath) {
|
|
|
654
685
|
const content = fs7.readFileSync(spaPath, "utf-8");
|
|
655
686
|
fs7.appendFileSync(tempFilePath, "\n" + content);
|
|
656
687
|
}
|
|
657
|
-
async function buildAlpineDataFile(componentData, dataFiles) {
|
|
688
|
+
async function buildAlpineDataFile(componentData, dataFiles, bundleID) {
|
|
658
689
|
const output = {
|
|
659
690
|
imports: [
|
|
660
691
|
"import Alpine from 'alpinejs';"
|
|
@@ -698,9 +729,16 @@ async function buildAlpineDataFile(componentData, dataFiles) {
|
|
|
698
729
|
output.code.push(`Alpine.data('${dataFunction.name}', ${dataFunction.name});`);
|
|
699
730
|
}
|
|
700
731
|
const result = output.imports.join("\n") + "\n" + output.code.join("\n") + "\n" + output.end.join("\n");
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
732
|
+
if (bundleID) {
|
|
733
|
+
const bundlePath = path5.join(config.distTempFolder, `./alpine-data-${bundleID}.ts`);
|
|
734
|
+
fs7.ensureFileSync(bundlePath);
|
|
735
|
+
fs7.writeFileSync(bundlePath, result);
|
|
736
|
+
return bundlePath;
|
|
737
|
+
} else {
|
|
738
|
+
fs7.ensureFileSync(config.alpineDataPath);
|
|
739
|
+
fs7.writeFileSync(config.alpineDataPath, result);
|
|
740
|
+
return config.alpineDataPath;
|
|
741
|
+
}
|
|
704
742
|
}
|
|
705
743
|
async function buildPublicFolderSymlinks() {
|
|
706
744
|
const files = globSync3(config.publicDir + "/**/*.*", {
|
|
@@ -833,7 +871,7 @@ async function buildOnLoadFile(componentData, isDev2) {
|
|
|
833
871
|
return a.path.localeCompare(b.path);
|
|
834
872
|
});
|
|
835
873
|
for (const file of onLoadFiles) {
|
|
836
|
-
const result = getXpineOnLoadFunction(file.path, file.source,
|
|
874
|
+
const result = getXpineOnLoadFunction(file.path, file.source, { convertPathsToJS: true });
|
|
837
875
|
onLoadFileResult.fn += result.fn;
|
|
838
876
|
onLoadFileResult.imports += result.imports;
|
|
839
877
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xpine",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.49",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@aws-sdk/client-secrets-manager": "^3.758.0",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"fs-extra": "^11.3.0",
|
|
15
15
|
"glob": "^11.0.1",
|
|
16
16
|
"jsonwebtoken": "^9.0.2",
|
|
17
|
+
"micromatch": "^4.0.8",
|
|
17
18
|
"postcss": "^8.5.3",
|
|
18
19
|
"request-ip": "^3.3.0",
|
|
19
20
|
"shelljs": "^0.9.2",
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"@eslint/js": "^9.24.0",
|
|
49
50
|
"@tailwindcss/oxide-darwin-arm64": "^4.1.3",
|
|
50
51
|
"@types/express": "^5.0.0",
|
|
52
|
+
"@types/micromatch": "^4.0.9",
|
|
51
53
|
"@types/node": "^22.13.5",
|
|
52
54
|
"@types/request-ip": "^0.0.41",
|
|
53
55
|
"@types/shelljs": "^0.8.15",
|