makepack 1.6.9 → 1.7.0
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 +16 -9
- package/src/actions/build/bundler.js +99 -0
- package/src/actions/build/index.js +33 -111
- package/src/actions/create/files/package-json.js +7 -23
- package/src/actions/start/index.js +156 -98
- package/src/actions/start/vite.js +1 -0
- package/src/helpers.js +0 -19
- package/src/index.js +2 -4
- package/src/actions/start/express.js +0 -45
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "makepack",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A CLI tool to create, build, and manage JavaScript, TypeScript, React, and React-TypeScript libraries for npm projects.",
|
|
6
6
|
"files": [
|
|
@@ -30,18 +30,22 @@
|
|
|
30
30
|
"build": "node ./src/index.js build"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"
|
|
33
|
+
"@rollup/plugin-commonjs": "^28.0.5",
|
|
34
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
35
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
36
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
34
37
|
"chokidar": "^4.0.3",
|
|
35
38
|
"commander": "^12.1.0",
|
|
36
|
-
"
|
|
37
|
-
"esbuild": "^0.25.0",
|
|
39
|
+
"esbuild": "^0.25.5",
|
|
38
40
|
"express": "^4.21.1",
|
|
39
|
-
"figures": "^6.1.0",
|
|
40
41
|
"fs-extra": "^11.2.0",
|
|
41
|
-
"glob": "^11.0.0",
|
|
42
42
|
"inquirer": "^12.1.0",
|
|
43
|
+
"lodash.debounce": "^4.0.8",
|
|
44
|
+
"madge": "^8.0.0",
|
|
43
45
|
"ora": "^8.1.1",
|
|
44
|
-
"
|
|
46
|
+
"rollup": "^4.43.0",
|
|
47
|
+
"rollup-plugin-dts": "^6.2.1",
|
|
48
|
+
"tslib": "^2.8.1",
|
|
45
49
|
"vite": "^6.0.2"
|
|
46
50
|
},
|
|
47
51
|
"keywords": [
|
|
@@ -54,8 +58,11 @@
|
|
|
54
58
|
"npm-package"
|
|
55
59
|
],
|
|
56
60
|
"devDependencies": {
|
|
61
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
|
57
62
|
"@types/fs-extra": "^11.0.4",
|
|
58
|
-
"react": "^19.
|
|
59
|
-
"react
|
|
63
|
+
"@types/react": "^19.1.8",
|
|
64
|
+
"react": "^19.1.0",
|
|
65
|
+
"react-dom": "^19.0.0",
|
|
66
|
+
"typescript": "^5.8.3"
|
|
60
67
|
}
|
|
61
68
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { rollup } from "rollup";
|
|
2
|
+
import resolve from "@rollup/plugin-node-resolve";
|
|
3
|
+
import commonjs from "@rollup/plugin-commonjs";
|
|
4
|
+
import typescript from "@rollup/plugin-typescript";
|
|
5
|
+
import { builtinModules } from "module";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import dts from "rollup-plugin-dts";
|
|
9
|
+
import json from '@rollup/plugin-json';
|
|
10
|
+
import terser from "@rollup/plugin-terser";
|
|
11
|
+
|
|
12
|
+
async function build(args, spinner) {
|
|
13
|
+
const pkg = JSON.parse(fs.readFileSync("./package.json", "utf-8"));
|
|
14
|
+
const external = [
|
|
15
|
+
...builtinModules,
|
|
16
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
17
|
+
...Object.keys(pkg.devDependencies ?? {}),
|
|
18
|
+
...Object.keys(pkg.peerDependencies ?? {}),
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const isTs = args.entry.endsWith(".ts")
|
|
22
|
+
|
|
23
|
+
const config = {
|
|
24
|
+
input: [args.entry],
|
|
25
|
+
external,
|
|
26
|
+
plugins: [
|
|
27
|
+
json(),
|
|
28
|
+
resolve(),
|
|
29
|
+
commonjs(),
|
|
30
|
+
isTs ? typescript({
|
|
31
|
+
compilerOptions: {
|
|
32
|
+
"module": "ESNext",
|
|
33
|
+
"jsx": "react",
|
|
34
|
+
"strict": true,
|
|
35
|
+
"forceConsistentCasingInFileNames": true,
|
|
36
|
+
"esModuleInterop": true
|
|
37
|
+
},
|
|
38
|
+
include: ["src/**/*.ts", "src/**/*.tsx"],
|
|
39
|
+
exclude: ["node_modules", ".mpack"],
|
|
40
|
+
}) : null,
|
|
41
|
+
args.minify ? terser() : null,
|
|
42
|
+
]
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const bundle = await rollup(config);
|
|
46
|
+
const esm = {
|
|
47
|
+
dir: args.outdir,
|
|
48
|
+
format: "esm",
|
|
49
|
+
sourcemap: args.sourcemap,
|
|
50
|
+
compact: true,
|
|
51
|
+
strict: true
|
|
52
|
+
};
|
|
53
|
+
if (!args.bundle) {
|
|
54
|
+
esm.preserveModules = true
|
|
55
|
+
esm.preserveModulesRoot = args.rootdir
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let cjs = {
|
|
59
|
+
...esm,
|
|
60
|
+
dir: args.outdir,
|
|
61
|
+
format: "cjs",
|
|
62
|
+
dynamicImportInCjs: true,
|
|
63
|
+
esModule: true,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let outputOptions = []
|
|
67
|
+
|
|
68
|
+
if (args.format === "both") {
|
|
69
|
+
outputOptions = [
|
|
70
|
+
{ ...esm, entryFileNames: '[name].mjs' },
|
|
71
|
+
cjs,
|
|
72
|
+
]
|
|
73
|
+
} else if (args.format === "esm") {
|
|
74
|
+
outputOptions = [esm];
|
|
75
|
+
} else if (args.format === "cjs") {
|
|
76
|
+
outputOptions = [cjs];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for (const output of outputOptions) {
|
|
80
|
+
await bundle.write(output);
|
|
81
|
+
}
|
|
82
|
+
await bundle.close();
|
|
83
|
+
|
|
84
|
+
// If TypeScript declaration files are requested, generate them
|
|
85
|
+
if (isTs && args.declaration) {
|
|
86
|
+
spinner.text = "Generating TypeScript declarations..."
|
|
87
|
+
const bundlets = await rollup({
|
|
88
|
+
...config,
|
|
89
|
+
plugins: [dts()],
|
|
90
|
+
});
|
|
91
|
+
await bundlets.write({
|
|
92
|
+
...esm,
|
|
93
|
+
dir: path.join(args.outdir),
|
|
94
|
+
});
|
|
95
|
+
await bundlets.close();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default build;
|
|
@@ -1,136 +1,59 @@
|
|
|
1
|
-
import esbuild from 'esbuild'
|
|
2
1
|
import fs from 'fs-extra'
|
|
3
2
|
import path from 'path'
|
|
4
3
|
import ora from 'ora'
|
|
5
|
-
import { glob } from 'glob'
|
|
6
|
-
import ts from 'typescript'
|
|
7
4
|
import { concolor, logger } from '../../helpers.js'
|
|
8
|
-
|
|
9
|
-
const eBuild = async (conf) => {
|
|
10
|
-
|
|
11
|
-
await esbuild.build({
|
|
12
|
-
jsx: 'automatic',
|
|
13
|
-
...conf,
|
|
14
|
-
loader: {
|
|
15
|
-
'.ts': 'ts',
|
|
16
|
-
'.tsx': 'tsx'
|
|
17
|
-
},
|
|
18
|
-
outdir: path.join(process.cwd(), '.mpack', conf.format === 'esm' ? '' : conf.format),
|
|
19
|
-
})
|
|
20
|
-
}
|
|
5
|
+
import bundler from './bundler.js'
|
|
21
6
|
|
|
22
7
|
const build = async (args) => {
|
|
23
8
|
/* args
|
|
24
|
-
--format=
|
|
9
|
+
--format=both
|
|
25
10
|
--bundle=true,
|
|
26
11
|
--minify=false,
|
|
27
12
|
--sourcemap=true,
|
|
28
|
-
--
|
|
29
|
-
--target=es2020,
|
|
13
|
+
--declaration=true,
|
|
30
14
|
*/
|
|
31
15
|
|
|
32
|
-
|
|
33
16
|
let printBool = (f) => typeof args[f] === 'string' ? (args[f] === 'true') : args[f];
|
|
34
17
|
|
|
18
|
+
const outdir = path.join(process.cwd(), '.mpack');
|
|
19
|
+
const rootdir = path.join(process.cwd(), 'src');
|
|
20
|
+
|
|
21
|
+
let entry = '';
|
|
22
|
+
let entryts = path.join(rootdir, 'index.ts');
|
|
23
|
+
let entryjs = path.join(rootdir, 'index.js');
|
|
24
|
+
let entrytsx = path.join(rootdir, 'index.tsx');
|
|
25
|
+
let entryjsx = path.join(rootdir, 'index.jsx');
|
|
26
|
+
|
|
27
|
+
if (fs.existsSync(entryts)) {
|
|
28
|
+
entry = "index.ts";
|
|
29
|
+
} else if (fs.existsSync(entryjs)) {
|
|
30
|
+
entry = "index.js";
|
|
31
|
+
} else if (fs.existsSync(entrytsx)) {
|
|
32
|
+
entry = "index.tsx";
|
|
33
|
+
} else if (fs.existsSync(entryjsx)) {
|
|
34
|
+
entry = "index.jsx";
|
|
35
|
+
} else {
|
|
36
|
+
throw new Error("No entry file found in src directory. Please provide an index.ts or index.js file.");
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
args = {
|
|
36
|
-
format: args.format || "
|
|
40
|
+
format: args.format || "both",
|
|
37
41
|
bundle: printBool('bundle'),
|
|
38
42
|
minify: printBool('minify'),
|
|
39
43
|
sourcemap: printBool('sourcemap'),
|
|
40
|
-
platform: args.platform || "",
|
|
41
|
-
target: args.target || "es2020",
|
|
42
44
|
declaration: printBool('declaration'),
|
|
45
|
+
outdir,
|
|
46
|
+
rootdir,
|
|
47
|
+
entry: path.join(rootdir, entry),
|
|
43
48
|
}
|
|
44
49
|
|
|
45
|
-
const outdir = path.join(process.cwd(), '.mpack');
|
|
46
50
|
if (fs.existsSync(outdir)) {
|
|
47
51
|
fs.rmSync(outdir, { recursive: true, force: true });
|
|
48
52
|
}
|
|
49
53
|
fs.mkdirSync(outdir)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const files = await glob("src/**/*.{tsx,ts,js,jsx}") || [];
|
|
53
|
-
const entryPoints = files.map(entry => path.join(process.cwd(), entry));
|
|
54
|
-
let batchSize = args.format === 'default' ? 300 : 500;
|
|
55
|
-
|
|
56
|
-
let ebconfig = {
|
|
57
|
-
bundle: args.bundle,
|
|
58
|
-
minify: args.minify,
|
|
59
|
-
sourcemap: args.sourcemap,
|
|
60
|
-
platform: args.platform,
|
|
61
|
-
target: args.target,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
for (let i = 0; i < entryPoints.length; i += batchSize) {
|
|
65
|
-
const batch = entryPoints.slice(i, i + batchSize);
|
|
66
|
-
let config = {
|
|
67
|
-
...ebconfig,
|
|
68
|
-
entryPoints: batch,
|
|
69
|
-
}
|
|
70
|
-
if (args.format === 'default') {
|
|
71
|
-
await eBuild({ ...config, format: "esm" });
|
|
72
|
-
logger.success('ESM build generated successfully!');
|
|
73
|
-
await eBuild({ ...config, format: "cjs" });
|
|
74
|
-
logger.success('CJS build generated successfully!');
|
|
75
|
-
} else {
|
|
76
|
-
await eBuild({ ...config, format: args.format });
|
|
77
|
-
logger.success(`${args.format} build generated successfully!`);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (args.declaration) {
|
|
83
|
-
const tsconfigPath = path.resolve(process.cwd(), "tsconfig.json");
|
|
84
|
-
let tsconfig = {};
|
|
85
|
-
if (fs.existsSync(tsconfigPath)) {
|
|
86
|
-
const parsedConfig = ts.getParsedCommandLineOfConfigFile(
|
|
87
|
-
tsconfigPath,
|
|
88
|
-
{},
|
|
89
|
-
ts.sys
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
if (!parsedConfig) {
|
|
93
|
-
logger.error("Error parsing tsconfig.json");
|
|
94
|
-
process.exit(1);
|
|
95
|
-
} else {
|
|
96
|
-
tsconfig = parsedConfig.options;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
tsconfig = {
|
|
101
|
-
allowJs: true,
|
|
102
|
-
target: ts.ScriptTarget.ESNext, // Ensure it's an enum
|
|
103
|
-
skipLibCheck: true,
|
|
104
|
-
moduleResolution: ts.ModuleResolutionKind.Node10,
|
|
105
|
-
...tsconfig, // Preserve root tsconfig settings
|
|
106
|
-
outDir: outdir,
|
|
107
|
-
declaration: true,
|
|
108
|
-
emitDeclarationOnly: true,
|
|
109
|
-
noEmit: false,
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
spinner.text = "Generating TypeScript declarations..."
|
|
113
|
-
const program = ts.createProgram(files, tsconfig);
|
|
114
|
-
const emitResult = program.emit();
|
|
115
|
-
const diagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
|
|
116
|
-
|
|
117
|
-
if (diagnostics.length > 0) {
|
|
118
|
-
diagnostics.forEach(diagnostic => {
|
|
119
|
-
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
|
120
|
-
if (diagnostic.file) {
|
|
121
|
-
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
122
|
-
logger.error(`Error at ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
|
123
|
-
} else {
|
|
124
|
-
logger.error(`${message}`);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
} else {
|
|
128
|
-
logger.success("TypeScript declaration files generated successfully!")
|
|
129
|
-
}
|
|
130
|
-
}
|
|
54
|
+
const spinner = ora("✨ Bundling your package..\n").start();
|
|
55
|
+
await bundler(args, spinner);
|
|
131
56
|
spinner.text = "Copying package.json and readme.md files..."
|
|
132
|
-
|
|
133
|
-
// update package.json to include the .mpack directory
|
|
134
57
|
const pkgPath = path.join(process.cwd(), 'package.json');
|
|
135
58
|
if (fs.existsSync(pkgPath)) {
|
|
136
59
|
const pkgjson = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
@@ -143,10 +66,9 @@ const build = async (args) => {
|
|
|
143
66
|
}
|
|
144
67
|
|
|
145
68
|
fs.copyFileSync(path.join(process.cwd(), '/readme.md'), path.join(outdir, `/readme.md`))
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
logger.info(`${concolor.yellow(`npm run release`)} or navigate to the ${concolor.yellow(`.mpack`)} directory and run ${concolor.yellow(`npm publish`)}`, 'RELEASE:', true)
|
|
69
|
+
spinner.succeed(concolor.bold(concolor.green(`Build successfully completed\n`)));
|
|
70
|
+
console.log(concolor.bold(`To publish your package to npm run:`));
|
|
71
|
+
console.log(`${concolor.yellow(`\`npm run release\``)} Or navigate to \`.mpack\` and run: ${concolor.yellow(`\`npm publish\`\n`)}`);
|
|
150
72
|
spinner.stop();
|
|
151
73
|
}
|
|
152
74
|
|
|
@@ -21,8 +21,8 @@ export default async (info) => {
|
|
|
21
21
|
const json = {
|
|
22
22
|
name: info.pdir,
|
|
23
23
|
version: "1.0.0",
|
|
24
|
-
main: `./
|
|
25
|
-
module: `./index.
|
|
24
|
+
main: `./index.js`,
|
|
25
|
+
module: `./index.mjs`,
|
|
26
26
|
types: `./index.d.ts`,
|
|
27
27
|
description: "",
|
|
28
28
|
keywords: [],
|
|
@@ -32,28 +32,12 @@ export default async (info) => {
|
|
|
32
32
|
"build": "makepack build",
|
|
33
33
|
"release": "makepack release"
|
|
34
34
|
},
|
|
35
|
-
exports: {
|
|
35
|
+
"exports": {
|
|
36
36
|
".": {
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"import": {
|
|
42
|
-
"types": "./index.d.ts",
|
|
43
|
-
"default": "./index.js"
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
"./*": {
|
|
47
|
-
"require": {
|
|
48
|
-
"types": "./*.d.ts",
|
|
49
|
-
"default": "./cjs/*.js"
|
|
50
|
-
},
|
|
51
|
-
"import": {
|
|
52
|
-
"types": "./*.d.ts",
|
|
53
|
-
"default": "./*.js"
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
"./cjs": null
|
|
37
|
+
"import": "./index.mjs",
|
|
38
|
+
"require": "./index.js",
|
|
39
|
+
"types": "./index.d.ts"
|
|
40
|
+
}
|
|
57
41
|
},
|
|
58
42
|
dependencies,
|
|
59
43
|
devDependencies
|
|
@@ -1,117 +1,175 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
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
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
|
+
|
|
17
|
+
let server = null;
|
|
18
|
+
let app = null;
|
|
19
|
+
let viteServer = null;
|
|
20
|
+
|
|
21
|
+
const pkg = path.join(process.cwd(), 'package.json');
|
|
22
|
+
const pkgjson = JSON.parse(fs.readFileSync(pkg, 'utf-8'));
|
|
23
|
+
let isEsmProject = pkgjson.type === 'module';
|
|
24
|
+
|
|
25
|
+
const uxpfileJS = path.resolve(projectRoot, 'express.js');
|
|
26
|
+
const uxpfileTS = path.resolve(projectRoot, 'express.ts');
|
|
27
|
+
const expExists = fs.existsSync(uxpfileJS) || fs.existsSync(uxpfileTS);
|
|
28
|
+
let uxpfile = expExists ? (fs.existsSync(uxpfileJS) ? uxpfileJS : uxpfileTS) : null;
|
|
29
|
+
|
|
30
|
+
const connections = new Set();
|
|
31
|
+
|
|
32
|
+
function trackConnections(srv) {
|
|
33
|
+
srv.on('connection', (conn) => {
|
|
34
|
+
connections.add(conn);
|
|
35
|
+
conn.on('close', () => connections.delete(conn));
|
|
36
|
+
});
|
|
37
|
+
}
|
|
7
38
|
|
|
8
|
-
|
|
39
|
+
async function bootServer(args) {
|
|
40
|
+
let wasServer = !!server;
|
|
41
|
+
if (server) {
|
|
42
|
+
for (const conn of connections) {
|
|
43
|
+
conn.destroy();
|
|
44
|
+
}
|
|
45
|
+
await new Promise((resolve, reject) => {
|
|
46
|
+
server.close(err => {
|
|
47
|
+
if (err) {
|
|
48
|
+
logger.error(`while closing server: ${err.message || err}`);
|
|
49
|
+
reject(err);
|
|
50
|
+
} else {
|
|
51
|
+
resolve();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
server = null;
|
|
56
|
+
}
|
|
9
57
|
|
|
10
|
-
if (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
} else {
|
|
14
|
-
__filename = __filename;
|
|
15
|
-
__dirname = __dirname;
|
|
16
|
-
}
|
|
58
|
+
if (viteServer) {
|
|
59
|
+
await viteServer.close();
|
|
60
|
+
}
|
|
17
61
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
62
|
+
app = express();
|
|
63
|
+
try {
|
|
64
|
+
const middleware = await loadExp();
|
|
65
|
+
if (typeof middleware === 'function') {
|
|
66
|
+
middleware(app);
|
|
67
|
+
}
|
|
23
68
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
69
|
+
viteServer = await viteSetup(app);
|
|
70
|
+
const port = args.port || 4000;
|
|
71
|
+
server = app.listen(port, () => {
|
|
72
|
+
if (!wasServer) {
|
|
73
|
+
logger.success(`Server running on: ${concolor.green(concolor.bold(`http://localhost:${port}`))}`, '')
|
|
74
|
+
}
|
|
75
|
+
trackConnections(server);
|
|
76
|
+
})
|
|
77
|
+
} catch (err) {
|
|
78
|
+
logger.error(`Failed to start server: ${err.message || err}`);
|
|
79
|
+
}
|
|
28
80
|
}
|
|
29
81
|
|
|
30
|
-
const start = async (args) => {
|
|
31
|
-
let port = args.port || 4000
|
|
32
82
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
83
|
+
let esbuildCtx = null;
|
|
84
|
+
const mpack = path.join(projectRoot, '.mpack');
|
|
85
|
+
if (fs.existsSync(mpack)) {
|
|
86
|
+
fs.rmSync(mpack, { recursive: true, force: true });
|
|
87
|
+
}
|
|
88
|
+
fs.mkdirSync(mpack, { recursive: true });
|
|
89
|
+
const buildFile = path.join(mpack, `${randomUUID().substring(0, 15)}.js`);
|
|
90
|
+
|
|
91
|
+
async function loadExp() {
|
|
92
|
+
if (!expExists) return null
|
|
93
|
+
|
|
94
|
+
const cacheKeys = Object.keys(requireFn.cache || {});
|
|
95
|
+
if (!isEsmProject) {
|
|
96
|
+
for (const key of cacheKeys) {
|
|
97
|
+
if (key.startsWith(process.cwd())) {
|
|
98
|
+
delete requireFn.cache[key];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
37
101
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
102
|
+
|
|
103
|
+
const ext = path.extname(uxpfile);
|
|
104
|
+
const isTs = ext === '.ts';
|
|
105
|
+
|
|
106
|
+
if (isTs) {
|
|
107
|
+
if (esbuildCtx) {
|
|
108
|
+
await esbuildCtx.rebuild();
|
|
109
|
+
} else {
|
|
110
|
+
esbuildCtx = await esbuild.context({
|
|
111
|
+
entryPoints: [uxpfile],
|
|
112
|
+
outfile: buildFile,
|
|
113
|
+
format: isEsmProject ? 'esm' : 'cjs',
|
|
114
|
+
platform: 'node',
|
|
115
|
+
sourcemap: 'inline',
|
|
116
|
+
bundle: true,
|
|
117
|
+
packages: 'external',
|
|
118
|
+
});
|
|
119
|
+
await esbuildCtx.rebuild();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (isEsmProject) {
|
|
123
|
+
const mod = await import(pathToFileURL(buildFile).href + `?update=${Date.now()}`);
|
|
124
|
+
return mod.default || mod;
|
|
125
|
+
} else {
|
|
126
|
+
return requireFn(buildFile);
|
|
46
127
|
}
|
|
47
128
|
}
|
|
48
129
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
packages: 'external',
|
|
57
|
-
define: {
|
|
58
|
-
'process.env.PORT': JSON.stringify(port),
|
|
59
|
-
},
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
const uxpjs = path.join(process.cwd(), 'express.js')
|
|
63
|
-
const uxpts = path.join(process.cwd(), 'express.ts')
|
|
64
|
-
const exists = fs.existsSync(uxpjs) || fs.existsSync(uxpts);
|
|
65
|
-
const uxpFile = exists ? (fs.existsSync(uxpjs) ? 'express.js' : 'express.ts') : '';
|
|
66
|
-
let contents = `import server from './.mpack/core';`;
|
|
67
|
-
contents += uxpFile ? `
|
|
68
|
-
import uxp from './${uxpFile}';
|
|
69
|
-
server(uxp);
|
|
70
|
-
` : `server();`;
|
|
71
|
-
|
|
72
|
-
const result = await esbuild.build({
|
|
73
|
-
bundle: true,
|
|
74
|
-
stdin: {
|
|
75
|
-
contents,
|
|
76
|
-
resolveDir: process.cwd(),
|
|
77
|
-
sourcefile: 'virtual.js',
|
|
78
|
-
loader: 'ts',
|
|
79
|
-
},
|
|
80
|
-
format,
|
|
81
|
-
outfile: path.join(mpack, 'index.js'),
|
|
82
|
-
platform: 'node',
|
|
83
|
-
packages: 'external',
|
|
84
|
-
sourcemap: true,
|
|
85
|
-
metafile: true,
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
let server = startServer();
|
|
89
|
-
if (uxpFile) {
|
|
90
|
-
const importedFiles = Object.keys(result.metafile.inputs);
|
|
91
|
-
const watcher = chokidar.watch(importedFiles, {
|
|
92
|
-
ignored: /node_modules/,
|
|
93
|
-
ignoreInitial: true
|
|
94
|
-
});
|
|
130
|
+
if (isEsmProject) {
|
|
131
|
+
const mod = await import(pathToFileURL(uxpfile).href + `?update=${Date.now()}`);
|
|
132
|
+
return mod.default || mod;
|
|
133
|
+
} else {
|
|
134
|
+
return requireFn(uxpfile);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
95
137
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
138
|
+
async function getAllDependencies() {
|
|
139
|
+
try {
|
|
140
|
+
if (!expExists) {
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
const result = await madge(uxpfile, { fileExtensions: ['ts', 'js'] });
|
|
144
|
+
const deps = Object.keys(result.obj());
|
|
145
|
+
// const circular = await result.circular();
|
|
146
|
+
// if (circular.length) {
|
|
147
|
+
// logger.warning(`Circular dependencies detected: ${circular.map(c => c.join(' -> ')).join(', ')}`);
|
|
148
|
+
// }
|
|
149
|
+
return deps.map(dep => path.resolve(path.dirname(uxpfile), dep));
|
|
150
|
+
} catch (err) {
|
|
151
|
+
logger.error(`Failed to analyze dependencies with madge: ${err.message || err}`);
|
|
152
|
+
return [uxpfile];
|
|
100
153
|
}
|
|
154
|
+
}
|
|
101
155
|
|
|
102
|
-
process.on('SIGINT', () => {
|
|
103
|
-
console.log('Received SIGINT, killing server...');
|
|
104
|
-
server.kill('SIGINT');
|
|
105
|
-
process.exit(0);
|
|
106
|
-
});
|
|
107
156
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
157
|
+
let watcher;
|
|
158
|
+
async function startDevServer(args) {
|
|
159
|
+
await bootServer(args);
|
|
160
|
+
const filesToWatch = await getAllDependencies();
|
|
161
|
+
if (watcher) watcher.close();
|
|
162
|
+
watcher = chokidar.watch(filesToWatch, { ignoreInitial: true });
|
|
113
163
|
|
|
114
|
-
|
|
164
|
+
const reload = debounce(async (f) => {
|
|
165
|
+
await bootServer(args);
|
|
166
|
+
const prettyPath = concolor.dim(path.relative(process.cwd(), f));
|
|
167
|
+
logger.info(`${concolor.green('server reload')} ${prettyPath}`);
|
|
168
|
+
}, 100);
|
|
115
169
|
|
|
170
|
+
watcher.on('change', reload);
|
|
171
|
+
watcher.on('add', reload);
|
|
172
|
+
watcher.on('unlink', reload);
|
|
173
|
+
}
|
|
116
174
|
|
|
117
|
-
export default
|
|
175
|
+
export default startDevServer
|
package/src/helpers.js
CHANGED
|
@@ -19,34 +19,15 @@ export const conicon = {
|
|
|
19
19
|
success: '✔',
|
|
20
20
|
warning: '⚠',
|
|
21
21
|
error: '✖',
|
|
22
|
-
dot: '․',
|
|
23
|
-
pointer: '❯',
|
|
24
|
-
arrowRight: '→',
|
|
25
|
-
arrowDown: '↓',
|
|
26
|
-
arrowUp: '↑',
|
|
27
|
-
star: '★',
|
|
28
|
-
check: '✅',
|
|
29
|
-
cross: '❌',
|
|
30
|
-
question: '?',
|
|
31
|
-
ellipsis: '…',
|
|
32
|
-
clock: '⏱',
|
|
33
|
-
hourglass: '⏳',
|
|
34
|
-
rocket: '🚀',
|
|
35
|
-
bug: '🐞',
|
|
36
22
|
};
|
|
37
23
|
|
|
38
24
|
export const concolor = {
|
|
39
|
-
reset: (str) => `\x1b[0m${str}\x1b[0m`,
|
|
40
25
|
red: (str) => `\x1b[31m${str}\x1b[0m`,
|
|
41
26
|
green: (str) => `\x1b[32m${str}\x1b[0m`,
|
|
42
27
|
yellow: (str) => `\x1b[33m${str}\x1b[0m`,
|
|
43
28
|
blue: (str) => `\x1b[34m${str}\x1b[0m`,
|
|
44
|
-
magenta: (str) => `\x1b[35m${str}\x1b[0m`,
|
|
45
|
-
cyan: (str) => `\x1b[36m${str}\x1b[0m`,
|
|
46
|
-
white: (str) => `\x1b[37m${str}\x1b[0m`,
|
|
47
29
|
bold: (str) => `\x1b[1m${str}\x1b[0m`,
|
|
48
30
|
dim: (str) => `\x1b[2m${str}\x1b[0m`,
|
|
49
|
-
underline: (str) => `\x1b[4m${str}\x1b[0m`,
|
|
50
31
|
};
|
|
51
32
|
|
|
52
33
|
|
package/src/index.js
CHANGED
|
@@ -24,12 +24,10 @@ program
|
|
|
24
24
|
program
|
|
25
25
|
.command("build")
|
|
26
26
|
.description("Build the project")
|
|
27
|
-
.option("-f, --format <format>", "Output format (cjs, esm,
|
|
27
|
+
.option("-f, --format <format>", "Output format (cjs, esm, both)", "both")
|
|
28
28
|
.option("-b, --bundle <bundle>", "Bundle the project", false)
|
|
29
|
-
.option("-m, --minify <minify>", "Minify the output",
|
|
29
|
+
.option("-m, --minify <minify>", "Minify the output", false)
|
|
30
30
|
.option("-s, --sourcemap <sourcemap>", "Generate sourcemaps", true)
|
|
31
|
-
.option("-t, --target <target>", "Target ECMAScript version", "es2020")
|
|
32
|
-
.option("-p, --platform <platform>", "Platform to target (node, browser)", "")
|
|
33
31
|
.option("-d, --declaration <declaration>", "Generate TypeScript declaration files", true)
|
|
34
32
|
.action(build);
|
|
35
33
|
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import fs from 'fs'
|
|
4
|
-
import viteSetup from './vite.js';
|
|
5
|
-
const port = process.env.PORT || 3000;
|
|
6
|
-
const app = express();
|
|
7
|
-
const server = async (cb) => {
|
|
8
|
-
|
|
9
|
-
// get type from package.json
|
|
10
|
-
const pkg = path.join(process.cwd(), 'package.json');
|
|
11
|
-
let type = 'module';
|
|
12
|
-
if (fs.existsSync(pkg)) {
|
|
13
|
-
const pkgjson = JSON.parse(fs.readFileSync(pkg, 'utf-8'));
|
|
14
|
-
type = pkgjson.type || 'module';
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (cb) {
|
|
18
|
-
cb(app)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// const mpack = path.join(process.cwd(), '.mpack');
|
|
22
|
-
// const uxp = path.join(mpack, 'uxp.js')
|
|
23
|
-
// if (fs.existsSync(uxp)) {
|
|
24
|
-
// // load user-express.js based on type
|
|
25
|
-
// if (type === 'module') {
|
|
26
|
-
// const { default: userExpress } = await import(uxp);
|
|
27
|
-
// userExpress(app);
|
|
28
|
-
// } else {
|
|
29
|
-
// const userExpress = require(uxp).default;
|
|
30
|
-
// userExpress(app);
|
|
31
|
-
// }
|
|
32
|
-
// }
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
await viteSetup(app)
|
|
36
|
-
app.use((_req, res) => {
|
|
37
|
-
res.status(500).send('Internal Server Error');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
app.listen(port, () => {
|
|
41
|
-
console.log(`Server is running on: http://localhost:${port}`);
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export default server;
|