@shellui/cli 0.0.9 → 0.0.11

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shellui/cli",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "description": "ShellUI CLI - Command-line tool for ShellUI",
5
5
  "main": "src/cli.js",
6
6
  "type": "module",
@@ -30,7 +30,7 @@
30
30
  "tsx": "^4.21.0",
31
31
  "vite": "7.3.1",
32
32
  "workbox-build": "^7.1.0",
33
- "@shellui/core": "0.0.9"
33
+ "@shellui/core": "0.0.11"
34
34
  },
35
35
  "publishConfig": {
36
36
  "access": "public"
@@ -84,7 +84,8 @@ export async function buildCommand(root = '.') {
84
84
  // Build main app
85
85
  await build({
86
86
  root: coreSrcPath,
87
- plugins: [react(), inlineLazyImportsPlugin()],
87
+ // Order matters: inlineLazyImportsPlugin must run before react() to transform lazy imports early
88
+ plugins: [inlineLazyImportsPlugin(), react()],
88
89
  define: createViteDefine(config),
89
90
  resolve: {
90
91
  alias: resolveAlias,
@@ -40,7 +40,12 @@ async function startServer(root, cwd, shouldOpen = false) {
40
40
 
41
41
  const server = await createServer({
42
42
  root: coreSrcPath,
43
- plugins: [react(), inlineLazyImportsPlugin(), serviceWorkerDevPlugin(corePackagePath, coreSrcPath)],
43
+ // Order matters: inlineLazyImportsPlugin must run before react() to transform lazy imports early
44
+ plugins: [
45
+ inlineLazyImportsPlugin(),
46
+ react(),
47
+ serviceWorkerDevPlugin(corePackagePath, coreSrcPath),
48
+ ],
44
49
  define: createViteDefine(config),
45
50
  resolve: {
46
51
  alias: createResolveAlias(),
@@ -54,6 +59,12 @@ async function startServer(root, cwd, shouldOpen = false) {
54
59
  esbuild: {
55
60
  sourcemap: false,
56
61
  },
62
+ // Prevent Vite from pre-bundling @shellui/core when it's in node_modules
63
+ // We want our transform plugin to handle lazy imports, not esbuild's pre-bundler
64
+ // This ensures consistent behavior between workspace and npm-installed packages
65
+ optimizeDeps: {
66
+ exclude: ['@shellui/core'],
67
+ },
57
68
  server: {
58
69
  port: config.port || 3000,
59
70
  open: shouldOpen,
@@ -2,21 +2,35 @@
2
2
  * Plugin that converts lazy(() => import(...)) to direct imports.
3
3
  * This prevents Rollup/Vite from creating code-split chunks, ensuring all rendering
4
4
  * goes through App.tsx where ConfigProvider wraps everything.
5
- *
5
+ *
6
6
  * This is critical: when the library is consumed via npm, Vite processes the source files.
7
7
  * If there are dynamic imports, it creates separate chunks that load separately, causing
8
8
  * duplicate module instances and breaking React context (ConfigContext, SettingsContext, etc.).
9
- *
9
+ *
10
10
  * @returns {import('vite').Plugin} Vite plugin
11
11
  */
12
12
  export function inlineLazyImportsPlugin() {
13
13
  return {
14
14
  name: 'inline-lazy-imports',
15
+ // Run before other transforms to ensure lazy imports are inlined early
16
+ enforce: 'pre',
15
17
  // Apply to both dev and build modes
16
18
  transform(code, id) {
17
- // Only transform source files, not node_modules (except our own src)
18
- // Match paths that contain /src/ but exclude node_modules that aren't @shellui/core/src
19
- if (!id.includes('/src/') || (id.includes('node_modules') && !id.includes('@shellui/core/src'))) {
19
+ // Only transform source files from @shellui/core
20
+ // Match paths that contain @shellui/core/src (works for both workspace and npm-installed)
21
+ // Also match router/routes files specifically since those contain the lazy imports
22
+ const isCoreSrc =
23
+ id.includes('@shellui/core/src') ||
24
+ id.includes('@shellui/core\\src') || // Windows paths
25
+ (id.includes('/src/') && id.match(/router[/\\]routes\.tsx?$/)) ||
26
+ (id.includes('/src/') && id.match(/router[/\\]router\.tsx?$/));
27
+
28
+ // Debug logging (remove after fixing)
29
+ if (id.includes('routes') && code.includes('lazy')) {
30
+ console.log(`[inline-lazy-imports] Processing: ${id}, isCoreSrc: ${isCoreSrc}`);
31
+ }
32
+
33
+ if (!isCoreSrc) {
20
34
  return null;
21
35
  }
22
36
 
@@ -28,20 +42,38 @@ export function inlineLazyImportsPlugin() {
28
42
  let hasChanges = false;
29
43
 
30
44
  // Match the exact pattern: const Name = lazy(() => import('path').then((m) => ({ default: m.Name })),);
31
- // Handles both single-line and multiline patterns
32
- // The regex captures: const declaration, lazy call, import path, component name, and trailing punctuation
33
- const lazyPattern = /const\s+(\w+)\s*=\s*lazy\s*\(\s*\(\)\s*=>\s*[\s\n]*import\s*\((['"])([^'"]+)\2\)\s*\.then\s*\([\s\S]*?\(?\s*m\s*\)?\s*=>\s*\([\s\S]*?\{\s*default:\s*m\.(\w+)\s*\}[\s\S]*?\)[\s\S]*?\)[\s\n]*\)[\s\n]*,?[\s\n]*;?/g;
45
+ // Strategy: Match the structure step by step, using non-greedy matching to stop at boundaries
46
+ // 1. Match: const Name = lazy(() =>
47
+ // 2. Match: import('path')
48
+ // 3. Match: .then((m) => ({ default: m.Name }))
49
+ // 4. Match: ,); or ); on new line
50
+ const lazyPattern =
51
+ /const\s+(\w+)\s*=\s*lazy\s*\(\s*\(\)\s*=>\s*[\s\n]*import\s*\((['"])([^'"]+)\2\)\s*\.then\s*\([\s\S]*?\(?\s*m\s*\)?\s*=>\s*\([\s\S]*?\{\s*default:\s*m\.(\w+)\s*\}[\s\S]*?\)[\s\S]*?\)\s*,?\s*[\s\n]*\)\s*;?\s*/g;
52
+
53
+ transformed = transformed.replace(
54
+ lazyPattern,
55
+ (fullMatch, varName, quote, importPath, componentName) => {
56
+ hasChanges = true;
57
+
58
+ // Debug: log what we're matching
59
+ if (id.includes('routes')) {
60
+ console.log(
61
+ `[inline-lazy-imports] Matched ${varName}:`,
62
+ fullMatch.replace(/\n/g, '\\n').substring(0, 150),
63
+ );
64
+ console.log(`[inline-lazy-imports] - importPath: ${importPath}`);
65
+ console.log(`[inline-lazy-imports] - componentName: ${componentName}`);
66
+ }
34
67
 
35
- transformed = transformed.replace(lazyPattern, (fullMatch, varName, quote, importPath, componentName) => {
36
- hasChanges = true;
37
- // Import with the same name as the variable (they match in the source code)
38
- const importStatement = `import { ${componentName} as ${varName} } from ${quote}${importPath}${quote};`;
39
- if (!imports.some(imp => imp.includes(`${varName}`))) {
40
- imports.push(importStatement);
41
- }
42
- // Remove the entire const declaration - the import statement replaces it
43
- return '';
44
- });
68
+ // Import with the same name as the variable (they match in the source code)
69
+ const importStatement = `import { ${componentName} as ${varName} } from ${quote}${importPath}${quote};`;
70
+ if (!imports.some((imp) => imp.includes(`${varName}`))) {
71
+ imports.push(importStatement);
72
+ }
73
+ // Remove the entire const declaration - return empty string to completely remove it
74
+ return '';
75
+ },
76
+ );
45
77
 
46
78
  if (!hasChanges || imports.length === 0) return null;
47
79
 
@@ -49,9 +81,15 @@ export function inlineLazyImportsPlugin() {
49
81
  // Find the last import statement
50
82
  const lastImportMatch = transformed.match(/^import\s+.*$/gm);
51
83
  if (lastImportMatch) {
52
- const lastImportIndex = transformed.lastIndexOf(lastImportMatch[lastImportMatch.length - 1]);
84
+ const lastImportIndex = transformed.lastIndexOf(
85
+ lastImportMatch[lastImportMatch.length - 1],
86
+ );
53
87
  const insertIndex = transformed.indexOf('\n', lastImportIndex) + 1;
54
- transformed = transformed.slice(0, insertIndex) + imports.join('\n') + '\n' + transformed.slice(insertIndex);
88
+ transformed =
89
+ transformed.slice(0, insertIndex) +
90
+ imports.join('\n') +
91
+ '\n' +
92
+ transformed.slice(insertIndex);
55
93
  } else {
56
94
  // No imports found, add at the top
57
95
  transformed = imports.join('\n') + '\n' + transformed;