easybuild-nox 1.0.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/LICENSE +21 -0
- package/README.md +405 -0
- package/bin/easy.js +71 -0
- package/easy.config.js +58 -0
- package/package.json +69 -0
- package/src/commands/analyze.js +203 -0
- package/src/commands/build.js +80 -0
- package/src/commands/clean.js +109 -0
- package/src/commands/config.js +104 -0
- package/src/commands/db.js +423 -0
- package/src/commands/deploy.js +203 -0
- package/src/commands/dev.js +188 -0
- package/src/commands/docker.js +264 -0
- package/src/commands/electron.js +210 -0
- package/src/commands/env.js +302 -0
- package/src/commands/generate.js +556 -0
- package/src/commands/health.js +261 -0
- package/src/commands/info.js +139 -0
- package/src/commands/init.js +794 -0
- package/src/commands/lint.js +111 -0
- package/src/commands/modules.js +333 -0
- package/src/commands/package.js +265 -0
- package/src/commands/proxy.js +73 -0
- package/src/commands/run.js +199 -0
- package/src/commands/test.js +104 -0
- package/src/index.js +30 -0
- package/src/targets/docker.js +201 -0
- package/src/targets/electron.js +157 -0
- package/src/targets/frontend.js +391 -0
- package/src/targets/library.js +164 -0
- package/src/targets/node.js +146 -0
- package/src/utils/config.js +191 -0
- package/src/utils/detector.js +407 -0
- package/src/utils/globalConfig.js +106 -0
- package/src/utils/logger.js +98 -0
- package/src/utils/modules.js +571 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
const { spawn } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs-extra');
|
|
4
|
+
const logger = require('../utils/logger');
|
|
5
|
+
|
|
6
|
+
class NodeBuilder {
|
|
7
|
+
constructor(projectInfo, config) {
|
|
8
|
+
this.projectInfo = projectInfo;
|
|
9
|
+
this.config = config;
|
|
10
|
+
this.outDir = config.outDir || 'dist';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async build(options) {
|
|
14
|
+
logger.section('Building Node.js Application');
|
|
15
|
+
|
|
16
|
+
// Determine bundler
|
|
17
|
+
const bundler = this.projectInfo.bundler || 'esbuild';
|
|
18
|
+
|
|
19
|
+
switch (bundler) {
|
|
20
|
+
case 'esbuild':
|
|
21
|
+
await this.buildWithEsbuild(options);
|
|
22
|
+
break;
|
|
23
|
+
case 'webpack':
|
|
24
|
+
await this.buildWithWebpack(options);
|
|
25
|
+
break;
|
|
26
|
+
case 'rollup':
|
|
27
|
+
await this.buildWithRollup(options);
|
|
28
|
+
break;
|
|
29
|
+
case 'vite':
|
|
30
|
+
await this.buildWithVite(options);
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
await this.buildWithEsbuild(options);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async buildWithEsbuild(options) {
|
|
38
|
+
logger.info('Building with esbuild...');
|
|
39
|
+
|
|
40
|
+
const pkg = await fs.readJson(path.join(process.cwd(), 'package.json'));
|
|
41
|
+
const entryPoint = this.config.entry || pkg.main || 'src/index.js';
|
|
42
|
+
|
|
43
|
+
const args = [
|
|
44
|
+
'esbuild',
|
|
45
|
+
entryPoint,
|
|
46
|
+
'--bundle',
|
|
47
|
+
'--platform=node',
|
|
48
|
+
'--target=node20',
|
|
49
|
+
`--outdir=${options.outDir || this.outDir}`,
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
if (options.minify) args.push('--minify');
|
|
53
|
+
if (options.sourcemap) args.push('--sourcemap');
|
|
54
|
+
if (this.config.format === 'esm') args.push('--format=esm');
|
|
55
|
+
|
|
56
|
+
// External dependencies
|
|
57
|
+
const externals = Object.keys(pkg.dependencies || {});
|
|
58
|
+
if (externals.length > 0) {
|
|
59
|
+
args.push(`--external:${externals.join(',')}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const child = spawn('npx', args, {
|
|
63
|
+
stdio: 'inherit',
|
|
64
|
+
shell: true,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
child.on('close', (code) => {
|
|
69
|
+
if (code === 0) {
|
|
70
|
+
logger.success('Build completed with esbuild');
|
|
71
|
+
resolve();
|
|
72
|
+
} else {
|
|
73
|
+
reject(new Error('esbuild build failed'));
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async buildWithWebpack(options) {
|
|
80
|
+
logger.info('Building with webpack...');
|
|
81
|
+
|
|
82
|
+
const args = ['webpack', '--mode', 'production'];
|
|
83
|
+
|
|
84
|
+
const child = spawn('npx', args, {
|
|
85
|
+
stdio: 'inherit',
|
|
86
|
+
shell: true,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
child.on('close', (code) => {
|
|
91
|
+
if (code === 0) {
|
|
92
|
+
logger.success('Build completed with webpack');
|
|
93
|
+
resolve();
|
|
94
|
+
} else {
|
|
95
|
+
reject(new Error('webpack build failed'));
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async buildWithRollup(options) {
|
|
102
|
+
logger.info('Building with Rollup...');
|
|
103
|
+
|
|
104
|
+
const args = ['rollup', '-c'];
|
|
105
|
+
|
|
106
|
+
const child = spawn('npx', args, {
|
|
107
|
+
stdio: 'inherit',
|
|
108
|
+
shell: true,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return new Promise((resolve, reject) => {
|
|
112
|
+
child.on('close', (code) => {
|
|
113
|
+
if (code === 0) {
|
|
114
|
+
logger.success('Build completed with Rollup');
|
|
115
|
+
resolve();
|
|
116
|
+
} else {
|
|
117
|
+
reject(new Error('Rollup build failed'));
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async buildWithVite(options) {
|
|
124
|
+
logger.info('Building with Vite...');
|
|
125
|
+
|
|
126
|
+
const args = ['vite', 'build'];
|
|
127
|
+
|
|
128
|
+
const child = spawn('npx', args, {
|
|
129
|
+
stdio: 'inherit',
|
|
130
|
+
shell: true,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
child.on('close', (code) => {
|
|
135
|
+
if (code === 0) {
|
|
136
|
+
logger.success('Build completed with Vite');
|
|
137
|
+
resolve();
|
|
138
|
+
} else {
|
|
139
|
+
reject(new Error('Vite build failed'));
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = NodeBuilder;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const CONFIG_FILE_NAMES = [
|
|
5
|
+
'easy.config.js',
|
|
6
|
+
'easy.config.mjs',
|
|
7
|
+
'easy.config.ts',
|
|
8
|
+
'easy.config.json',
|
|
9
|
+
'.easyrc',
|
|
10
|
+
'.easyrc.json',
|
|
11
|
+
'.easyrc.js',
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const DEFAULT_CONFIG = {
|
|
15
|
+
// Project settings
|
|
16
|
+
name: 'my-app',
|
|
17
|
+
version: '1.0.0',
|
|
18
|
+
description: '',
|
|
19
|
+
|
|
20
|
+
// Build settings
|
|
21
|
+
entry: 'src/index.js',
|
|
22
|
+
outDir: 'dist',
|
|
23
|
+
target: 'node',
|
|
24
|
+
format: 'cjs',
|
|
25
|
+
platform: 'current',
|
|
26
|
+
|
|
27
|
+
// TypeScript
|
|
28
|
+
typescript: {
|
|
29
|
+
enabled: false,
|
|
30
|
+
tsconfig: 'tsconfig.json',
|
|
31
|
+
declaration: true,
|
|
32
|
+
sourceMap: true,
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
// Development
|
|
36
|
+
dev: {
|
|
37
|
+
port: 3000,
|
|
38
|
+
host: 'localhost',
|
|
39
|
+
open: true,
|
|
40
|
+
watch: true,
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
// Production build
|
|
44
|
+
build: {
|
|
45
|
+
minify: true,
|
|
46
|
+
sourcemap: false,
|
|
47
|
+
analyze: false,
|
|
48
|
+
clean: true,
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
// Electron
|
|
52
|
+
electron: {
|
|
53
|
+
enabled: false,
|
|
54
|
+
main: 'electron/main.js',
|
|
55
|
+
preload: 'electron/preload.js',
|
|
56
|
+
renderer: 'electron/renderer',
|
|
57
|
+
output: 'release',
|
|
58
|
+
platforms: ['win', 'mac', 'linux'],
|
|
59
|
+
arch: ['x64', 'arm64'],
|
|
60
|
+
icon: null,
|
|
61
|
+
asar: true,
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
// Docker
|
|
65
|
+
docker: {
|
|
66
|
+
enabled: false,
|
|
67
|
+
baseImage: 'node:20-alpine',
|
|
68
|
+
workdir: '/app',
|
|
69
|
+
port: 3000,
|
|
70
|
+
output: 'Dockerfile',
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
// Cloud deployment
|
|
74
|
+
deploy: {
|
|
75
|
+
provider: null,
|
|
76
|
+
region: 'us-east-1',
|
|
77
|
+
runtime: 'nodejs20.x',
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
// Monorepo
|
|
81
|
+
monorepo: {
|
|
82
|
+
enabled: false,
|
|
83
|
+
packages: ['packages/*'],
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// Testing
|
|
87
|
+
test: {
|
|
88
|
+
framework: 'node',
|
|
89
|
+
coverage: false,
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
// Linting
|
|
93
|
+
lint: {
|
|
94
|
+
enabled: false,
|
|
95
|
+
eslint: true,
|
|
96
|
+
prettier: true,
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
class ConfigLoader {
|
|
101
|
+
constructor(rootDir = process.cwd()) {
|
|
102
|
+
this.rootDir = rootDir;
|
|
103
|
+
this.config = null;
|
|
104
|
+
this.userConfig = null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async load() {
|
|
108
|
+
// Load user config
|
|
109
|
+
this.userConfig = await this.loadUserConfig();
|
|
110
|
+
|
|
111
|
+
// Merge with defaults
|
|
112
|
+
this.config = this.mergeConfig(DEFAULT_CONFIG, this.userConfig || {});
|
|
113
|
+
|
|
114
|
+
// Apply environment-specific overrides
|
|
115
|
+
await this.applyEnvironmentOverrides();
|
|
116
|
+
|
|
117
|
+
return this.config;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async loadUserConfig() {
|
|
121
|
+
for (const configName of CONFIG_FILE_NAMES) {
|
|
122
|
+
const configPath = path.join(this.rootDir, configName);
|
|
123
|
+
if (await fs.pathExists(configPath)) {
|
|
124
|
+
try {
|
|
125
|
+
if (configName.endsWith('.json')) {
|
|
126
|
+
return await fs.readJson(configPath);
|
|
127
|
+
} else {
|
|
128
|
+
// For JS/MJS files, require them
|
|
129
|
+
delete require.cache[require.resolve(configPath)];
|
|
130
|
+
return require(configPath);
|
|
131
|
+
}
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error(`Error loading config from ${configName}:`, error.message);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
mergeConfig(defaults, user) {
|
|
141
|
+
const merged = { ...defaults };
|
|
142
|
+
|
|
143
|
+
for (const key of Object.keys(user)) {
|
|
144
|
+
if (typeof user[key] === 'object' && !Array.isArray(user[key]) && user[key] !== null) {
|
|
145
|
+
merged[key] = this.mergeConfig(defaults[key] || {}, user[key]);
|
|
146
|
+
} else {
|
|
147
|
+
merged[key] = user[key];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return merged;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async applyEnvironmentOverrides() {
|
|
155
|
+
const env = process.env.NODE_ENV || 'development';
|
|
156
|
+
|
|
157
|
+
if (env === 'production') {
|
|
158
|
+
this.config.build.minify = true;
|
|
159
|
+
this.config.build.sourcemap = false;
|
|
160
|
+
this.config.dev.watch = false;
|
|
161
|
+
} else if (env === 'development') {
|
|
162
|
+
this.config.build.minify = false;
|
|
163
|
+
this.config.build.sourcemap = true;
|
|
164
|
+
this.config.dev.watch = true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
get(key) {
|
|
169
|
+
return key.split('.').reduce((obj, k) => obj?.[k], this.config);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
set(key, value) {
|
|
173
|
+
const keys = key.split('.');
|
|
174
|
+
let obj = this.config;
|
|
175
|
+
|
|
176
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
177
|
+
if (!obj[keys[i]]) obj[keys[i]] = {};
|
|
178
|
+
obj = obj[keys[i]];
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
obj[keys[keys.length - 1]] = value;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
async save() {
|
|
185
|
+
const configPath = path.join(this.rootDir, 'easy.config.js');
|
|
186
|
+
const content = `module.exports = ${JSON.stringify(this.config, null, 2)};`;
|
|
187
|
+
await fs.writeFile(configPath, content);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
module.exports = ConfigLoader;
|