@nlabs/lex 1.51.6 → 1.52.0
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 +120 -54
- package/lib/Button.stories.js +1 -1
- package/lib/LexConfig.d.ts +1 -1
- package/lib/LexConfig.js +36 -14
- package/lib/commands/build/build.js +120 -23
- package/lib/commands/clean/clean.js +1 -1
- package/lib/commands/compile/compile.js +95 -28
- package/lib/commands/config/config.js +1 -1
- package/lib/commands/copy/copy.js +1 -1
- package/lib/commands/create/create.js +1 -1
- package/lib/commands/dev/dev.js +22 -11
- package/lib/commands/init/init.js +1 -1
- package/lib/commands/link/link.js +1 -1
- package/lib/commands/lint/lint.js +1 -1
- package/lib/commands/serverless/serverless.js +1 -1
- package/lib/commands/storybook/storybook.js +1 -1
- package/lib/commands/versions/versions.js +1 -1
- package/lib/utils/aiService.js +1 -1
- package/lib/utils/app.d.ts +1 -1
- package/lib/utils/app.js +22 -17
- package/lib/utils/file.js +24 -3
- package/lib/utils/postcss/postcss-for.d.ts +1 -1
- package/lib/utils/postcss/postcss-for.js +6 -8
- package/lib/utils/postcss/postcss-percentage.d.ts +1 -1
- package/lib/utils/postcss/postcss-percentage.js +14 -13
- package/package.json +10 -3
- package/scripts/test-static-manual.js +117 -0
- package/scripts/test-webpack.js +124 -30
- package/webpack.config.js +135 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nlabs/lex",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.52.0",
|
|
4
4
|
"description": "Lex",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"dotenv-webpack": "^8.1.1",
|
|
132
132
|
"download-npm-package": "^3.1.12",
|
|
133
133
|
"eslint": "^9.39.1",
|
|
134
|
-
"eslint-config-styleguidejs": "^4.1.
|
|
134
|
+
"eslint-config-styleguidejs": "^4.1.12",
|
|
135
135
|
"execa": "9.6.1",
|
|
136
136
|
"expect": "^30.2.0",
|
|
137
137
|
"exports-loader": "^5.0.0",
|
|
@@ -176,9 +176,12 @@
|
|
|
176
176
|
"postcss-nesting": "^13.0.2",
|
|
177
177
|
"postcss-percentage": "^0.0.0",
|
|
178
178
|
"postcss-preset-env": "^10.5.0",
|
|
179
|
+
"postcss-value-parser": "^4.2.0",
|
|
180
|
+
"math-expression-evaluator": "^2.0.7",
|
|
179
181
|
"postcss-simple-vars": "^7.0.1",
|
|
180
182
|
"postcss-svgo": "7.1.0",
|
|
181
183
|
"postcss-url": "10.1.3",
|
|
184
|
+
"postcss": "^8.5.6",
|
|
182
185
|
"process": "^0.11.10",
|
|
183
186
|
"randombytes": "^2.1.0",
|
|
184
187
|
"react": "^19.2.1",
|
|
@@ -194,7 +197,7 @@
|
|
|
194
197
|
"stream-browserify": "^3.0.0",
|
|
195
198
|
"stream-http": "^3.2.0",
|
|
196
199
|
"style-loader": "^4.0.0",
|
|
197
|
-
"svg-spritemap-webpack-plugin": "^5.0
|
|
200
|
+
"svg-spritemap-webpack-plugin": "^5.1.0",
|
|
198
201
|
"svgo": "4.0.0",
|
|
199
202
|
"swc-loader": "^0.2.6",
|
|
200
203
|
"tailwindcss": "^4.1.17",
|
|
@@ -230,10 +233,14 @@
|
|
|
230
233
|
"css-loader": "7.1.2"
|
|
231
234
|
},
|
|
232
235
|
"overrides": {
|
|
236
|
+
"cheerio": "^1.0.0-rc.13",
|
|
233
237
|
"cross-spawn": "^7.0.6",
|
|
238
|
+
"css-select": "^5.1.0",
|
|
234
239
|
"got": "^14.6.5",
|
|
235
240
|
"http-cache-semantics": "^4.2.0",
|
|
236
241
|
"http-proxy-middleware": "^3.0.5",
|
|
242
|
+
"lodash.pick": "^4.4.0",
|
|
243
|
+
"nth-check": "^2.1.1",
|
|
237
244
|
"postcss": "^8.5.6",
|
|
238
245
|
"semver-regex": "^4.0.5",
|
|
239
246
|
"tmp": "^0.2.5"
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Manual test script to verify static file serving
|
|
4
|
+
* This script starts the dev server and tests static file access
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {spawn} from 'child_process';
|
|
8
|
+
import {createConnection} from 'net';
|
|
9
|
+
import {join} from 'path';
|
|
10
|
+
import {fileURLToPath} from 'url';
|
|
11
|
+
import {dirname} from 'path';
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
const projectRoot = join(__dirname, '..');
|
|
16
|
+
|
|
17
|
+
const testPort = 3002;
|
|
18
|
+
const lexPath = join(projectRoot, 'lib', 'lex.js');
|
|
19
|
+
|
|
20
|
+
console.log('🧪 Starting dev server to test static file serving...');
|
|
21
|
+
console.log(` Port: ${testPort}`);
|
|
22
|
+
console.log(` Static path: ${join(projectRoot, 'src', 'static')}`);
|
|
23
|
+
console.log(` Test file: ${join(projectRoot, 'src', 'static', 'test.txt')}\n`);
|
|
24
|
+
|
|
25
|
+
const devServerProcess = spawn('node', [lexPath, 'dev', '--port', testPort.toString()], {
|
|
26
|
+
cwd: projectRoot,
|
|
27
|
+
stdio: 'inherit',
|
|
28
|
+
env: {
|
|
29
|
+
...process.env,
|
|
30
|
+
NODE_ENV: 'development'
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const checkPort = (port) => {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
const socket = createConnection(port, 'localhost');
|
|
37
|
+
socket.on('connect', () => {
|
|
38
|
+
socket.destroy();
|
|
39
|
+
resolve(true);
|
|
40
|
+
});
|
|
41
|
+
socket.on('error', () => {
|
|
42
|
+
resolve(false);
|
|
43
|
+
});
|
|
44
|
+
socket.setTimeout(2000, () => {
|
|
45
|
+
socket.destroy();
|
|
46
|
+
resolve(false);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const waitForServer = async () => {
|
|
52
|
+
console.log('⏳ Waiting for server to start...');
|
|
53
|
+
for (let i = 0; i < 60; i++) {
|
|
54
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
55
|
+
const portOpen = await checkPort(testPort);
|
|
56
|
+
if (portOpen) {
|
|
57
|
+
console.log(`✅ Server is running on port ${testPort}\n`);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
if (i % 5 === 4) {
|
|
61
|
+
process.stdout.write('.');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const testStaticFile = async () => {
|
|
68
|
+
try {
|
|
69
|
+
console.log('🌐 Testing static file access...');
|
|
70
|
+
const response = await fetch(`http://localhost:${testPort}/test.txt`);
|
|
71
|
+
console.log(` Status: ${response.status}`);
|
|
72
|
+
console.log(` Headers:`, Object.fromEntries(response.headers.entries()));
|
|
73
|
+
|
|
74
|
+
if (response.ok) {
|
|
75
|
+
const content = await response.text();
|
|
76
|
+
console.log(` Content: "${content}"`);
|
|
77
|
+
console.log('\n✅ Static file is accessible!');
|
|
78
|
+
return true;
|
|
79
|
+
} else {
|
|
80
|
+
console.log(`\n❌ Static file returned status ${response.status}`);
|
|
81
|
+
const text = await response.text();
|
|
82
|
+
console.log(` Response: ${text.substring(0, 200)}`);
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.log(`\n❌ Error accessing static file: ${error.message}`);
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
waitForServer().then(async (serverReady) => {
|
|
92
|
+
if (!serverReady) {
|
|
93
|
+
console.log('\n❌ Server did not start within 60 seconds');
|
|
94
|
+
devServerProcess.kill('SIGTERM');
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Give it a moment to fully initialize
|
|
99
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
100
|
+
|
|
101
|
+
const success = await testStaticFile();
|
|
102
|
+
|
|
103
|
+
console.log('\n🛑 Stopping dev server...');
|
|
104
|
+
devServerProcess.kill('SIGTERM');
|
|
105
|
+
setTimeout(() => {
|
|
106
|
+
if (!devServerProcess.killed) {
|
|
107
|
+
devServerProcess.kill('SIGKILL');
|
|
108
|
+
}
|
|
109
|
+
process.exit(success ? 0 : 1);
|
|
110
|
+
}, 1000);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
devServerProcess.on('error', (error) => {
|
|
114
|
+
console.error('❌ Failed to start dev server:', error.message);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
});
|
|
117
|
+
|
package/scripts/test-webpack.js
CHANGED
|
@@ -215,9 +215,14 @@ try {
|
|
|
215
215
|
});
|
|
216
216
|
|
|
217
217
|
let serverOutput = '';
|
|
218
|
+
let serverStartedOutput = false;
|
|
218
219
|
devServerProcess.stdout.on('data', (data) => {
|
|
219
220
|
const output = data.toString();
|
|
220
221
|
serverOutput += output;
|
|
222
|
+
// Check for server ready indicators
|
|
223
|
+
if (output.includes('compiled') || output.includes('Local:') || output.includes('http://') || output.includes('webpack compiled')) {
|
|
224
|
+
serverStartedOutput = true;
|
|
225
|
+
}
|
|
221
226
|
});
|
|
222
227
|
|
|
223
228
|
devServerProcess.stderr.on('data', (data) => {
|
|
@@ -226,6 +231,10 @@ try {
|
|
|
226
231
|
if (output.includes('error') || output.includes('Error') || output.includes('ERROR')) {
|
|
227
232
|
serverError = output;
|
|
228
233
|
}
|
|
234
|
+
// Sometimes webpack outputs to stderr but it's not an error
|
|
235
|
+
if (output.includes('compiled') || output.includes('webpack')) {
|
|
236
|
+
serverStartedOutput = true;
|
|
237
|
+
}
|
|
229
238
|
});
|
|
230
239
|
|
|
231
240
|
devServerProcess.on('error', (error) => {
|
|
@@ -253,33 +262,65 @@ try {
|
|
|
253
262
|
};
|
|
254
263
|
|
|
255
264
|
const waitForServer = async () => {
|
|
256
|
-
for (let i = 0; i <
|
|
265
|
+
for (let i = 0; i < 90; i++) {
|
|
257
266
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
258
267
|
|
|
259
268
|
const portOpen = await checkPort(testPort);
|
|
260
|
-
if (portOpen) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
269
|
+
if (portOpen || serverStartedOutput) {
|
|
270
|
+
// Give it a bit more time to fully initialize
|
|
271
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
272
|
+
|
|
273
|
+
// Try to access the static file directly
|
|
274
|
+
try {
|
|
275
|
+
const controller = new AbortController();
|
|
276
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
277
|
+
const response = await fetch(`http://localhost:${testPort}/test.txt`, {
|
|
278
|
+
signal: controller.signal
|
|
279
|
+
});
|
|
280
|
+
clearTimeout(timeoutId);
|
|
281
|
+
if (response.ok && response.status === 200) {
|
|
282
|
+
const content = await response.text();
|
|
283
|
+
if (content.includes('Static file content')) {
|
|
272
284
|
return true;
|
|
273
285
|
}
|
|
274
|
-
}
|
|
275
|
-
|
|
286
|
+
}
|
|
287
|
+
} catch (error) {
|
|
288
|
+
if (error.name !== 'AbortError' && i > 5) {
|
|
289
|
+
// Only log after a few attempts
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Also try index.html as a fallback check
|
|
294
|
+
try {
|
|
295
|
+
const controller = new AbortController();
|
|
296
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000);
|
|
297
|
+
const response = await fetch(`http://localhost:${testPort}/index.html`, {
|
|
298
|
+
signal: controller.signal
|
|
299
|
+
});
|
|
300
|
+
clearTimeout(timeoutId);
|
|
301
|
+
if (response.ok || response.status === 200) {
|
|
302
|
+
// Server is up, even if static file test didn't work yet
|
|
303
|
+
if (i > 10) {
|
|
304
|
+
// After 10 seconds, if server is up, try static file again
|
|
305
|
+
try {
|
|
306
|
+
const staticResponse = await fetch(`http://localhost:${testPort}/test.txt`, {
|
|
307
|
+
signal: controller.signal
|
|
308
|
+
});
|
|
309
|
+
if (staticResponse.ok) {
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
} catch {
|
|
313
|
+
}
|
|
276
314
|
}
|
|
277
315
|
}
|
|
316
|
+
} catch (error) {
|
|
317
|
+
if (error.name !== 'AbortError') {
|
|
318
|
+
}
|
|
278
319
|
}
|
|
279
320
|
}
|
|
280
321
|
|
|
281
322
|
if (i % 10 === 9 && i > 0) {
|
|
282
|
-
console.log(` Still waiting... (${i + 1}/
|
|
323
|
+
console.log(` Still waiting... (${i + 1}/90 seconds)`);
|
|
283
324
|
}
|
|
284
325
|
}
|
|
285
326
|
return false;
|
|
@@ -288,29 +329,49 @@ try {
|
|
|
288
329
|
serverReady = await waitForServer();
|
|
289
330
|
|
|
290
331
|
if (serverError) {
|
|
291
|
-
console.log(
|
|
292
|
-
console.log('
|
|
332
|
+
console.log(`❌ Dev server error: ${serverError}`);
|
|
333
|
+
console.log('❌ HTTP tests cannot run due to server error');
|
|
293
334
|
console.log('💡 Note: Static files are copied to build directory and should be accessible via dev server');
|
|
335
|
+
throw new Error(`Dev server failed to start: ${serverError}`);
|
|
294
336
|
} else if (!serverReady) {
|
|
295
|
-
console.log('
|
|
296
|
-
console.log('
|
|
337
|
+
console.log('❌ Dev server did not start within 60 seconds');
|
|
338
|
+
console.log('❌ HTTP tests cannot run - this is a required test');
|
|
297
339
|
console.log('💡 To test manually, run: cd <test-dir> && lex dev --port 3001');
|
|
298
340
|
if (serverOutput) {
|
|
299
|
-
const lastOutput = serverOutput.slice(-
|
|
300
|
-
console.log('\nServer output (last
|
|
341
|
+
const lastOutput = serverOutput.slice(-2000);
|
|
342
|
+
console.log('\nServer output (last 2000 chars):');
|
|
301
343
|
console.log(lastOutput);
|
|
344
|
+
// Check if there are any obvious errors
|
|
345
|
+
if (lastOutput.includes('Error') || lastOutput.includes('error') || lastOutput.includes('Cannot find')) {
|
|
346
|
+
console.log('\n⚠️ Potential errors detected in server output above');
|
|
347
|
+
}
|
|
302
348
|
} else {
|
|
303
349
|
console.log(' (No server output captured - server may not have started)');
|
|
350
|
+
console.log(' This could indicate the process failed to spawn or exited immediately');
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Check if process is still running
|
|
354
|
+
if (devServerProcess && !devServerProcess.killed) {
|
|
355
|
+
try {
|
|
356
|
+
devServerProcess.kill(0); // Check if process exists
|
|
357
|
+
console.log(' (Dev server process is still running but not responding)');
|
|
358
|
+
} catch {
|
|
359
|
+
console.log(' (Dev server process has exited)');
|
|
360
|
+
}
|
|
304
361
|
}
|
|
362
|
+
throw new Error('Dev server did not start within timeout period - HTTP static file access test cannot run');
|
|
305
363
|
} else {
|
|
306
364
|
console.log(`✅ Dev server started on port ${testPort}`);
|
|
307
365
|
|
|
308
366
|
const testUrls = [
|
|
309
|
-
{url: '/test.txt', expectedContent: 'Static file content', description: 'Static file from staticPath'},
|
|
310
|
-
{url: '/index.html', expectedContent: 'Test App', description: 'HTML file'},
|
|
311
|
-
{url: '/images/test.png', expectedContent: 'fake-png-content', description: 'Image file'}
|
|
367
|
+
{url: '/test.txt', expectedContent: 'Static file content', description: 'Static file from staticPath', required: true},
|
|
368
|
+
{url: '/index.html', expectedContent: 'Test App', description: 'HTML file', required: false},
|
|
369
|
+
{url: '/images/test.png', expectedContent: 'fake-png-content', description: 'Image file', required: false}
|
|
312
370
|
];
|
|
313
371
|
|
|
372
|
+
let httpTestFailed = false;
|
|
373
|
+
const httpTestErrors = [];
|
|
374
|
+
|
|
314
375
|
for (const test of testUrls) {
|
|
315
376
|
try {
|
|
316
377
|
const response = await fetch(`http://localhost:${testPort}${test.url}`);
|
|
@@ -319,19 +380,47 @@ try {
|
|
|
319
380
|
if (content.includes(test.expectedContent)) {
|
|
320
381
|
console.log(`✅ ${test.description} accessible via HTTP (${test.url})`);
|
|
321
382
|
} else {
|
|
322
|
-
|
|
383
|
+
const errorMsg = `${test.description} accessible but content doesn't match (${test.url})`;
|
|
384
|
+
console.log(`❌ ${errorMsg}`);
|
|
385
|
+
if (test.required) {
|
|
386
|
+
httpTestFailed = true;
|
|
387
|
+
httpTestErrors.push(errorMsg);
|
|
388
|
+
}
|
|
323
389
|
}
|
|
324
390
|
} else {
|
|
325
|
-
|
|
391
|
+
const errorMsg = `${test.description} returned status ${response.status} (${test.url})`;
|
|
392
|
+
console.log(`❌ ${errorMsg}`);
|
|
393
|
+
if (test.required) {
|
|
394
|
+
httpTestFailed = true;
|
|
395
|
+
httpTestErrors.push(errorMsg);
|
|
396
|
+
}
|
|
326
397
|
}
|
|
327
398
|
} catch (error) {
|
|
328
|
-
|
|
399
|
+
const errorMsg = `Failed to fetch ${test.description}: ${error.message}`;
|
|
400
|
+
console.log(`❌ ${errorMsg}`);
|
|
401
|
+
if (test.required) {
|
|
402
|
+
httpTestFailed = true;
|
|
403
|
+
httpTestErrors.push(errorMsg);
|
|
404
|
+
}
|
|
329
405
|
}
|
|
330
406
|
}
|
|
407
|
+
|
|
408
|
+
if (httpTestFailed) {
|
|
409
|
+
console.log('\n❌ HTTP static file access test FAILED!');
|
|
410
|
+
console.log('Errors:');
|
|
411
|
+
httpTestErrors.forEach(err => console.log(` - ${err}`));
|
|
412
|
+
console.log('\n💡 The dev server must be able to serve static files from the staticPath directory.');
|
|
413
|
+
console.log('💡 Check that the middleware in webpack.config.js is correctly serving files from staticPathFull.');
|
|
414
|
+
throw new Error('HTTP static file access test failed');
|
|
415
|
+
} else {
|
|
416
|
+
console.log('\n✅ All HTTP static file access tests passed!');
|
|
417
|
+
}
|
|
331
418
|
}
|
|
332
419
|
|
|
333
420
|
} catch (error) {
|
|
334
|
-
console.
|
|
421
|
+
console.error(`\n❌ Dev server HTTP test failed: ${error.message}`);
|
|
422
|
+
console.error('This test is required and must pass.');
|
|
423
|
+
throw error;
|
|
335
424
|
} finally {
|
|
336
425
|
if (devServerProcess) {
|
|
337
426
|
console.log('🛑 Stopping dev server...');
|
|
@@ -344,12 +433,17 @@ try {
|
|
|
344
433
|
}
|
|
345
434
|
}
|
|
346
435
|
|
|
436
|
+
// Only print success if we didn't throw an error
|
|
347
437
|
console.log('\n🎉 All tests passed!');
|
|
348
438
|
console.log(`\n📁 Test project location: ${testDir}`);
|
|
349
439
|
console.log('💡 You can inspect the build output in the build/ directory');
|
|
350
440
|
|
|
351
441
|
} catch (error) {
|
|
352
|
-
console.error('❌
|
|
442
|
+
console.error('\n❌ Test suite failed:', error.message);
|
|
443
|
+
if (error.stack) {
|
|
444
|
+
console.error('\nStack trace:');
|
|
445
|
+
console.error(error.stack);
|
|
446
|
+
}
|
|
353
447
|
process.exit(1);
|
|
354
448
|
} finally {
|
|
355
449
|
console.log('\n🧹 Cleaning up...');
|
package/webpack.config.js
CHANGED
|
@@ -15,7 +15,9 @@ import {existsSync} from 'fs';
|
|
|
15
15
|
import {sync as globSync} from 'glob';
|
|
16
16
|
import HtmlWebPackPlugin from 'html-webpack-plugin';
|
|
17
17
|
import isEmpty from 'lodash/isEmpty.js';
|
|
18
|
+
import {createRequire} from 'module';
|
|
18
19
|
import {resolve as pathResolve} from 'path';
|
|
20
|
+
import {fileURLToPath} from 'url';
|
|
19
21
|
import postcssBrowserReporter from 'postcss-browser-reporter';
|
|
20
22
|
import postcssCustomProperties from 'postcss-custom-properties';
|
|
21
23
|
import postcssFlexbugsFixes from 'postcss-flexbugs-fixes';
|
|
@@ -40,6 +42,7 @@ const {ProgressPlugin, ProvidePlugin} = webpack;
|
|
|
40
42
|
const isProduction = process.env.NODE_ENV === 'production';
|
|
41
43
|
const lexConfig = JSON.parse(process.env.LEX_CONFIG) || {};
|
|
42
44
|
const dirName = new URL('.', import.meta.url).pathname;
|
|
45
|
+
const require = createRequire(fileURLToPath(import.meta.url));
|
|
43
46
|
|
|
44
47
|
const {
|
|
45
48
|
isStatic,
|
|
@@ -100,6 +103,48 @@ const plugins = [
|
|
|
100
103
|
console.log('\x1b[32m[webpack]\x1b[0m Build complete. Watching for changes...');
|
|
101
104
|
}
|
|
102
105
|
});
|
|
106
|
+
compiler.hooks.normalModuleFactory.tap('ImportMetaTransform', (normalModuleFactory) => {
|
|
107
|
+
normalModuleFactory.hooks.parser.for('javascript/auto').tap('ImportMetaTransform', (parser) => {
|
|
108
|
+
parser.hooks.expression.for('import.meta').tap('ImportMetaTransform', (expr) => {
|
|
109
|
+
const dep = new webpack.dependencies.ConstDependency(
|
|
110
|
+
'({ url: typeof document !== "undefined" && document.currentScript && document.currentScript.src ? new URL(document.currentScript.src, window.location.href).href : (typeof window !== "undefined" ? new URL("", window.location.href).href : "") })',
|
|
111
|
+
expr.range
|
|
112
|
+
);
|
|
113
|
+
dep.loc = expr.loc;
|
|
114
|
+
parser.state.module.addPresentationalDependency(dep);
|
|
115
|
+
return true;
|
|
116
|
+
});
|
|
117
|
+
parser.hooks.expression.for('import.meta.url').tap('ImportMetaTransform', (expr) => {
|
|
118
|
+
const dep = new webpack.dependencies.ConstDependency(
|
|
119
|
+
'(typeof document !== "undefined" && document.currentScript && document.currentScript.src ? new URL(document.currentScript.src, window.location.href).href : (typeof window !== "undefined" ? new URL("", window.location.href).href : ""))',
|
|
120
|
+
expr.range
|
|
121
|
+
);
|
|
122
|
+
dep.loc = expr.loc;
|
|
123
|
+
parser.state.module.addPresentationalDependency(dep);
|
|
124
|
+
return true;
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
normalModuleFactory.hooks.parser.for('javascript/esm').tap('ImportMetaTransform', (parser) => {
|
|
128
|
+
parser.hooks.expression.for('import.meta').tap('ImportMetaTransform', (expr) => {
|
|
129
|
+
const dep = new webpack.dependencies.ConstDependency(
|
|
130
|
+
'({ url: typeof document !== "undefined" && document.currentScript && document.currentScript.src ? new URL(document.currentScript.src, window.location.href).href : (typeof window !== "undefined" ? new URL("", window.location.href).href : "") })',
|
|
131
|
+
expr.range
|
|
132
|
+
);
|
|
133
|
+
dep.loc = expr.loc;
|
|
134
|
+
parser.state.module.addPresentationalDependency(dep);
|
|
135
|
+
return true;
|
|
136
|
+
});
|
|
137
|
+
parser.hooks.expression.for('import.meta.url').tap('ImportMetaTransform', (expr) => {
|
|
138
|
+
const dep = new webpack.dependencies.ConstDependency(
|
|
139
|
+
'(typeof document !== "undefined" && document.currentScript && document.currentScript.src ? new URL(document.currentScript.src, window.location.href).href : (typeof window !== "undefined" ? new URL("", window.location.href).href : ""))',
|
|
140
|
+
expr.range
|
|
141
|
+
);
|
|
142
|
+
dep.loc = expr.loc;
|
|
143
|
+
parser.state.module.addPresentationalDependency(dep);
|
|
144
|
+
return true;
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
});
|
|
103
148
|
}
|
|
104
149
|
}
|
|
105
150
|
];
|
|
@@ -270,6 +315,8 @@ const alias = aliasKeys.reduce((aliases, key) => {
|
|
|
270
315
|
|
|
271
316
|
export default (webpackEnv, webpackOptions) => {
|
|
272
317
|
const {bundleAnalyzer, watch, entry: cliEntry, mode: cliMode, port} = webpackOptions;
|
|
318
|
+
const envPort = process.env.WEBPACK_DEV_PORT ? parseInt(process.env.WEBPACK_DEV_PORT, 10) : null;
|
|
319
|
+
const finalPort = port || envPort || 3000;
|
|
273
320
|
const entryValue = Array.isArray(cliEntry) ? cliEntry[0] : cliEntry;
|
|
274
321
|
|
|
275
322
|
// Debug printout for environment and mode
|
|
@@ -312,8 +359,42 @@ export default (webpackEnv, webpackOptions) => {
|
|
|
312
359
|
{
|
|
313
360
|
test: /\.js$/,
|
|
314
361
|
include: /node_modules/,
|
|
362
|
+
exclude: [
|
|
363
|
+
/[\\/]websocket\.js$/,
|
|
364
|
+
/[\\/]websocket.*\.js$/
|
|
365
|
+
],
|
|
315
366
|
type: 'javascript/auto'
|
|
316
367
|
},
|
|
368
|
+
{
|
|
369
|
+
test: /[\\/]websocket(.*)?\.js$/,
|
|
370
|
+
include: /node_modules/,
|
|
371
|
+
use: {
|
|
372
|
+
loader: swcLoaderPath,
|
|
373
|
+
options: {
|
|
374
|
+
jsc: {
|
|
375
|
+
parser: {
|
|
376
|
+
syntax: 'ecmascript',
|
|
377
|
+
dynamicImport: true,
|
|
378
|
+
importAssertions: true
|
|
379
|
+
},
|
|
380
|
+
target: 'es2020',
|
|
381
|
+
transform: {
|
|
382
|
+
legacyDecorator: false,
|
|
383
|
+
decoratorMetadata: false
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
module: {
|
|
387
|
+
type: 'es6',
|
|
388
|
+
strict: false,
|
|
389
|
+
strictMode: true,
|
|
390
|
+
lazy: false,
|
|
391
|
+
noInterop: true
|
|
392
|
+
},
|
|
393
|
+
minify: false,
|
|
394
|
+
sourceMaps: false
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
},
|
|
317
398
|
{
|
|
318
399
|
enforce: 'pre',
|
|
319
400
|
exclude: /(node_modules)/,
|
|
@@ -328,6 +409,7 @@ export default (webpackEnv, webpackOptions) => {
|
|
|
328
409
|
`${sourceFullPath}/**/*.test.ts*`
|
|
329
410
|
],
|
|
330
411
|
include: sourceFullPath,
|
|
412
|
+
type: 'javascript/esm',
|
|
331
413
|
loader: swcLoaderPath,
|
|
332
414
|
options: {
|
|
333
415
|
...LexConfig.config.swc,
|
|
@@ -335,8 +417,14 @@ export default (webpackEnv, webpackOptions) => {
|
|
|
335
417
|
...LexConfig.config.swc?.jsc,
|
|
336
418
|
parser: {
|
|
337
419
|
...LexConfig.config.swc?.jsc?.parser,
|
|
338
|
-
tsx: false
|
|
339
|
-
|
|
420
|
+
tsx: false,
|
|
421
|
+
dynamicImport: true
|
|
422
|
+
},
|
|
423
|
+
target: LexConfig.config.swc?.jsc?.target || 'es2020'
|
|
424
|
+
},
|
|
425
|
+
module: {
|
|
426
|
+
...LexConfig.config.swc?.module,
|
|
427
|
+
type: 'es6'
|
|
340
428
|
}
|
|
341
429
|
},
|
|
342
430
|
resolve: {
|
|
@@ -351,6 +439,7 @@ export default (webpackEnv, webpackOptions) => {
|
|
|
351
439
|
`${sourceFullPath}/**/*.test.ts*`
|
|
352
440
|
],
|
|
353
441
|
include: sourceFullPath,
|
|
442
|
+
type: 'javascript/esm',
|
|
354
443
|
loader: swcLoaderPath,
|
|
355
444
|
options: {
|
|
356
445
|
...LexConfig.config.swc,
|
|
@@ -543,7 +632,10 @@ export default (webpackEnv, webpackOptions) => {
|
|
|
543
632
|
library: libraryName,
|
|
544
633
|
libraryTarget,
|
|
545
634
|
path: outputFullPath,
|
|
546
|
-
publicPath: '/'
|
|
635
|
+
publicPath: '/',
|
|
636
|
+
environment: {
|
|
637
|
+
module: true
|
|
638
|
+
}
|
|
547
639
|
},
|
|
548
640
|
plugins,
|
|
549
641
|
recordsPath: relativeFilePath('webpack.records.json', process.cwd()),
|
|
@@ -620,7 +712,7 @@ export default (webpackEnv, webpackOptions) => {
|
|
|
620
712
|
}
|
|
621
713
|
},
|
|
622
714
|
{
|
|
623
|
-
from: /\\.(css|gif|ico|jpg|json|png|svg)$/,
|
|
715
|
+
from: /\\.(css|gif|ico|jpg|json|png|svg|txt)$/,
|
|
624
716
|
to: ({parsedUrl: {pathname}}) => pathname
|
|
625
717
|
}
|
|
626
718
|
],
|
|
@@ -628,17 +720,52 @@ export default (webpackEnv, webpackOptions) => {
|
|
|
628
720
|
},
|
|
629
721
|
hmr: false,
|
|
630
722
|
log: {level: 'trace'},
|
|
631
|
-
middleware: (app) =>
|
|
723
|
+
middleware: (app, builtins) => {
|
|
724
|
+
if(existsSync(staticPathFull)) {
|
|
725
|
+
if (process.env.LEX_CONFIG_DEBUG) {
|
|
726
|
+
console.log(`[LEX_DEBUG] Setting up static file serving from: ${staticPathFull}`);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
const koaStatic = require('koa-static');
|
|
730
|
+
|
|
731
|
+
app.use(koaStatic(staticPathFull, {
|
|
732
|
+
index: false, // Don't auto-serve index files
|
|
733
|
+
defer: false, // CRITICAL: Don't defer - serve immediately if file exists
|
|
734
|
+
hidden: false,
|
|
735
|
+
gzip: true,
|
|
736
|
+
br: false
|
|
737
|
+
}));
|
|
738
|
+
|
|
739
|
+
if (process.env.LEX_CONFIG_DEBUG) {
|
|
740
|
+
app.use(async (ctx, next) => {
|
|
741
|
+
const path = ctx.path || ctx.url || '';
|
|
742
|
+
if (path && !path.match(/^\/wps/) && !path.match(/^\/webpack/)) {
|
|
743
|
+
console.log(`[LEX_DEBUG] Request: ${path}`);
|
|
744
|
+
}
|
|
745
|
+
await next();
|
|
746
|
+
if (ctx.status === 404 && path && path.includes('.')) {
|
|
747
|
+
console.log(`[LEX_DEBUG] 404 for: ${path}, body set: ${ctx.body !== undefined}`);
|
|
748
|
+
}
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
} else {
|
|
752
|
+
if (process.env.LEX_CONFIG_DEBUG) {
|
|
753
|
+
console.log(`[LEX_DEBUG] Static path does not exist: ${staticPathFull}`);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
632
757
|
app.use(async (ctx, next) => {
|
|
633
|
-
|
|
758
|
+
const path = ctx.path || ctx.url || (ctx.request && ctx.request.path) || '';
|
|
759
|
+
if(path && path.match(/^\/wps/)) {
|
|
634
760
|
const {accept, Accept, ...remainingHeaders} =
|
|
635
761
|
ctx.request.header;
|
|
636
762
|
ctx.request.header = remainingHeaders;
|
|
637
763
|
}
|
|
638
764
|
await next();
|
|
639
|
-
})
|
|
765
|
+
});
|
|
766
|
+
},
|
|
640
767
|
open: process.env.WEBPACK_DEV_OPEN === 'true',
|
|
641
|
-
port:
|
|
768
|
+
port: finalPort,
|
|
642
769
|
progress: 'minimal',
|
|
643
770
|
static: existsSync(outputFullPath) ? [outputFullPath] : [],
|
|
644
771
|
status: true
|