lilact 0.7.12 → 0.8.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 +146 -83
- package/bin/bundle.cjs +122 -0
- package/bin/bundle.js +118 -0
- package/dist/lilact.development.js +220 -4
- package/dist/lilact.development.js.map +1 -1
- package/dist/lilact.development.min.js +2 -2
- package/dist/lilact.development.min.js.map +1 -1
- package/dist/lilact.production.min.js +1 -1
- package/dist/lilact.production.min.js.map +1 -1
- package/docs/assets/highlight.css +39 -25
- package/docs/classes/components.HTMLComponent.html +1 -1
- package/docs/classes/components.RootComponent.html +1 -1
- package/docs/functions/accessories.Spinner.html +2 -2
- package/docs/functions/redux.Provider.html +2 -2
- package/docs/functions/redux.connect.html +2 -2
- package/docs/functions/router.HashRouter.html +2 -2
- package/docs/functions/router.Link.html +2 -2
- package/docs/functions/router.NavLink.html +2 -2
- package/docs/functions/router.Routes.html +2 -2
- package/docs/functions/run.lazy.html +2 -2
- package/docs/functions/transition.CSSTransition.html +2 -2
- package/docs/index.html +95 -88
- package/docs/static/lilact.development.js +220 -4
- package/docs/static/lilact.development.min.js +2 -2
- package/docs/static/lilact.production.min.js +1 -1
- package/docs/variables/pane.ResizablePane.html +1 -1
- package/package.json +9 -4
- package/root/lilact.development.js +220 -4
- package/root/lilact.development.min.js +2 -2
- package/root/lilact.production.min.js +1 -1
- package/src/lilact.jsx +20 -7
- package/webpack.config.factory.cjs +124 -0
- package/webpack.config.js +32 -16
package/README.md
CHANGED
|
@@ -2,129 +2,192 @@
|
|
|
2
2
|
|
|
3
3
|
# Lilact
|
|
4
4
|
|
|
5
|
-
### A Little React/JSX Runtime Implementation for Browser
|
|
5
|
+
### A Little React/JSX Runtime Implementation for the Browser
|
|
6
6
|
|
|
7
|
-
[Docs on GitHub Pages](
|
|
7
|
+
[Docs on GitHub Pages](arashkazemi.github.io/lilact/) — [Demos on GitHub Pages](arashkazemi.github.io/lilact/static)
|
|
8
8
|
|
|
9
|
-
[Lilact repo on GitHub](
|
|
9
|
+
[Lilact repo on GitHub](github.com/arashkazemi/lilact) — [Lilact on npm](www.npmjs.com/package/lilact)
|
|
10
10
|
|
|
11
|
-
[Lilact/PHP Demo](
|
|
11
|
+
[Lilact/Node/Express Demo Project](github.com/arashkazemi/lilact-express) — [Lilact/PHP Demo Project](github.com/arashkazemi/lilact-php-demo) — [Lilact/Python Demo Project](github.com/arashkazemi/lilact-python-demo)
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
If you find Lilact useful, please consider sponsoring. Your support funds ongoing maintenance,
|
|
16
|
-
|
|
15
|
+
If you find Lilact useful, please consider sponsoring. Your support funds ongoing maintenance, performance improvements, and new features.
|
|
16
|
+
[Sponsor me on GitHub](github.com/sponsors/arashkazemi)
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
designed to work in the browser. It can be used as a single script
|
|
22
|
-
that is around `80kb` minified and around `27kb` gzipped and includes its whole api.
|
|
23
|
-
`Lilact` is very fast, it uses minimal resources and handles memory very efficiently.
|
|
20
|
+
## Overview
|
|
24
21
|
|
|
25
|
-
`Lilact`
|
|
26
|
-
essentially work with any kind of web server/back-end. An example of using it with a PHP/MySQL
|
|
27
|
-
data store is available on [lilact-php-demo](https://github.com/arashkazemi/lilact-php-demo).
|
|
28
|
-
And an example of using it with a Python/SQLite data store is available on
|
|
29
|
-
[lilact-python-demo](https://github.com/arashkazemi/lilact-python-demo).
|
|
22
|
+
`Lilact` is a very lightweight implementation of the React API designed to run in the browser. It can be used as a single script that is around `80kb` minified and around `27kb` gzipped, and includes its whole API.
|
|
30
23
|
|
|
31
|
-
`Lilact`
|
|
32
|
-
parser with lookahead, that doesn't parse the JS syntax completely and relies on the
|
|
33
|
-
JS runtime to detect some errors. The transpiler weights only a few kilobytes and can
|
|
34
|
-
be incorporated into other React engines too. It even generates sourcemaps without relying
|
|
35
|
-
on any 3rd party library. There is a `transpile.js` helper in the bin directory to show
|
|
36
|
-
how you can use it.
|
|
24
|
+
`Lilact` is very fast, uses minimal resources, and handles memory very efficiently.
|
|
37
25
|
|
|
38
|
-
`Lilact`
|
|
39
|
-
has almost everything necessary. In addition to the API, it also includes the official
|
|
40
|
-
`Redux` and `PropTypes` libraries to be used (see the `redux.jsx` and `proptypes.jsx` demos).
|
|
41
|
-
So it has redux support and has many of the functions and hooks, i.e. `connect` and
|
|
42
|
-
`useDispatch`.
|
|
26
|
+
In a Node.js environment, `Lilact` can be incorporated and imported similarly to React, and it can also be used as a static library in other platforms.
|
|
43
27
|
|
|
44
|
-
|
|
45
|
-
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## JSX Transpiler
|
|
31
|
+
|
|
32
|
+
`Lilact` uses its own JSX transpiler (not Babel). It is a recursive-descent parser with lookahead. It doesn’t parse the full JavaScript syntax and instead relies on the JS runtime to detect some errors.
|
|
33
|
+
|
|
34
|
+
The transpiler is only a few kilobytes and can be incorporated into other React engines as well. It even generates sourcemaps without relying on any third-party library.
|
|
35
|
+
|
|
36
|
+
There is a `transpile.js` helper in the `bin` directory to demonstrate how to use it.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## React APIs, Libraries, and Built-in Components
|
|
41
|
+
|
|
42
|
+
`Lilact` implements both the **legacy class-based** API and the **modern hook-based** API, and it includes almost everything you need.
|
|
43
|
+
|
|
44
|
+
In addition to the API itself, it bundles the official `Redux` and `PropTypes` libraries (see the `redux.jsx` and `proptypes.jsx` demos). As a result, it has Redux support and provides many functions and hooks, including `connect` and `useDispatch`.
|
|
45
|
+
|
|
46
|
+
It also includes the amazing `@emotion/css` library to ease working with styles. You can access it via `Lilact.emotion`.
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
`Suspense`, and some helper components like `Spinner` and `ResizablePane`. It also has
|
|
49
|
-
a specific timeout implementation that can be paused and resumed at will. `Lilact`'s
|
|
50
|
-
`Suspense` has a few more features than the standard API.
|
|
48
|
+
For convenience, it already includes components such as:
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
itself directly.
|
|
50
|
+
- `HashRouter`
|
|
51
|
+
- `CSSTransition`
|
|
52
|
+
- `ErrorBoundary`
|
|
53
|
+
- `Suspense`
|
|
57
54
|
|
|
58
|
-
|
|
59
|
-
use import and exports the same as a module. So you should import the functions using the following
|
|
60
|
-
convention
|
|
55
|
+
and helper components like:
|
|
61
56
|
|
|
62
|
-
|
|
57
|
+
- `Spinner`
|
|
58
|
+
- `ResizablePane`
|
|
63
59
|
|
|
64
|
-
|
|
60
|
+
It also includes a specific timeout implementation that can be paused and resumed at will. `Lilact`’s `Suspense` includes additional features beyond the standard API.
|
|
65
61
|
|
|
62
|
+
You can see all available members and methods in the documentation. There is also a list of demos you can view alongside their code at:
|
|
63
|
+
[Lilact Demo Examples](arashkazemi.github.io/lilact/static)
|
|
64
|
+
|
|
65
|
+
Note: modules are separated in the documentation to improve structure, but in practice all members and methods are accessible directly via the `Lilact` object.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Webpack-based Bundler
|
|
70
|
+
|
|
71
|
+
A `webpack` based bundler is available in the `bin` directory. It can be used like this:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npx lilact-bundle --entry client/App.jsx --mode production --name bundle.js --out public/dist
|
|
75
|
+
```
|
|
66
76
|
|
|
67
77
|
---
|
|
68
78
|
|
|
69
|
-
|
|
79
|
+
## Using Lilact Outside Node.js (Browser / Script Tag Integration)
|
|
80
|
+
|
|
81
|
+
If you use `Lilact` outside Node.js, `Lilact` runs in the browser. In this mode it uses `eval` to run the transpiled scripts, so it cannot use `import`/`export` the same way as a module.
|
|
82
|
+
|
|
83
|
+
Import the functions using this convention:
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
const { useState, useRef, render } = Lilact;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
To export:
|
|
70
90
|
|
|
71
|
-
|
|
91
|
+
```js
|
|
92
|
+
module.exports = ...
|
|
93
|
+
```
|
|
72
94
|
|
|
73
|
-
|
|
95
|
+
Bundled projects can also be used statically on other backends. However, bundling is not required: JSX files can be served and transpiled live.
|
|
74
96
|
|
|
75
|
-
|
|
97
|
+
A complete example of a `Lilact` project with an `express` request handler is available at:
|
|
98
|
+
[lilact-express](github.com/arashkazemi/lilact-express)
|
|
99
|
+
|
|
100
|
+
An example using it with a PHP/MySQL data store is available at:
|
|
101
|
+
[lilact-php-demo](github.com/arashkazemi/lilact-php-demo)
|
|
102
|
+
|
|
103
|
+
An example using it with a Python/SQLite data store is available at:
|
|
104
|
+
[lilact-python-demo](github.com/arashkazemi/lilact-python-demo)
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Installation and Delivery
|
|
109
|
+
|
|
110
|
+
### Node.js (npm)
|
|
111
|
+
To use `Lilact` in other Node projects, install it from the npm public repository:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm i lilact
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Browser / Static (dist + CDN)
|
|
118
|
+
To use `Lilact` in a webpage, first download the source code and extract it. The minified script itself is available in the `/dist` directory, and the documentation can be found in `/docs` and also in the source files.
|
|
119
|
+
|
|
120
|
+
It is also available via unpkg CDN and can be included in HTML like:
|
|
121
|
+
|
|
122
|
+
```html
|
|
123
|
+
<script src="unpkg.com/lilact/dist/lilact.development.min.js"></script>
|
|
124
|
+
```
|
|
76
125
|
|
|
77
126
|
or
|
|
78
127
|
|
|
79
|
-
|
|
128
|
+
```html
|
|
129
|
+
<script src="unpkg.com/lilact/dist/lilact.production.min.js"></script>
|
|
130
|
+
```
|
|
80
131
|
|
|
132
|
+
Note: the production version, like the official React API, doesn’t perform PropTypes checks, but you can access PropTypes using `Lilact.PropTypes`.
|
|
81
133
|
|
|
82
|
-
|
|
83
|
-
script itself is available in the `/dist` directory and the documentation
|
|
84
|
-
can be found in the `/docs` and also in the source files.
|
|
134
|
+
After loading, `Lilact` automatically scans the document for any script elements with `type='text/jsx'` and runs them. If the `src` attribute is present on the script, it will load the resource; if the script contains inner content, it will be executed.
|
|
85
135
|
|
|
86
|
-
|
|
87
|
-
checks, but you can access PropTypes using Lilact.PropTypes.
|
|
136
|
+
This is not the only way to use it—inside Node projects you can use standard module imports and treat `Lilact` like a normal module.
|
|
88
137
|
|
|
89
|
-
|
|
90
|
-
with `type='text/jsx'` and it will run them. If the `src` attribute is set it will load
|
|
91
|
-
the resource, and if there is inner content it will be executed. Of course this is not the
|
|
92
|
-
only way.
|
|
138
|
+
`Lilact` wraps browser events to mimic React events. This mimicry is not perfect on some edge cases (because the footprint was important), but it works well overall.
|
|
93
139
|
|
|
94
|
-
|
|
95
|
-
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Example
|
|
143
|
+
|
|
144
|
+
### Node.js example
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
import { render } from "lilact";
|
|
148
|
+
|
|
149
|
+
function App() {
|
|
150
|
+
return <div>Hello World</div>;
|
|
151
|
+
}
|
|
96
152
|
|
|
97
|
-
|
|
153
|
+
render(<App/>, document.body);
|
|
154
|
+
```
|
|
98
155
|
|
|
99
|
-
|
|
100
|
-
<html>
|
|
101
|
-
<head>
|
|
102
|
-
<meta charset="utf-8"/>
|
|
103
|
-
<title>Lilact Demo</title>
|
|
104
|
-
<script src='./lilact.development.min.js' type="module"></script>
|
|
105
|
-
</head>
|
|
106
|
-
<body></body>
|
|
107
|
-
<script type='text/jsx'>
|
|
108
|
-
const { render } = Lilact;
|
|
156
|
+
### Outside Node.js (e.g., PHP / Python integration)
|
|
109
157
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
158
|
+
```html
|
|
159
|
+
<!DOCTYPE html>
|
|
160
|
+
<html>
|
|
161
|
+
<head>
|
|
162
|
+
<meta charset="utf-8"/>
|
|
163
|
+
<title>Lilact Demo</title>
|
|
164
|
+
<script src='./lilact.development.min.js' type="module"></script>
|
|
165
|
+
</head>
|
|
166
|
+
<body></body>
|
|
167
|
+
<script type='text/jsx'>
|
|
168
|
+
const { render } = Lilact;
|
|
117
169
|
|
|
170
|
+
function App() {
|
|
171
|
+
return <div>Hello World</div>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
render(<App/>, document.body);
|
|
175
|
+
</script>
|
|
176
|
+
</html>
|
|
177
|
+
```
|
|
118
178
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Learn More / Demos / Beta Status
|
|
182
|
+
|
|
183
|
+
To know more about using `Lilact`, see the included examples:
|
|
184
|
+
[Lilact Demo Examples](arashkazemi.github.io/lilact/static)
|
|
122
185
|
|
|
123
|
-
|
|
124
|
-
being made. Please report any possible issues or bugs, they will be fixed
|
|
125
|
-
without any hesitation!
|
|
186
|
+
For the details, see the documentation.
|
|
126
187
|
|
|
127
|
-
|
|
188
|
+
`Lilact` is currently in its beta state. It is under heavy testing and improvements are being made. Please report any possible issues or bugs—They will be fixed without any hesitation!
|
|
189
|
+
|
|
190
|
+
---
|
|
128
191
|
|
|
129
192
|
Copyright (C) 2024-2026 Arash Kazemi <contact.arash.kazemi@gmail.com>. All rights reserved.
|
|
130
193
|
|
package/bin/bundle.cjs
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
|
|
5
|
+
Lilact
|
|
6
|
+
Copyright (C) 2024-2025 Arash Kazemi <contact.arash.kazemi@gmail.com>
|
|
7
|
+
All rights reserved.
|
|
8
|
+
BSD-2-Clause
|
|
9
|
+
|
|
10
|
+
Redistribution and use in source and binary forms, with or without
|
|
11
|
+
modification, are permitted provided that the following conditions are met:
|
|
12
|
+
|
|
13
|
+
* Redistributions of source code must retain the above copyright
|
|
14
|
+
notice, this list of conditions and the following disclaimer.
|
|
15
|
+
* Redistributions in binary form must reproduce the above copyright
|
|
16
|
+
notice, this list of conditions and the following disclaimer in the
|
|
17
|
+
documentation and/or other materials provided with the distribution.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
22
|
+
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
23
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
24
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
25
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
26
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
27
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
28
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
+
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
const path = require("path");
|
|
33
|
+
const webpack = require("webpack");
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
function parseArgs(argv) {
|
|
37
|
+
// Simple args:
|
|
38
|
+
// bundler --entry ./src/index.js --out ./dist/bundle
|
|
39
|
+
const args = {};
|
|
40
|
+
for (let i = 2; i < argv.length; i++) {
|
|
41
|
+
const k = argv[i];
|
|
42
|
+
if (!k.startsWith("--")) continue;
|
|
43
|
+
const key = k.slice(2);
|
|
44
|
+
const v = argv[i + 1];
|
|
45
|
+
i++;
|
|
46
|
+
args[key] = v;
|
|
47
|
+
}
|
|
48
|
+
return args;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function run() {
|
|
52
|
+
const args = parseArgs(process.argv);
|
|
53
|
+
|
|
54
|
+
const userProjectRoot = process.cwd(); // MUST be user's project root
|
|
55
|
+
const userEntry = args.entry
|
|
56
|
+
? path.resolve(userProjectRoot, args.entry)
|
|
57
|
+
: null;
|
|
58
|
+
|
|
59
|
+
if (!userEntry) {
|
|
60
|
+
console.error("Usage: lilact-bundler --entry ./path/to/entry.js --mode production --out ./dist/out --name bundle.js");
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const name = args.name ?? "bundle.js";
|
|
65
|
+
const mode = args.mode ?? "production";
|
|
66
|
+
|
|
67
|
+
// Locate lilact root reliably (where this CLI is installed)
|
|
68
|
+
const lilactRoot = path.dirname(require.resolve("lilact/package.json"));
|
|
69
|
+
|
|
70
|
+
// Load config factory from your package
|
|
71
|
+
const configFactoryPath = path.join(lilactRoot, "webpack.config.factory.cjs");
|
|
72
|
+
const configFactory = require(configFactoryPath);
|
|
73
|
+
|
|
74
|
+
const userOutDir = args.out
|
|
75
|
+
? path.resolve(userProjectRoot, args.out)
|
|
76
|
+
: path.resolve(userProjectRoot, "dist");
|
|
77
|
+
|
|
78
|
+
// Build config using a factory, then override resolution for user's project
|
|
79
|
+
const baseConfig = configFactory({
|
|
80
|
+
entry: userEntry,
|
|
81
|
+
outputPath: userOutDir,
|
|
82
|
+
userProjectRoot,
|
|
83
|
+
mode, name
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// ---- Critical: ensure resolution happens from user's project ----
|
|
87
|
+
baseConfig.context = userProjectRoot;
|
|
88
|
+
baseConfig.resolve = baseConfig.resolve || {};
|
|
89
|
+
baseConfig.resolve.modules = [
|
|
90
|
+
path.join(userProjectRoot, "node_modules"),
|
|
91
|
+
"node_modules"
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
const compiler = webpack(baseConfig);
|
|
95
|
+
|
|
96
|
+
compiler.run((err, stats) => {
|
|
97
|
+
// webpack keeps resources; close when available
|
|
98
|
+
compiler.close(() => {});
|
|
99
|
+
|
|
100
|
+
if (err) {
|
|
101
|
+
console.error(err);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (stats?.hasErrors?.()) {
|
|
106
|
+
console.error(stats.toString("errors-only"));
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
console.log(
|
|
111
|
+
stats?.toString?.({
|
|
112
|
+
colors: true,
|
|
113
|
+
chunks: false
|
|
114
|
+
}) || "Build finished."
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
run().catch((e) => {
|
|
120
|
+
console.error(e);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
});
|
package/bin/bundle.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
|
|
5
|
+
Lilact
|
|
6
|
+
Copyright (C) 2024-2025 Arash Kazemi <contact.arash.kazemi@gmail.com>
|
|
7
|
+
All rights reserved.
|
|
8
|
+
BSD-2-Clause
|
|
9
|
+
|
|
10
|
+
Redistribution and use in source and binary forms, with or without
|
|
11
|
+
modification, are permitted provided that the following conditions are met:
|
|
12
|
+
|
|
13
|
+
* Redistributions of source code must retain the above copyright
|
|
14
|
+
notice, this list of conditions and the following disclaimer.
|
|
15
|
+
* Redistributions in binary form must reproduce the above copyright
|
|
16
|
+
notice, this list of conditions and the following disclaimer in the
|
|
17
|
+
documentation and/or other materials provided with the distribution.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
22
|
+
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
23
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
24
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
25
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
26
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
27
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
28
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
+
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
const path = require("path");
|
|
33
|
+
const webpack = require("webpack");
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
function parseArgs(argv) {
|
|
37
|
+
// Simple args:
|
|
38
|
+
// bundler --entry ./src/index.js --out ./dist/bundle
|
|
39
|
+
const args = {};
|
|
40
|
+
for (let i = 2; i < argv.length; i++) {
|
|
41
|
+
const k = argv[i];
|
|
42
|
+
if (!k.startsWith("--")) continue;
|
|
43
|
+
const key = k.slice(2);
|
|
44
|
+
const v = argv[i + 1];
|
|
45
|
+
i++;
|
|
46
|
+
args[key] = v;
|
|
47
|
+
}
|
|
48
|
+
return args;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function run() {
|
|
52
|
+
const args = parseArgs(process.argv);
|
|
53
|
+
|
|
54
|
+
const userProjectRoot = process.cwd(); // MUST be user's project root
|
|
55
|
+
const userEntry = args.entry
|
|
56
|
+
? path.resolve(userProjectRoot, args.entry)
|
|
57
|
+
: null;
|
|
58
|
+
|
|
59
|
+
if (!userEntry) {
|
|
60
|
+
console.error("Usage: bundler --entry ./path/to/entry.js --out ./dist/out");
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Locate lilact root reliably (where this CLI is installed)
|
|
65
|
+
const myPackageRoot = path.dirname(require.resolve("lilact/package.json"));
|
|
66
|
+
|
|
67
|
+
// Load config factory from your package
|
|
68
|
+
const configFactoryPath = path.join(myPackageRoot, "webpack.config.factory.cjs");
|
|
69
|
+
const configFactory = require(configFactoryPath);
|
|
70
|
+
|
|
71
|
+
const userOutDir = args.out
|
|
72
|
+
? path.resolve(userProjectRoot, args.out)
|
|
73
|
+
: path.resolve(userProjectRoot, "dist/bundle-out");
|
|
74
|
+
|
|
75
|
+
// Build config using a factory, then override resolution for user's project
|
|
76
|
+
const baseConfig = configFactory({
|
|
77
|
+
entry: userEntry,
|
|
78
|
+
outputPath: userOutDir,
|
|
79
|
+
userProjectRoot
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// ---- Critical: ensure resolution happens from user's project ----
|
|
83
|
+
baseConfig.context = userProjectRoot;
|
|
84
|
+
baseConfig.resolve = baseConfig.resolve || {};
|
|
85
|
+
baseConfig.resolve.modules = [
|
|
86
|
+
path.join(userProjectRoot, "node_modules"),
|
|
87
|
+
"node_modules"
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
const compiler = webpack(baseConfig);
|
|
91
|
+
|
|
92
|
+
compiler.run((err, stats) => {
|
|
93
|
+
// webpack keeps resources; close when available
|
|
94
|
+
compiler.close(() => {});
|
|
95
|
+
|
|
96
|
+
if (err) {
|
|
97
|
+
console.error(err);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (stats?.hasErrors?.()) {
|
|
102
|
+
console.error(stats.toString("errors-only"));
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log(
|
|
107
|
+
stats?.toString?.({
|
|
108
|
+
colors: true,
|
|
109
|
+
chunks: false
|
|
110
|
+
}) || "Build finished."
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
run().catch((e) => {
|
|
116
|
+
console.error(e);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
});
|