frontend-hamroun 1.2.69 → 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 +38 -0
- 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 +95 -73
- package/templates/go-wasm-app/package-lock.json +6459 -0
- package/templates/go-wasm-app/package.json +9 -8
- package/templates/go-wasm-app/public/index.html +118 -3
- package/templates/go-wasm-app/public/styles.css +197 -0
- 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 +521 -0
- package/templates/go-wasm-app/src/App.jsx +38 -0
- package/templates/go-wasm-app/src/client.js +57 -0
- package/templates/go-wasm-app/src/components/Footer.jsx +13 -0
- package/templates/go-wasm-app/src/components/Header.jsx +19 -0
- package/templates/go-wasm-app/src/components/WasmDemo.jsx +120 -0
- package/templates/go-wasm-app/src/main.jsx +12 -0
- package/templates/go-wasm-app/src/wasm/example.go +75 -0
- package/templates/go-wasm-app/tsconfig.server.json +18 -0
- package/templates/go-wasm-app/vite.config.js +10 -4
package/package.json
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Frontend Hamroun - Go WebAssembly Template with SSR
|
2
|
+
|
3
|
+
This template demonstrates integration between Frontend Hamroun, Go WebAssembly, and Server-Side Rendering for high-performance web applications.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
- 🔄 Go + WebAssembly integration
|
8
|
+
- 🌐 Server-Side Rendering with client hydration
|
9
|
+
- ⚡ High-performance computation in both browser and server
|
10
|
+
- 🚀 Same Go code runs in both environments
|
11
|
+
- 🔍 SEO-friendly with pre-rendered HTML
|
12
|
+
|
13
|
+
## Prerequisites
|
14
|
+
|
15
|
+
- [Node.js](https://nodejs.org/) (v14+)
|
16
|
+
- [Go](https://golang.org/dl/) (v1.16+)
|
17
|
+
|
18
|
+
## Getting Started
|
19
|
+
|
20
|
+
1. Install dependencies:
|
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,89 +42,49 @@ 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
|
|
48
|
-
// Copy the wasm_exec.js
|
54
|
+
// Copy the wasm_exec.js files to the output directory (for both browser and Node.js)
|
49
55
|
const wasmExecJsPath = join(goRoot, 'misc', 'wasm', 'wasm_exec.js');
|
50
56
|
const wasmExecJsDest = join(wasmOutputDir, 'wasm_exec.js');
|
51
57
|
|
58
|
+
const wasmExecNodeJsPath = join(goRoot, 'misc', 'wasm', 'wasm_exec_node.js');
|
59
|
+
const wasmExecNodeJsDest = join(wasmOutputDir, 'wasm_exec_node.js');
|
60
|
+
|
52
61
|
console.log(`Copying ${wasmExecJsPath} to ${wasmExecJsDest}`);
|
53
62
|
fs.copyFileSync(wasmExecJsPath, wasmExecJsDest);
|
54
63
|
|
55
|
-
//
|
56
|
-
if (fs.existsSync(
|
57
|
-
|
58
|
-
|
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);
|
59
68
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
const wasmFilePath = join(wasmOutputDir, wasmFileName);
|
69
|
-
|
70
|
-
console.log(`Building ${goFile} to ${wasmFilePath}`);
|
71
|
-
|
72
|
-
try {
|
73
|
-
// Create a unique temporary directory with timestamp
|
74
|
-
const timestamp = Date.now();
|
75
|
-
const tempDir = join(os.tmpdir(), `go-wasm-build-${timestamp}`);
|
76
|
-
|
77
|
-
// Ensure the directory is clean (doesn't exist from previous builds)
|
78
|
-
if (fs.existsSync(tempDir)) {
|
79
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
80
|
-
}
|
81
|
-
|
82
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
83
|
-
|
84
|
-
// Copy the Go file to the temp directory
|
85
|
-
const tempGoFile = join(tempDir, goFile);
|
86
|
-
fs.copyFileSync(goFilePath, tempGoFile);
|
87
|
-
|
88
|
-
// Initialize Go module
|
89
|
-
console.log(`Initializing Go module in ${tempDir}`);
|
90
|
-
execSync(`go mod init wasmapp`, { cwd: tempDir });
|
91
|
-
|
92
|
-
// Build the WASM module with OS-specific command
|
93
|
-
if (isWindows) {
|
94
|
-
// Fix: Windows command without spaces in environment variables
|
95
|
-
// and using environment object instead of command-line args
|
96
|
-
execSync(`go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
97
|
-
cwd: tempDir,
|
98
|
-
env: {
|
99
|
-
...process.env,
|
100
|
-
GOOS: 'js',
|
101
|
-
GOARCH: 'wasm'
|
102
|
-
}
|
103
|
-
});
|
104
|
-
} else {
|
105
|
-
// Unix/Linux/Mac command
|
106
|
-
execSync(`GOOS=js GOARCH=wasm go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
107
|
-
cwd: tempDir
|
108
|
-
});
|
109
|
-
}
|
110
|
-
|
111
|
-
// Clean up temporary directory
|
112
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
113
|
-
|
114
|
-
console.log(`✓ Successfully built ${wasmFileName}`);
|
115
|
-
} catch (error) {
|
116
|
-
console.error(`✗ Error building ${goFile}:`);
|
117
|
-
console.error(error.message);
|
118
|
-
if (error.stdout) console.error(error.stdout.toString());
|
119
|
-
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}`);
|
120
77
|
}
|
78
|
+
} catch (error) {
|
79
|
+
console.warn("Could not copy go_js_wasm_exec:", error.message);
|
121
80
|
}
|
122
81
|
} else {
|
123
|
-
console.
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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)) {
|
128
88
|
const exampleGoContent = `//go:build js && wasm
|
129
89
|
// +build js,wasm
|
130
90
|
|
@@ -204,10 +164,72 @@ func main() {
|
|
204
164
|
|
205
165
|
fs.writeFileSync(exampleGoFile, exampleGoContent);
|
206
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}`);
|
207
184
|
|
208
|
-
|
209
|
-
|
210
|
-
|
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
|
+
}
|
211
233
|
}
|
212
234
|
}
|
213
235
|
|