frontend-hamroun 1.2.70 → 1.2.71
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/templates/go-wasm-app/README.md +18 -2
- package/templates/go-wasm-app/babel.config.js +15 -0
- package/templates/go-wasm-app/build-client.js +49 -0
- package/templates/go-wasm-app/build-wasm.js +91 -75
- package/templates/go-wasm-app/package-lock.json +6459 -0
- package/templates/go-wasm-app/package.json +7 -12
- package/templates/go-wasm-app/public/index.html +118 -3
- package/templates/go-wasm-app/public/wasm/example.wasm +0 -0
- package/templates/go-wasm-app/public/wasm/wasm_exec.js +561 -0
- package/templates/go-wasm-app/public/wasm/wasm_exec_node.js +39 -0
- package/templates/go-wasm-app/server.js +457 -59
- package/templates/go-wasm-app/src/App.jsx +21 -62
- package/templates/go-wasm-app/src/client.js +57 -0
- package/templates/go-wasm-app/src/wasm/example.go +75 -0
- package/templates/go-wasm-app/vite.config.js +10 -4
package/package.json
CHANGED
@@ -9,7 +9,6 @@ This template demonstrates integration between Frontend Hamroun, Go WebAssembly,
|
|
9
9
|
- ⚡ High-performance computation in both browser and server
|
10
10
|
- 🚀 Same Go code runs in both environments
|
11
11
|
- 🔍 SEO-friendly with pre-rendered HTML
|
12
|
-
- 🧩 Example Go WASM modules and usage patterns
|
13
12
|
|
14
13
|
## Prerequisites
|
15
14
|
|
@@ -19,4 +18,21 @@ This template demonstrates integration between Frontend Hamroun, Go WebAssembly,
|
|
19
18
|
## Getting Started
|
20
19
|
|
21
20
|
1. Install dependencies:
|
22
|
-
|
21
|
+
```
|
22
|
+
npm install
|
23
|
+
```
|
24
|
+
|
25
|
+
2. Start the development server:
|
26
|
+
```
|
27
|
+
npm run dev
|
28
|
+
```
|
29
|
+
|
30
|
+
3. Open your browser and navigate to `http://localhost:3000`
|
31
|
+
|
32
|
+
The development server includes:
|
33
|
+
- Automatic WASM compilation from Go source
|
34
|
+
- Server-side rendering with Express
|
35
|
+
- Hot reloading of server code with Node's `--watch` flag
|
36
|
+
- Client-side hydration for interactivity
|
37
|
+
|
38
|
+
## Project Structure
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import fs from 'fs-extra';
|
2
|
+
import path from 'path';
|
3
|
+
import { fileURLToPath } from 'url';
|
4
|
+
|
5
|
+
// Get __dirname equivalent in ESM
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
7
|
+
const __dirname = path.dirname(__filename);
|
8
|
+
|
9
|
+
// Output directory
|
10
|
+
const outputDir = path.join(__dirname, 'dist');
|
11
|
+
|
12
|
+
// Ensure output directory exists
|
13
|
+
fs.ensureDirSync(outputDir);
|
14
|
+
|
15
|
+
// Copy necessary files for production
|
16
|
+
console.log('Copying files for production...');
|
17
|
+
|
18
|
+
// Copy HTML template
|
19
|
+
fs.copySync(path.join(__dirname, 'public', 'index.html'), path.join(outputDir, 'index.html'));
|
20
|
+
|
21
|
+
// Copy WASM files
|
22
|
+
const wasmDir = path.join(__dirname, 'public', 'wasm');
|
23
|
+
const distWasmDir = path.join(outputDir, 'wasm');
|
24
|
+
fs.ensureDirSync(distWasmDir);
|
25
|
+
|
26
|
+
if (fs.existsSync(wasmDir)) {
|
27
|
+
fs.copySync(wasmDir, distWasmDir);
|
28
|
+
console.log('Copied WASM files to:', distWasmDir);
|
29
|
+
} else {
|
30
|
+
console.warn('WASM directory not found:', wasmDir);
|
31
|
+
}
|
32
|
+
|
33
|
+
// Copy client.js for hydration
|
34
|
+
const srcDir = path.join(__dirname, 'src');
|
35
|
+
const distSrcDir = path.join(outputDir, 'src');
|
36
|
+
fs.ensureDirSync(distSrcDir);
|
37
|
+
fs.copySync(path.join(srcDir, 'client.js'), path.join(distSrcDir, 'client.js'));
|
38
|
+
|
39
|
+
// Copy any other static assets
|
40
|
+
const publicDir = path.join(__dirname, 'public');
|
41
|
+
fs.readdirSync(publicDir).forEach(file => {
|
42
|
+
if (file !== 'index.html' && file !== 'wasm') {
|
43
|
+
const srcPath = path.join(publicDir, file);
|
44
|
+
const destPath = path.join(outputDir, file);
|
45
|
+
fs.copySync(srcPath, destPath);
|
46
|
+
}
|
47
|
+
});
|
48
|
+
|
49
|
+
console.log('Build completed successfully.');
|
@@ -42,6 +42,12 @@ async function buildWasmModules() {
|
|
42
42
|
fs.mkdirSync(wasmOutputDir, { recursive: true });
|
43
43
|
}
|
44
44
|
|
45
|
+
// Create Go source directory if it doesn't exist
|
46
|
+
if (!fs.existsSync(goSourceDir)) {
|
47
|
+
fs.mkdirSync(goSourceDir, { recursive: true });
|
48
|
+
console.log(`Created Go source directory: ${goSourceDir}`);
|
49
|
+
}
|
50
|
+
|
45
51
|
// Get the Go root directory
|
46
52
|
const goRoot = execSync('go env GOROOT', { encoding: 'utf8' }).trim();
|
47
53
|
|
@@ -55,82 +61,30 @@ async function buildWasmModules() {
|
|
55
61
|
console.log(`Copying ${wasmExecJsPath} to ${wasmExecJsDest}`);
|
56
62
|
fs.copyFileSync(wasmExecJsPath, wasmExecJsDest);
|
57
63
|
|
58
|
-
|
59
|
-
fs.
|
60
|
-
|
61
|
-
|
62
|
-
if (fs.existsSync(goSourceDir)) {
|
63
|
-
const goFiles = fs.readdirSync(goSourceDir)
|
64
|
-
.filter(file => file.endsWith('.go'));
|
64
|
+
// Copy Node.js WASM executor if it exists
|
65
|
+
if (fs.existsSync(wasmExecNodeJsPath)) {
|
66
|
+
console.log(`Copying ${wasmExecNodeJsPath} to ${wasmExecNodeJsDest}`);
|
67
|
+
fs.copyFileSync(wasmExecNodeJsPath, wasmExecNodeJsDest);
|
65
68
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
const wasmFilePath = join(wasmOutputDir, wasmFileName);
|
75
|
-
|
76
|
-
console.log(`Building ${goFile} to ${wasmFilePath}`);
|
77
|
-
|
78
|
-
try {
|
79
|
-
// Create a unique temporary directory with timestamp
|
80
|
-
const timestamp = Date.now();
|
81
|
-
const tempDir = join(os.tmpdir(), `go-wasm-build-${timestamp}`);
|
82
|
-
|
83
|
-
// Ensure the directory is clean (doesn't exist from previous builds)
|
84
|
-
if (fs.existsSync(tempDir)) {
|
85
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
86
|
-
}
|
87
|
-
|
88
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
89
|
-
|
90
|
-
// Copy the Go file to the temp directory
|
91
|
-
const tempGoFile = join(tempDir, goFile);
|
92
|
-
fs.copyFileSync(goFilePath, tempGoFile);
|
93
|
-
|
94
|
-
// Initialize Go module
|
95
|
-
console.log(`Initializing Go module in ${tempDir}`);
|
96
|
-
execSync(`go mod init wasmapp`, { cwd: tempDir });
|
97
|
-
|
98
|
-
// Build the WASM module with OS-specific command
|
99
|
-
if (isWindows) {
|
100
|
-
// Fix: Windows command without spaces in environment variables
|
101
|
-
// and using environment object instead of command-line args
|
102
|
-
execSync(`go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
103
|
-
cwd: tempDir,
|
104
|
-
env: {
|
105
|
-
...process.env,
|
106
|
-
GOOS: 'js',
|
107
|
-
GOARCH: 'wasm'
|
108
|
-
}
|
109
|
-
});
|
110
|
-
} else {
|
111
|
-
// Unix/Linux/Mac command
|
112
|
-
execSync(`GOOS=js GOARCH=wasm go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
113
|
-
cwd: tempDir
|
114
|
-
});
|
115
|
-
}
|
116
|
-
|
117
|
-
// Clean up temporary directory
|
118
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
119
|
-
|
120
|
-
console.log(`✓ Successfully built ${wasmFileName}`);
|
121
|
-
} catch (error) {
|
122
|
-
console.error(`✗ Error building ${goFile}:`);
|
123
|
-
console.error(error.message);
|
124
|
-
if (error.stdout) console.error(error.stdout.toString());
|
125
|
-
if (error.stderr) console.error(error.stderr.toString());
|
69
|
+
// Also try to copy the go_js_wasm_exec script that's needed in some Go versions
|
70
|
+
try {
|
71
|
+
const goJsWasmExecPath = join(goRoot, 'misc', 'wasm', 'go_js_wasm_exec');
|
72
|
+
if (fs.existsSync(goJsWasmExecPath)) {
|
73
|
+
const goJsWasmExecDest = join(wasmOutputDir, 'go_js_wasm_exec');
|
74
|
+
fs.copyFileSync(goJsWasmExecPath, goJsWasmExecDest);
|
75
|
+
fs.chmodSync(goJsWasmExecDest, '755'); // Make executable
|
76
|
+
console.log(`Copied go_js_wasm_exec to ${goJsWasmExecDest}`);
|
126
77
|
}
|
78
|
+
} catch (error) {
|
79
|
+
console.warn("Could not copy go_js_wasm_exec:", error.message);
|
127
80
|
}
|
128
81
|
} else {
|
129
|
-
console.
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
82
|
+
console.warn(`${wasmExecNodeJsPath} not found, skipping Node.js WASM support`);
|
83
|
+
}
|
84
|
+
|
85
|
+
// Create an example Go file if it doesn't exist
|
86
|
+
const exampleGoFile = join(goSourceDir, 'example.go');
|
87
|
+
if (!fs.existsSync(exampleGoFile)) {
|
134
88
|
const exampleGoContent = `//go:build js && wasm
|
135
89
|
// +build js,wasm
|
136
90
|
|
@@ -210,10 +164,72 @@ func main() {
|
|
210
164
|
|
211
165
|
fs.writeFileSync(exampleGoFile, exampleGoContent);
|
212
166
|
console.log(`Created example Go file at ${exampleGoFile}`);
|
167
|
+
}
|
168
|
+
|
169
|
+
// Get list of Go files
|
170
|
+
const goFiles = fs.readdirSync(goSourceDir).filter(file => file.endsWith('.go'));
|
171
|
+
|
172
|
+
if (goFiles.length === 0) {
|
173
|
+
console.log('No Go files found in src/wasm');
|
174
|
+
return;
|
175
|
+
}
|
176
|
+
|
177
|
+
// Build each Go file
|
178
|
+
for (const goFile of goFiles) {
|
179
|
+
const goFilePath = join(goSourceDir, goFile);
|
180
|
+
const wasmFileName = goFile.replace('.go', '.wasm');
|
181
|
+
const wasmFilePath = join(wasmOutputDir, wasmFileName);
|
182
|
+
|
183
|
+
console.log(`Building ${goFile} to ${wasmFilePath}`);
|
213
184
|
|
214
|
-
|
215
|
-
|
216
|
-
|
185
|
+
try {
|
186
|
+
// Create a unique temporary directory with timestamp
|
187
|
+
const timestamp = Date.now();
|
188
|
+
const tempDir = join(os.tmpdir(), `go-wasm-build-${timestamp}`);
|
189
|
+
|
190
|
+
// Ensure the directory is clean (doesn't exist from previous builds)
|
191
|
+
if (fs.existsSync(tempDir)) {
|
192
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
193
|
+
}
|
194
|
+
|
195
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
196
|
+
|
197
|
+
// Copy the Go file to the temp directory
|
198
|
+
const tempGoFile = join(tempDir, goFile);
|
199
|
+
fs.copyFileSync(goFilePath, tempGoFile);
|
200
|
+
|
201
|
+
// Initialize Go module
|
202
|
+
console.log(`Initializing Go module in ${tempDir}`);
|
203
|
+
execSync(`go mod init wasmapp`, { cwd: tempDir });
|
204
|
+
|
205
|
+
// Build the WASM module with OS-specific command
|
206
|
+
if (isWindows) {
|
207
|
+
// Fix: Use Windows-specific environment variable setting
|
208
|
+
execSync(`go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
209
|
+
cwd: tempDir,
|
210
|
+
env: {
|
211
|
+
...process.env,
|
212
|
+
GOOS: 'js',
|
213
|
+
GOARCH: 'wasm'
|
214
|
+
}
|
215
|
+
});
|
216
|
+
} else {
|
217
|
+
// Unix/Linux/Mac command
|
218
|
+
execSync(`GOOS=js GOARCH=wasm go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
219
|
+
cwd: tempDir
|
220
|
+
});
|
221
|
+
}
|
222
|
+
|
223
|
+
// Clean up temporary directory
|
224
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
225
|
+
|
226
|
+
console.log(`✓ Successfully built ${wasmFileName}`);
|
227
|
+
} catch (error) {
|
228
|
+
console.error(`✗ Error building ${goFile}:`);
|
229
|
+
console.error(error.message);
|
230
|
+
if (error.stdout) console.error(error.stdout.toString());
|
231
|
+
if (error.stderr) console.error(error.stderr.toString());
|
232
|
+
}
|
217
233
|
}
|
218
234
|
}
|
219
235
|
|