makepack 1.7.13 → 1.7.14

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.
@@ -1,216 +1,216 @@
1
- import express from 'express';
2
- import path from 'path';
3
- import fs from 'fs';
4
- import { pathToFileURL } from 'url';
5
- import { createRequire } from 'module';
6
- import chokidar from 'chokidar';
7
- import madge from 'madge';
8
- import viteSetup from './vite.js';
9
- import * as esbuild from 'esbuild';
10
- import { randomUUID } from 'crypto';
11
- import debounce from 'lodash.debounce';
12
- import { logger, concolor } from '../../helpers.js';
13
-
14
- const projectRoot = process.cwd();
15
- const requireFn = createRequire(import.meta.url);
16
- const mpack = path.join(projectRoot, '.mpack');
17
-
18
- let server = null;
19
- let app = null;
20
- let viteServer = null;
21
-
22
- const pkg = path.join(process.cwd(), 'package.json');
23
- const pkgjson = JSON.parse(fs.readFileSync(pkg, 'utf-8'));
24
- let isEsmProject = pkgjson.type === 'module';
25
-
26
- const uxpfileJS = path.resolve(projectRoot, 'express.js');
27
- const uxpfileTS = path.resolve(projectRoot, 'express.ts');
28
- const expExists = fs.existsSync(uxpfileJS) || fs.existsSync(uxpfileTS);
29
- let uxpfile = expExists ? (fs.existsSync(uxpfileJS) ? uxpfileJS : uxpfileTS) : null;
30
-
31
- const connections = new Set();
32
-
33
- function safeHandler(fn) {
34
- return (req, res, next) => {
35
- try {
36
- const result = fn(req, res, next);
37
- if (result && typeof result.catch === 'function') {
38
- result.catch(next);
39
- }
40
- } catch (err) {
41
- logger.error(`Error in request handler: ${err.message || err}`);
42
- res.status(500).send('Internal Server Error');
43
- // next();
44
- }
45
- };
46
- }
47
-
48
- function trackConnections(srv) {
49
- srv.on('connection', (conn) => {
50
- connections.add(conn);
51
- conn.on('close', () => connections.delete(conn));
52
- });
53
- }
54
-
55
- async function bootServer(args) {
56
- let wasServer = !!server;
57
- if (server) {
58
- for (const conn of connections) {
59
- conn.destroy();
60
- }
61
- await new Promise((resolve, reject) => {
62
- server.close(err => {
63
- if (err) {
64
- logger.error(`while closing server: ${err.message || err}`);
65
- reject(err);
66
- } else {
67
- resolve();
68
- }
69
- });
70
- });
71
- server = null;
72
- }
73
-
74
- if (viteServer) {
75
- await viteServer.close();
76
- }
77
-
78
- app = express();
79
-
80
- try {
81
- const middleware = await loadExp();
82
- if (typeof middleware === 'function') {
83
- const _get = app.get.bind(app);
84
- const _post = app.post.bind(app);
85
- const _delete = app.delete.bind(app);
86
- const _put = app.put.bind(app);
87
-
88
- app.get = (path, ...handlers) => {
89
- handlers = handlers.map(h => safeHandler(h));
90
- return _get(path, ...handlers);
91
- };
92
-
93
- app.post = (path, ...handlers) => {
94
- handlers = handlers.map(h => safeHandler(h));
95
- return _post(path, ...handlers);
96
- };
97
-
98
- app.put = (path, ...handlers) => {
99
- handlers = handlers.map(h => safeHandler(h));
100
- return _put(path, ...handlers);
101
- };
102
-
103
- app.delete = (path, ...handlers) => {
104
- handlers = handlers.map(h => safeHandler(h));
105
- return _delete(path, ...handlers);
106
- };
107
- middleware(app);
108
- }
109
-
110
- viteServer = await viteSetup(app);
111
- const port = args.port || 4000;
112
- server = app.listen(port, () => {
113
- if (!wasServer) {
114
- logger.success(`Server running on: ${concolor.green(concolor.bold(`http://localhost:${port}`))}`, '')
115
- }
116
- trackConnections(server);
117
- })
118
- } catch (err) {
119
- logger.error(`Failed to start server: ${err.message || err}`);
120
- }
121
- }
122
-
123
- let esbuildCtx = null;
124
-
125
- const buildFile = path.join(mpack, `${randomUUID().substring(0, 15)}.js`);
126
-
127
- async function loadExp() {
128
- if (!expExists) return null
129
-
130
- const cacheKeys = Object.keys(requireFn.cache || {});
131
- if (!isEsmProject) {
132
- for (const key of cacheKeys) {
133
- if (key.startsWith(process.cwd())) {
134
- delete requireFn.cache[key];
135
- }
136
- }
137
- }
138
-
139
- const ext = path.extname(uxpfile);
140
- const isTs = ext === '.ts' || ext === '.tsx';
141
-
142
- if (isTs) {
143
- if (esbuildCtx) {
144
- await esbuildCtx.rebuild();
145
- } else {
146
- esbuildCtx = await esbuild.context({
147
- entryPoints: [uxpfile],
148
- outfile: buildFile,
149
- format: isEsmProject ? 'esm' : 'cjs',
150
- platform: 'node',
151
- sourcemap: 'inline',
152
- bundle: true,
153
- packages: 'external',
154
- });
155
- await esbuildCtx.rebuild();
156
- }
157
-
158
- if (isEsmProject) {
159
- const mod = await import(pathToFileURL(buildFile).href + `?update=${Date.now()}`);
160
- return mod.default || mod;
161
- } else {
162
- return requireFn(buildFile);
163
- }
164
- }
165
-
166
- if (isEsmProject) {
167
- const mod = await import(pathToFileURL(uxpfile).href + `?update=${Date.now()}`);
168
- return mod.default || mod;
169
- } else {
170
- return requireFn(uxpfile);
171
- }
172
- }
173
-
174
- async function getAllDependencies() {
175
- try {
176
- if (!expExists) {
177
- return [];
178
- }
179
- const result = await madge(uxpfile, { fileExtensions: ['ts', 'js'] });
180
- const deps = Object.keys(result.obj());
181
- // const circular = await result.circular();
182
- // if (circular.length) {
183
- // logger.warning(`Circular dependencies detected: ${circular.map(c => c.join(' -> ')).join(', ')}`);
184
- // }
185
- return deps.map(dep => path.resolve(path.dirname(uxpfile), dep));
186
- } catch (err) {
187
- logger.error(`Failed to analyze dependencies with madge: ${err.message || err}`);
188
- return [uxpfile];
189
- }
190
- }
191
-
192
-
193
- let watcher;
194
- async function startDevServer(args) {
195
- if (fs.existsSync(mpack)) {
196
- fs.rmSync(mpack, { recursive: true, force: true });
197
- }
198
- fs.mkdirSync(mpack, { recursive: true });
199
-
200
- await bootServer(args);
201
- const filesToWatch = await getAllDependencies();
202
- if (watcher) watcher.close();
203
- watcher = chokidar.watch(filesToWatch, { ignoreInitial: true });
204
-
205
- const reload = debounce(async (f) => {
206
- await bootServer(args);
207
- const prettyPath = concolor.dim(path.relative(process.cwd(), f));
208
- logger.info(`${concolor.green('server reload')} ${prettyPath}`);
209
- }, 100);
210
-
211
- watcher.on('change', reload);
212
- watcher.on('add', reload);
213
- watcher.on('unlink', reload);
214
- }
215
-
1
+ import express from 'express';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import { pathToFileURL } from 'url';
5
+ import { createRequire } from 'module';
6
+ import chokidar from 'chokidar';
7
+ import madge from 'madge';
8
+ import viteSetup from './vite.js';
9
+ import * as esbuild from 'esbuild';
10
+ import { randomUUID } from 'crypto';
11
+ import debounce from 'lodash.debounce';
12
+ import { logger, concolor, loadViteConfig } from '../../helpers.js';
13
+
14
+ const projectRoot = process.cwd();
15
+ const requireFn = createRequire(import.meta.url);
16
+ const mpack = path.join(projectRoot, '.mpack');
17
+
18
+ let server = null;
19
+ let app = null;
20
+ let viteServer = null;
21
+
22
+ const pkg = path.join(process.cwd(), 'package.json');
23
+ const pkgjson = JSON.parse(fs.readFileSync(pkg, 'utf-8'));
24
+ let isEsmProject = pkgjson.type === 'module';
25
+
26
+ const uxpfileJS = path.resolve(projectRoot, 'express.js');
27
+ const uxpfileTS = path.resolve(projectRoot, 'express.ts');
28
+ const expExists = fs.existsSync(uxpfileJS) || fs.existsSync(uxpfileTS);
29
+ let uxpfile = expExists ? (fs.existsSync(uxpfileJS) ? uxpfileJS : uxpfileTS) : null;
30
+
31
+ const connections = new Set();
32
+
33
+ function safeHandler(fn) {
34
+ return (req, res, next) => {
35
+ try {
36
+ const result = fn(req, res, next);
37
+ if (result && typeof result.catch === 'function') {
38
+ result.catch(next);
39
+ }
40
+ } catch (err) {
41
+ logger.error(`Error in request handler: ${err.message || err}`);
42
+ res.status(500).send('Internal Server Error');
43
+ // next();
44
+ }
45
+ };
46
+ }
47
+
48
+ function trackConnections(srv) {
49
+ srv.on('connection', (conn) => {
50
+ connections.add(conn);
51
+ conn.on('close', () => connections.delete(conn));
52
+ });
53
+ }
54
+
55
+ async function bootServer(args) {
56
+ let wasServer = !!server;
57
+ if (server) {
58
+ for (const conn of connections) {
59
+ conn.destroy();
60
+ }
61
+ await new Promise((resolve, reject) => {
62
+ server.close(err => {
63
+ if (err) {
64
+ logger.error(`while closing server: ${err.message || err}`);
65
+ reject(err);
66
+ } else {
67
+ resolve();
68
+ }
69
+ });
70
+ });
71
+ server = null;
72
+ }
73
+
74
+ if (viteServer) {
75
+ await viteServer.close();
76
+ }
77
+
78
+ app = express();
79
+
80
+ try {
81
+ const middleware = await loadExp();
82
+ if (typeof middleware === 'function') {
83
+ const _get = app.get.bind(app);
84
+ const _post = app.post.bind(app);
85
+ const _delete = app.delete.bind(app);
86
+ const _put = app.put.bind(app);
87
+
88
+ app.get = (path, ...handlers) => {
89
+ handlers = handlers.map(h => safeHandler(h));
90
+ return _get(path, ...handlers);
91
+ };
92
+
93
+ app.post = (path, ...handlers) => {
94
+ handlers = handlers.map(h => safeHandler(h));
95
+ return _post(path, ...handlers);
96
+ };
97
+
98
+ app.put = (path, ...handlers) => {
99
+ handlers = handlers.map(h => safeHandler(h));
100
+ return _put(path, ...handlers);
101
+ };
102
+
103
+ app.delete = (path, ...handlers) => {
104
+ handlers = handlers.map(h => safeHandler(h));
105
+ return _delete(path, ...handlers);
106
+ };
107
+ middleware(app);
108
+ }
109
+ const config = await loadViteConfig() || {}
110
+ viteServer = await viteSetup(app);
111
+ const port = args.port || config?.server?.port || 4000;
112
+ server = app.listen(port, () => {
113
+ if (!wasServer) {
114
+ logger.success(`Server running on: ${concolor.green(concolor.bold(`http://localhost:${port}`))}`, '')
115
+ }
116
+ trackConnections(server);
117
+ })
118
+ } catch (err) {
119
+ logger.error(`Failed to start server: ${err.message || err}`);
120
+ }
121
+ }
122
+
123
+ let esbuildCtx = null;
124
+
125
+ const buildFile = path.join(mpack, `${randomUUID().substring(0, 15)}.js`);
126
+
127
+ async function loadExp() {
128
+ if (!expExists) return null
129
+
130
+ const cacheKeys = Object.keys(requireFn.cache || {});
131
+ if (!isEsmProject) {
132
+ for (const key of cacheKeys) {
133
+ if (key.startsWith(process.cwd())) {
134
+ delete requireFn.cache[key];
135
+ }
136
+ }
137
+ }
138
+
139
+ const ext = path.extname(uxpfile);
140
+ const isTs = ext === '.ts' || ext === '.tsx';
141
+
142
+ if (isTs) {
143
+ if (esbuildCtx) {
144
+ await esbuildCtx.rebuild();
145
+ } else {
146
+ esbuildCtx = await esbuild.context({
147
+ entryPoints: [uxpfile],
148
+ outfile: buildFile,
149
+ format: isEsmProject ? 'esm' : 'cjs',
150
+ platform: 'node',
151
+ sourcemap: 'inline',
152
+ bundle: true,
153
+ packages: 'external',
154
+ });
155
+ await esbuildCtx.rebuild();
156
+ }
157
+
158
+ if (isEsmProject) {
159
+ const mod = await import(pathToFileURL(buildFile).href + `?update=${Date.now()}`);
160
+ return mod.default || mod;
161
+ } else {
162
+ return requireFn(buildFile);
163
+ }
164
+ }
165
+
166
+ if (isEsmProject) {
167
+ const mod = await import(pathToFileURL(uxpfile).href + `?update=${Date.now()}`);
168
+ return mod.default || mod;
169
+ } else {
170
+ return requireFn(uxpfile);
171
+ }
172
+ }
173
+
174
+ async function getAllDependencies() {
175
+ try {
176
+ if (!expExists) {
177
+ return [];
178
+ }
179
+ const result = await madge(uxpfile, { fileExtensions: ['ts', 'js'] });
180
+ const deps = Object.keys(result.obj());
181
+ // const circular = await result.circular();
182
+ // if (circular.length) {
183
+ // logger.warning(`Circular dependencies detected: ${circular.map(c => c.join(' -> ')).join(', ')}`);
184
+ // }
185
+ return deps.map(dep => path.resolve(path.dirname(uxpfile), dep));
186
+ } catch (err) {
187
+ logger.error(`Failed to analyze dependencies with madge: ${err.message || err}`);
188
+ return [uxpfile];
189
+ }
190
+ }
191
+
192
+
193
+ let watcher;
194
+ async function startDevServer(args) {
195
+ if (fs.existsSync(mpack)) {
196
+ fs.rmSync(mpack, { recursive: true, force: true });
197
+ }
198
+ fs.mkdirSync(mpack, { recursive: true });
199
+
200
+ await bootServer(args);
201
+ const filesToWatch = await getAllDependencies();
202
+ if (watcher) watcher.close();
203
+ watcher = chokidar.watch(filesToWatch, { ignoreInitial: true });
204
+
205
+ const reload = debounce(async (f) => {
206
+ await bootServer(args);
207
+ const prettyPath = concolor.dim(path.relative(process.cwd(), f));
208
+ logger.info(`${concolor.green('server reload')} ${prettyPath}`);
209
+ }, 100);
210
+
211
+ watcher.on('change', reload);
212
+ watcher.on('add', reload);
213
+ watcher.on('unlink', reload);
214
+ }
215
+
216
216
  export default startDevServer
@@ -1,69 +1,73 @@
1
- // import react from '@vitejs/plugin-react'
2
- import { createServer as createViteServer } from 'vite';
3
- import { logger } from '../../helpers.js'
4
- import path from 'path';
5
- import fs from 'fs';
6
-
7
- const viteSetup = async (app) => {
8
-
9
- // delete .vite directory if exists
10
- const viteDir = path.join(process.cwd(), 'node_modules/.vite');
11
- if (fs.existsSync(viteDir)) {
12
- fs.rmSync(viteDir, { recursive: true, force: true });
13
- }
14
-
15
- const viteConfig = {
16
- root: process.cwd(),
17
- base: "/",
18
- // plugins: [react()],
19
- server: {
20
- middlewareMode: true,
21
- },
22
- customLogger: {
23
- info: (msg) => {
24
- logger.info(msg)
25
- },
26
- warn: (msg) => logger.warning(msg),
27
- error: (msg) => logger.error(msg),
28
- },
29
- appType: 'custom'
30
- }
31
-
32
- const vite = await createViteServer(viteConfig);
33
- app.use(vite.middlewares);
34
-
35
- // exists tsconfig.json in the root directory
36
- const isTs = fs.existsSync(path.resolve(process.cwd(), 'main.tsx'))
37
- let entry = `/main.${isTs ? "tsx" : "jsx"}`
38
-
39
- app.get('*', async (req, res, next) => {
40
- const url = req.originalUrl;
41
-
42
- try {
43
- let template = await vite.transformIndexHtml(url, `
44
- <!doctype html>
45
- <html lang="en">
46
- <head>
47
- <meta charset="UTF-8" />
48
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
49
- </head>
50
- <body>
51
- <div id="root"></div>
52
- <script type="module" src="${entry}"></script>
53
- </body>
54
- </html>
55
- `);
56
-
57
- res.status(200).set({
58
- 'Content-Type': 'text/html'
59
- }).end(template);
60
- } catch (e) {
61
- vite.ssrFixStacktrace(e);
62
- next(e);
63
- }
64
- });
65
- return vite;
66
- }
67
-
68
-
1
+ // import react from '@vitejs/plugin-react'
2
+ import { createServer as createViteServer } from 'vite';
3
+ import { loadViteConfig, logger } from '../../helpers.js'
4
+ import path from 'path';
5
+ import fs from 'fs';
6
+
7
+ const viteSetup = async (app) => {
8
+ const config = await loadViteConfig() || {}
9
+
10
+ // delete .vite directory if exists
11
+ const viteDir = path.join(process.cwd(), 'node_modules/.vite');
12
+ if (fs.existsSync(viteDir)) {
13
+ fs.rmSync(viteDir, { recursive: true, force: true });
14
+ }
15
+
16
+ const viteConfig = {
17
+ ...config,
18
+ configFile: false,
19
+ root: process.cwd(),
20
+ base: "/",
21
+ // plugins: [react()],
22
+ server: {
23
+ ...config?.server,
24
+ middlewareMode: true,
25
+ },
26
+ customLogger: {
27
+ info: (msg) => {
28
+ logger.info(msg)
29
+ },
30
+ warn: (msg) => logger.warning(msg),
31
+ error: (msg) => logger.error(msg),
32
+ },
33
+ appType: 'custom'
34
+ }
35
+
36
+ const vite = await createViteServer(viteConfig);
37
+ app.use(vite.middlewares);
38
+
39
+ // exists tsconfig.json in the root directory
40
+ const isTs = fs.existsSync(path.resolve(process.cwd(), 'main.tsx'))
41
+ let entry = `/main.${isTs ? "tsx" : "jsx"}`
42
+
43
+ app.get('*', async (req, res, next) => {
44
+ const url = req.originalUrl;
45
+
46
+ try {
47
+ let template = await vite.transformIndexHtml(url, `
48
+ <!doctype html>
49
+ <html lang="en">
50
+ <head>
51
+ <meta charset="UTF-8" />
52
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
53
+ </head>
54
+ <body>
55
+ <div id="root"></div>
56
+ <script type="module" src="${entry}"></script>
57
+ </body>
58
+ </html>
59
+ `);
60
+
61
+ res.status(200).set({
62
+ 'Content-Type': 'text/html'
63
+ }).end(template);
64
+ } catch (e) {
65
+ vite.ssrFixStacktrace(e);
66
+ next(e);
67
+ }
68
+ });
69
+ return vite;
70
+ }
71
+
72
+
69
73
  export default viteSetup