@webmate-studio/builder 0.2.18 → 0.2.20
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/package.json +1 -1
- package/src/bundler.js +46 -25
package/package.json
CHANGED
package/src/bundler.js
CHANGED
|
@@ -3,6 +3,17 @@ import esbuildSvelte from 'esbuild-svelte';
|
|
|
3
3
|
import fs from 'fs/promises';
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import pc from 'picocolors';
|
|
6
|
+
import crypto from 'crypto';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generate content hash for asset file
|
|
10
|
+
* @param {Buffer} content - File content as buffer
|
|
11
|
+
* @param {number} length - Hash length (default: 8)
|
|
12
|
+
* @returns {string} - Content hash (hex)
|
|
13
|
+
*/
|
|
14
|
+
function generateAssetHash(content, length = 8) {
|
|
15
|
+
return crypto.createHash('sha256').update(content).digest('hex').substring(0, length);
|
|
16
|
+
}
|
|
6
17
|
|
|
7
18
|
/**
|
|
8
19
|
* Bundle island JavaScript files with esbuild
|
|
@@ -42,6 +53,7 @@ export async function bundleIsland(islandPath, outputPath, options = {}) {
|
|
|
42
53
|
target,
|
|
43
54
|
outfile: outputPath,
|
|
44
55
|
platform: 'browser',
|
|
56
|
+
charset: 'utf8', // Force UTF-8 output to prevent base64 corruption (esbuild bug #1501)
|
|
45
57
|
// Loaders for different file types
|
|
46
58
|
// NOTE: All image formats are handled by custom plugin above (image-base64-dataurl)
|
|
47
59
|
// to generate proper data:image/...;base64,... URLs for CSS compatibility
|
|
@@ -70,39 +82,48 @@ export async function bundleIsland(islandPath, outputPath, options = {}) {
|
|
|
70
82
|
'__VUE_PROD_HYDRATION_MISMATCH_DETAILS__': 'false'
|
|
71
83
|
},
|
|
72
84
|
plugins: [
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
// -
|
|
77
|
-
//
|
|
85
|
+
// Asset URL resolver with content hashing
|
|
86
|
+
// Instead of base64 encoding (bad for large images, no caching, huge bundles),
|
|
87
|
+
// we use asset markers with content hashes that get resolved at runtime:
|
|
88
|
+
// - wm dev: /assets/{componentName}/{filename} (no hash in dev)
|
|
89
|
+
// - CMS: /api/components/proxy/organization-components/{uuid}/assets/{filename}.{hash}.{ext}
|
|
78
90
|
{
|
|
79
|
-
name: '
|
|
91
|
+
name: 'asset-url-resolver',
|
|
80
92
|
setup(build) {
|
|
81
93
|
// Handle all image formats
|
|
82
94
|
build.onLoad({ filter: /\.(svg|jpg|jpeg|png|gif|webp)$/i }, async (args) => {
|
|
83
|
-
|
|
84
|
-
const mimeTypes = {
|
|
85
|
-
svg: 'image/svg+xml',
|
|
86
|
-
jpg: 'image/jpeg',
|
|
87
|
-
jpeg: 'image/jpeg',
|
|
88
|
-
png: 'image/png',
|
|
89
|
-
gif: 'image/gif',
|
|
90
|
-
webp: 'image/webp'
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// Read file as binary buffer
|
|
95
|
+
// Read file to generate content hash
|
|
94
96
|
const buffer = await fs.readFile(args.path);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
const hash = generateAssetHash(buffer);
|
|
98
|
+
|
|
99
|
+
// Get relative path from component directory
|
|
100
|
+
// Example: /full/path/components/Hero/assets/logo.svg
|
|
101
|
+
// → Find "assets/" segment and extract path from there
|
|
102
|
+
const assetPath = args.path;
|
|
103
|
+
const assetsIndex = assetPath.lastIndexOf('/assets/');
|
|
104
|
+
|
|
105
|
+
if (assetsIndex === -1) {
|
|
106
|
+
throw new Error(`Asset must be in "assets/" directory: ${assetPath}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Extract relative path from assets/ onwards
|
|
110
|
+
// Example: assets/logo.svg
|
|
111
|
+
const relativePath = assetPath.substring(assetsIndex + 1); // +1 to keep "assets/"
|
|
112
|
+
|
|
113
|
+
// Parse filename and extension
|
|
114
|
+
const filename = path.basename(relativePath);
|
|
115
|
+
const ext = path.extname(filename);
|
|
116
|
+
const nameWithoutExt = path.basename(filename, ext);
|
|
117
|
+
const dir = path.dirname(relativePath);
|
|
98
118
|
|
|
99
|
-
// Build
|
|
100
|
-
const
|
|
119
|
+
// Build hashed filename: logo.abc123.svg
|
|
120
|
+
const hashedFilename = `${nameWithoutExt}.${hash}${ext}`;
|
|
121
|
+
const hashedPath = path.join(dir, hashedFilename);
|
|
101
122
|
|
|
102
|
-
// Return as
|
|
103
|
-
//
|
|
123
|
+
// Return as asset marker (will be resolved at runtime)
|
|
124
|
+
// Runtime resolver will replace __ASSET__: with correct base path
|
|
104
125
|
return {
|
|
105
|
-
contents: `export default
|
|
126
|
+
contents: `export default "__ASSET__:${hashedPath}";`,
|
|
106
127
|
loader: 'js'
|
|
107
128
|
};
|
|
108
129
|
});
|