Skip to content

Commit 5673590

Browse files
committed
fixing auto imports
1 parent 1a574be commit 5673590

18 files changed

Lines changed: 537 additions & 275 deletions

build/vite-plugin-openscript.js

Lines changed: 187 additions & 239 deletions
Large diffs are not rendered by default.

docs/COMPONENT_AUTO_IMPORT.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# OpenScript Component Auto-Import System
2+
3+
## How to Use (For Developers)
4+
5+
### 1. Install OpenScript
6+
7+
```bash
8+
npm install modular-openscriptjs
9+
```
10+
11+
### 2. Configure Vite
12+
13+
```javascript
14+
// vite.config.js
15+
import { defineConfig } from "vite";
16+
import { openScriptComponentPlugin } from "modular-openscriptjs/plugin";
17+
18+
export default defineConfig({
19+
plugins: [
20+
openScriptComponentPlugin({
21+
componentsDir: "src/components", // default
22+
autoRegister: true, // auto-register components
23+
generateTypes: true, // generate .d.ts for IDE
24+
}),
25+
],
26+
});
27+
```
28+
29+
### 3. Create Components
30+
31+
```javascript
32+
// src/components/TodoList.js
33+
import { Component, app, state } from "modular-openscriptjs";
34+
35+
const h = app("h");
36+
37+
export default class TodoList extends Component {
38+
constructor() {
39+
super();
40+
this.todos = state([]);
41+
}
42+
43+
render() {
44+
return h.div(
45+
h.h2("My Todos"),
46+
h.ul(...this.todos.value.map((todo) => h.li(todo.text)))
47+
);
48+
}
49+
}
50+
```
51+
52+
### 4. Use Components with Auto-Import
53+
54+
```javascript
55+
// src/main.js
56+
import { app } from "modular-openscriptjs";
57+
import "virtual:openscript-components"; // Auto-imports all components
58+
59+
const h = app("h");
60+
61+
// IDE will autocomplete ComponentName!
62+
// Component is automatically imported and bundled by Vite!
63+
h.TodoList({ parent: document.body });
64+
```
65+
66+
## Features
67+
68+
**IDE Autocomplete**: Type `h.` and see all your components
69+
**Auto-Import**: No need to manually import components
70+
**TypeScript Support**: Generated `.d.ts` files
71+
**HMR Support**: Hot module replacement during development
72+
**Automatic Bundling**: Vite includes all components in bundle
73+
**Nested Components**: Supports subdirectories in components/
74+
75+
## How It Works
76+
77+
1. **Component Discovery**: Plugin scans `src/components/` for all Component files
78+
2. **Type Generation**: Creates `openscript-components.d.ts` with type definitions
79+
3. **Virtual Module**: Creates a virtual module that imports all components
80+
4. **Auto-Registration**: Optionally auto-registers all components on app start
81+
5. **IDE Support**: TypeScript definitions provide autocomplete and type checking
82+
83+
## Advanced Usage
84+
85+
### Manual Component Registration
86+
87+
```javascript
88+
// vite.config.js
89+
openScriptComponentPlugin({
90+
autoRegister: false, // Disable auto-registration
91+
});
92+
```
93+
94+
```javascript
95+
// src/main.js
96+
import components, {
97+
registerAllComponents,
98+
} from "virtual:openscript-components";
99+
100+
// Manually register when needed
101+
await registerAllComponents();
102+
103+
// Or register individually
104+
const todoList = new components.TodoList();
105+
await todoList.mount();
106+
```
107+
108+
### Custom Components Directory
109+
110+
```javascript
111+
openScriptComponentPlugin({
112+
componentsDir: "src/ui/components",
113+
});
114+
```
115+
116+
### Exclude Components from Auto-Discovery
117+
118+
Name files with lowercase or prefix with underscore:
119+
120+
- `utils.js` ❌ (lowercase, won't be discovered)
121+
- `_BaseComponent.js` ❌ (underscore prefix, won't be discovered)
122+
- `TodoList.js` ✅ (PascalCase, will be discovered)
123+
124+
## TypeScript Example
125+
126+
```typescript
127+
// src/main.ts
128+
import { app } from "modular-openscriptjs";
129+
import "virtual:openscript-components";
130+
131+
const h = app("h");
132+
133+
// Full type safety!
134+
h.TodoList({
135+
parent: document.body,
136+
resetParent: true,
137+
});
138+
```
139+
140+
## Comparison with JSX
141+
142+
**JSX/React:**
143+
144+
```jsx
145+
import TodoList from "./components/TodoList";
146+
<TodoList />;
147+
```
148+
149+
**OpenScript (with plugin):**
150+
151+
```javascript
152+
import "virtual:openscript-components";
153+
h.TodoList();
154+
```
155+
156+
Both provide:
157+
158+
- ✅ IDE autocomplete
159+
- ✅ Type checking
160+
- ✅ Proper bundling
161+
- ✅ HMR support
162+
163+
## Migration from Manual Imports
164+
165+
**Before:**
166+
167+
```javascript
168+
import TodoList from "./components/TodoList";
169+
import Header from "./components/Header";
170+
171+
const todoList = new TodoList();
172+
await todoList.mount();
173+
h.TodoList({ parent: document.body });
174+
```
175+
176+
**After:**
177+
178+
```javascript
179+
import "virtual:openscript-components";
180+
181+
// Components auto-registered and available on h!
182+
h.TodoList({ parent: document.body });
183+
h.Header({ parent: document.body });
184+
```
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## Component Auto-Import Feature
2+
3+
OpenScript provides automatic component discovery and import, similar to JSX, giving you IDE autocomplete and ensuring all components are properly bundled.
4+
5+
### Setup
6+
7+
```javascript
8+
// vite.config.js
9+
import { openScriptComponentPlugin } from "modular-openscriptjs/plugin";
10+
11+
export default {
12+
plugins: [openScriptComponentPlugin()],
13+
};
14+
```
15+
16+
### Usage
17+
18+
```javascript
19+
// src/main.js
20+
import { app } from "modular-openscriptjs";
21+
import "virtual:openscript-components"; // Auto-imports all components!
22+
23+
const h = app("h");
24+
25+
// IDE will autocomplete component names!
26+
// Components are automatically imported and bundled!
27+
h.TodoList({ parent: document.body });
28+
h.Header({ parent: document.body });
29+
```
30+
31+
**Benefits:**
32+
33+
- ✅ IDE autocomplete for `h.ComponentName`
34+
- ✅ Automatic component imports (no manual imports needed)
35+
- ✅ TypeScript support with generated `.d.ts` files
36+
- ✅ Proper Vite bundling
37+
- ✅ Hot Module Replacement (HMR)
38+
39+
See [Component Auto-Import Guide](./docs/COMPONENT_AUTO_IMPORT.md) for details.

examples/vite.config.example.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Example vite.config.js for OpenScript projects
2+
import { defineConfig } from "vite";
3+
import { openScriptComponentPlugin } from "modular-openscriptjs/plugin";
4+
5+
export default defineConfig({
6+
plugins: [
7+
openScriptComponentPlugin({
8+
// Directory where your components are located
9+
componentsDir: "src/components",
10+
11+
// Auto-register all components on app start
12+
// Set to false if you want manual control
13+
autoRegister: true,
14+
15+
// Generate TypeScript definitions for IDE autocomplete
16+
// Creates src/openscript-components.d.ts
17+
generateTypes: true,
18+
}),
19+
],
20+
21+
build: {
22+
target: "es2015",
23+
},
24+
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "modular-openscriptjs",
3-
"version": "1.0.5",
3+
"version": "1.0.5.1",
44
"description": "OpenScriptJs Framework - A lightweight, reactive JavaScript framework for building modern web applications",
55
"type": "module",
66
"main": "./dist/modular-openscriptjs.umd.js",

src/component/Component.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import BrokerRegistrar from "../broker/BrokerRegistrar.js";
44
import State from "../core/State.js";
55
import { container } from "../core/Container.js";
66

7-
const h = container.resolve("h");
8-
97
/**
108
* Base Component Class
119
*/
@@ -113,6 +111,7 @@ export default class Component {
113111
routeChanged: () => {
114112
setTimeout(() => {
115113
if (this.markup().length == 0) {
114+
const h = container.resolve("h");
116115
if (this.isAnonymous) {
117116
return h.deleteComponent(this.name);
118117
}
@@ -146,6 +145,7 @@ export default class Component {
146145
if (!Array.isArray(args)) {
147146
args = [args];
148147
}
148+
const h = container.resolve("h");
149149
return h.func([this, name], ...args);
150150
}
151151

@@ -167,6 +167,7 @@ export default class Component {
167167
);
168168
}
169169

170+
const h = container.resolve("h");
170171
return h.getComponent(splitted[0]).method(splitted[1], args);
171172
}
172173

@@ -255,6 +256,7 @@ export default class Component {
255256
getDeclaredListeners() {
256257
let obj = this;
257258
let seen = new Set();
259+
const h = container.resolve("h");
258260

259261
do {
260262
if (!(obj instanceof Component)) break;
@@ -343,7 +345,7 @@ export default class Component {
343345
);
344346
return;
345347
}
346-
348+
const h = container.resolve("h");
347349
h.component(this.name, this);
348350

349351
this.claimListeners();
@@ -376,6 +378,7 @@ export default class Component {
376378
* visible
377379
*/
378380
checkVisibility() {
381+
const h = container.resolve("h");
379382
let elem = h.dom.querySelector(`ojs-${this.kebab(this.name)}`);
380383

381384
if (elem && elem.parentElement?.style.display !== "none" && !this.visible) {
@@ -422,7 +425,7 @@ export default class Component {
422425
*/
423426
async bindComponent() {
424427
this.emit(this.EVENTS.prebind);
425-
428+
const h = container.resolve("h");
426429
let all = h.dom.querySelectorAll(`ojs-${this.kebab(this.name)}-tmp--`);
427430

428431
if (all.length == 0 && !this.bindCalled) {
@@ -469,6 +472,7 @@ export default class Component {
469472
* @returns
470473
*/
471474
markup(parent = null) {
475+
const h = container.resolve("h");
472476
if (!parent) parent = h.dom;
473477

474478
return parent.querySelectorAll(`ojs-${this.kebab(this.name)}`);
@@ -550,6 +554,7 @@ export default class Component {
550554
* Gets all the listeners for itself and adds them to itself
551555
*/
552556
claimListeners() {
557+
const h = container.resolve("h");
553558
if (!h.eventsMap.has(this.name)) return;
554559

555560
let events = h.eventsMap.get(this.name);
@@ -596,6 +601,7 @@ export default class Component {
596601
* @returns {DocumentFragment|HTMLElement|String|Array<DocumentFragment|HTMLElement|String>}
597602
*/
598603
render(...args) {
604+
const h = container.resolve("h");
599605
return h.ojs(...args);
600606
}
601607

@@ -671,6 +677,7 @@ export default class Component {
671677
* @returns
672678
*/
673679
wrap(...args) {
680+
const h = container.resolve("h");
674681
const lastArg = args[args.length - 1];
675682
let { index, parent, resetParent, states, replaceParent, firstOfParent } =
676683
this.getParentAndListen(args);

src/component/MarkupEngine.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import DOMReconciler from "./DOMReconciler.js";
22
import Utils from "../utils/Utils.js";
3-
import { h } from "./h.js"; // Circular dependency? h is used in MarkupEngine
43
import Component from "./Component.js";
54
import State from "../core/State.js";
5+
import { container } from "../core/Container.js";
66

77
/**
88
* Base Markup Engine Class
@@ -494,6 +494,7 @@ export default class MarkupEngine {
494494
sc.forEach((c) => {
495495
if (!isComponentName(c.tagName.toLowerCase())) return;
496496
let cmpName = getComponentName(c.tagName);
497+
const h = container.resolve("h");
497498
h.getComponent(cmpName)?.emit(event, eventParams);
498499
});
499500
}

src/component/h.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)