@shellui/cli 0.0.1
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 +80 -0
- package/bin/shellui.js +4 -0
- package/package.json +39 -0
- package/src/app.jsx +31 -0
- package/src/cli.js +127 -0
- package/src/index.html +12 -0
package/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# ShellUI
|
|
2
|
+
|
|
3
|
+
> A lightweight microfrontend shell to ship apps faster.
|
|
4
|
+
|
|
5
|
+
ShellUI is a CLI tool that spins up a React-based microfrontend shell. It is powered by Vite and designed to be easily configurable.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🚀 **Fast**: Built on top of Vite for instant server start.
|
|
10
|
+
- ⚛️ **React-based**: The shell is a React application.
|
|
11
|
+
- ⚙️ **Configurable**: Loads configuration from `shellui.json` in your project root.
|
|
12
|
+
- 🔌 **Injectable Config**: Configuration is automatically injected into the shell application.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
Install ShellUI globally or locally:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g shellui
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or install it as a dev dependency in your project:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install --save-dev shellui
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
After installation, you can use the `shellui` command directly:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx shellui start [path/to/project]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or if installed globally:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
shellui start [path/to/project]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
You can also use it via npm scripts in your `package.json`:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"scripts": {
|
|
47
|
+
"start": "shellui start",
|
|
48
|
+
"build": "shellui build"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
By default, it looks for configuration in the current directory.
|
|
54
|
+
|
|
55
|
+
## Configuration
|
|
56
|
+
|
|
57
|
+
ShellUI looks for a `shellui.json` file in your project root.
|
|
58
|
+
|
|
59
|
+
**Example `shellui.json`:**
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"port": 4000
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
- **port**: The port number to start the server on (default: `3000`).
|
|
68
|
+
|
|
69
|
+
## Development
|
|
70
|
+
|
|
71
|
+
This repository contains the core logic for the shell.
|
|
72
|
+
|
|
73
|
+
- `bin/shellui.js`: The CLI entry point.
|
|
74
|
+
- `src/cli.js`: Main CLI logic using `cac` and `vite`.
|
|
75
|
+
- `src/app.jsx`: The shell's React application entry point.
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
MIT
|
|
80
|
+
|
package/bin/shellui.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shellui/cli",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "ShellUI - a lightweight microfrontend shell to ship apps faster",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"shellui": "./bin/shellui.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin",
|
|
12
|
+
"src",
|
|
13
|
+
"README.md",
|
|
14
|
+
"package.json"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"start": "node bin/shellui.js start",
|
|
18
|
+
"build": "node bin/shellui.js build",
|
|
19
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"microfrontend",
|
|
23
|
+
"shell",
|
|
24
|
+
"cli",
|
|
25
|
+
"vite",
|
|
26
|
+
"react",
|
|
27
|
+
"frontend"
|
|
28
|
+
],
|
|
29
|
+
"author": "ShellUI",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
33
|
+
"cac": "^6.7.14",
|
|
34
|
+
"picocolors": "^1.1.1",
|
|
35
|
+
"react": "^19.2.3",
|
|
36
|
+
"react-dom": "^19.2.3",
|
|
37
|
+
"vite": "^7.3.0"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/src/app.jsx
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom/client';
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
// __SHELLUI_CONFIG__ is replaced by Vite at build time
|
|
6
|
+
const config = typeof __SHELLUI_CONFIG__ !== 'undefined' ? __SHELLUI_CONFIG__ : {};
|
|
7
|
+
|
|
8
|
+
return (
|
|
9
|
+
<div style={{ fontFamily: 'system-ui, sans-serif', padding: '2rem' }}>
|
|
10
|
+
<h1>ShellUI</h1>
|
|
11
|
+
<p>Welcome to ShellUI</p>
|
|
12
|
+
|
|
13
|
+
<div style={{
|
|
14
|
+
marginTop: '2rem',
|
|
15
|
+
padding: '1rem',
|
|
16
|
+
background: '#f5f5f5',
|
|
17
|
+
borderRadius: '8px'
|
|
18
|
+
}}>
|
|
19
|
+
<h2>Configuration</h2>
|
|
20
|
+
<pre>{JSON.stringify(config, null, 2)}</pre>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
ReactDOM.createRoot(document.getElementById('root')).render(
|
|
27
|
+
<React.StrictMode>
|
|
28
|
+
<App />
|
|
29
|
+
</React.StrictMode>
|
|
30
|
+
);
|
|
31
|
+
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { cac } from 'cac';
|
|
2
|
+
import { createServer, build } from 'vite';
|
|
3
|
+
import react from '@vitejs/plugin-react';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import pc from 'picocolors';
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const cli = cac('shellui');
|
|
11
|
+
|
|
12
|
+
cli
|
|
13
|
+
.command('start [root]', 'Start the shellui server')
|
|
14
|
+
.action(async (root = '.') => {
|
|
15
|
+
const cwd = process.cwd();
|
|
16
|
+
const configDir = path.resolve(cwd, root);
|
|
17
|
+
const configPath = path.join(configDir, 'shellui.json');
|
|
18
|
+
const legacyConfigPath = path.join(configDir, 'shellioj.json');
|
|
19
|
+
|
|
20
|
+
console.log(pc.blue(`Starting ShellUI...`));
|
|
21
|
+
|
|
22
|
+
let config = {};
|
|
23
|
+
let activeConfigPath = null;
|
|
24
|
+
|
|
25
|
+
if (fs.existsSync(configPath)) {
|
|
26
|
+
activeConfigPath = configPath;
|
|
27
|
+
} else if (fs.existsSync(legacyConfigPath)) {
|
|
28
|
+
activeConfigPath = legacyConfigPath;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (activeConfigPath) {
|
|
32
|
+
try {
|
|
33
|
+
const configFile = fs.readFileSync(activeConfigPath, 'utf-8');
|
|
34
|
+
config = JSON.parse(configFile);
|
|
35
|
+
console.log(pc.green(`Loaded config from ${activeConfigPath}`));
|
|
36
|
+
} catch (e) {
|
|
37
|
+
console.error(pc.red(`Failed to load config: ${e.message}`));
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
console.log(pc.yellow(`No shellui.json (or shellioj.json) found, using defaults.`));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Path to the index.html inside the package
|
|
44
|
+
const packageRoot = path.resolve(__dirname, '..');
|
|
45
|
+
const templateRoot = path.join(__dirname); // src folder
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const server = await createServer({
|
|
49
|
+
root: templateRoot, // Serve from src/ where index.html is
|
|
50
|
+
plugins: [react()],
|
|
51
|
+
define: {
|
|
52
|
+
'__SHELLUI_CONFIG__': JSON.stringify(config),
|
|
53
|
+
},
|
|
54
|
+
server: {
|
|
55
|
+
port: config.port || 3000,
|
|
56
|
+
open: true,
|
|
57
|
+
fs: {
|
|
58
|
+
allow: [packageRoot, cwd]
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
await server.listen();
|
|
64
|
+
server.printUrls();
|
|
65
|
+
} catch (e) {
|
|
66
|
+
console.error(pc.red(`Error starting server: ${e.message}`));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
cli
|
|
72
|
+
.command('build [root]', 'Build the shellui application')
|
|
73
|
+
.action(async (root = '.') => {
|
|
74
|
+
const cwd = process.cwd();
|
|
75
|
+
const configDir = path.resolve(cwd, root);
|
|
76
|
+
const configPath = path.join(configDir, 'shellui.json');
|
|
77
|
+
const legacyConfigPath = path.join(configDir, 'shellioj.json');
|
|
78
|
+
|
|
79
|
+
console.log(pc.blue(`Building ShellUI...`));
|
|
80
|
+
|
|
81
|
+
let config = {};
|
|
82
|
+
let activeConfigPath = null;
|
|
83
|
+
|
|
84
|
+
if (fs.existsSync(configPath)) {
|
|
85
|
+
activeConfigPath = configPath;
|
|
86
|
+
} else if (fs.existsSync(legacyConfigPath)) {
|
|
87
|
+
activeConfigPath = legacyConfigPath;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (activeConfigPath) {
|
|
91
|
+
try {
|
|
92
|
+
const configFile = fs.readFileSync(activeConfigPath, 'utf-8');
|
|
93
|
+
config = JSON.parse(configFile);
|
|
94
|
+
console.log(pc.green(`Loaded config from ${activeConfigPath}`));
|
|
95
|
+
} catch (e) {
|
|
96
|
+
console.error(pc.red(`Failed to load config: ${e.message}`));
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
console.log(pc.yellow(`No shellui.json (or shellioj.json) found, using defaults.`));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Path to the index.html inside the package
|
|
103
|
+
const templateRoot = path.join(__dirname); // src folder
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
await build({
|
|
107
|
+
root: templateRoot, // Serve from src/ where index.html is
|
|
108
|
+
plugins: [react()],
|
|
109
|
+
define: {
|
|
110
|
+
'__SHELLUI_CONFIG__': JSON.stringify(config),
|
|
111
|
+
},
|
|
112
|
+
build: {
|
|
113
|
+
outDir: path.resolve(cwd, 'dist'),
|
|
114
|
+
emptyOutDir: true,
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
console.log(pc.green('Build complete!'));
|
|
118
|
+
} catch (e) {
|
|
119
|
+
console.error(pc.red(`Error building: ${e.message}`));
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
cli.help();
|
|
125
|
+
cli.version('0.0.1');
|
|
126
|
+
cli.parse();
|
|
127
|
+
|
package/src/index.html
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>ShellUI</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/app.jsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|