jizy-packer 2.0.6 → 2.1.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/README.md +119 -1
- package/lib/Build.js +105 -143
- package/lib/Cli.js +10 -11
- package/lib/Config.js +58 -18
- package/lib/Rollup.js +20 -91
- package/lib/index.js +1 -4
- package/lib/utils.js +75 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,2 +1,120 @@
|
|
|
1
|
+
|
|
1
2
|
# jizy-packer
|
|
2
|
-
|
|
3
|
+
|
|
4
|
+
A CLI tool and Node.js library to generate optimized builds for your projects. It provides utilities for configuration management, build orchestration, and file operations.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- Command-line interface for building projects
|
|
9
|
+
- Configurable via JSON and programmatic API
|
|
10
|
+
- Utilities for cleaning build folders and managing configs
|
|
11
|
+
- Rollup-based build process with plugin support
|
|
12
|
+
|
|
13
|
+
## Quick Usage
|
|
14
|
+
|
|
15
|
+
### CLI
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
node lib/Cli.js
|
|
19
|
+
node lib/Cli.js --action build --name perso --config { "key": "value" }
|
|
20
|
+
node lib/Cli.js --action build --name perso --config ABSOLUTE_PATH_TO_JSON_FILE
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Options:
|
|
24
|
+
- `--action, -a` Build action (dist|build)
|
|
25
|
+
- `--name, -n` Name of the build
|
|
26
|
+
- `--config, -c` Path to the custom config file or JSON string
|
|
27
|
+
- `--debug, -d` Enable debug mode
|
|
28
|
+
|
|
29
|
+
### Programmatic
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
import jPackBuild from './lib/Build.js';
|
|
33
|
+
|
|
34
|
+
await jPackBuild({
|
|
35
|
+
action: 'build',
|
|
36
|
+
name: 'perso',
|
|
37
|
+
config: 'PATH_TO_JSON_FILE',
|
|
38
|
+
debug: true
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Create a jPacker
|
|
43
|
+
|
|
44
|
+
Example from the "jizy-browser" extension.
|
|
45
|
+
|
|
46
|
+
***First for the default dist build***
|
|
47
|
+
|
|
48
|
+
#### ./config/config.json
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"desktopBreakpoint": "900px"
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### ./config/jpack.js
|
|
56
|
+
```js
|
|
57
|
+
import fs from 'fs';
|
|
58
|
+
import path from 'path';
|
|
59
|
+
import { LogMe, jPackConfig } from 'jizy-packer';
|
|
60
|
+
|
|
61
|
+
const jPackData = {
|
|
62
|
+
name: 'BrowserCompat',
|
|
63
|
+
alias: 'jizy-browser',
|
|
64
|
+
|
|
65
|
+
onCheckConfig: () => {
|
|
66
|
+
// add some config validation
|
|
67
|
+
const desktopBreakpoint = jPackConfig.get('desktopBreakpoint');
|
|
68
|
+
if (!desktopBreakpoint) {
|
|
69
|
+
LogMe.error('Missing desktopBreakpoint in config');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
// generate config.less
|
|
75
|
+
onGenerateBuildJs: (code) => {
|
|
76
|
+
LogMe.log('Generate config.less');
|
|
77
|
+
const desktopBreakpoint = jPackConfig.get('desktopBreakpoint') ?? '768px';
|
|
78
|
+
let lessContent = `@desktop-breakpoint: ${desktopBreakpoint};\n`;
|
|
79
|
+
lessContent += `@mobile-breakpoint: @desktop-breakpoint - 1px;`;
|
|
80
|
+
fs.writeFileSync(path.join(jPackConfig.get('targetPath'), 'config.less'), lessContent);
|
|
81
|
+
return code;
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
// parse wrapped js
|
|
85
|
+
onGenerateWrappedJs: (wrapped) => wrapped,
|
|
86
|
+
|
|
87
|
+
// after packing
|
|
88
|
+
onPacked: () => { }
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export default jPackData;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### ./config/jpack.template
|
|
95
|
+
```js
|
|
96
|
+
import BrowserCompat from '{{PREFIX}}lib/js/browsercompat.js';
|
|
97
|
+
import '{{PREFIX}}lib/browsercompat.less';
|
|
98
|
+
export default BrowserCompat;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### ./config/jpack.wrapper.js
|
|
102
|
+
```js
|
|
103
|
+
/*! BrowserCompat v@VERSION | @DATE | [@BUNDLE] */
|
|
104
|
+
(function (global) {
|
|
105
|
+
"use strict";
|
|
106
|
+
|
|
107
|
+
if (typeof global !== "object" || !global || !global.document) {
|
|
108
|
+
throw new Error("BrowserCompat requires a window and a document");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (typeof global.BrowserCompat !== "undefined") {
|
|
112
|
+
throw new Error("BrowserCompat is already defined");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// @CODE
|
|
116
|
+
|
|
117
|
+
global.BrowserCompat = BrowserCompat;
|
|
118
|
+
|
|
119
|
+
})(typeof window !== "undefined" ? window : this);
|
|
120
|
+
```
|
package/lib/Build.js
CHANGED
|
@@ -5,189 +5,151 @@ import { rollup } from 'rollup';
|
|
|
5
5
|
import LogMe from "./LogMe.js";
|
|
6
6
|
import jPackConfig from "./Config.js";
|
|
7
7
|
import jPackRollup from "./Rollup.js";
|
|
8
|
-
import {
|
|
8
|
+
import { emptyTargetPath, loadJson } from "./utils.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {string} action the build action (dist|build) defaults to dist
|
|
12
|
+
* @param {string} name the name of the build ([a-z0-9\-\_])
|
|
13
|
+
* @param {string } config the path to the custom config.json file
|
|
14
|
+
* @param {boolean} debug for verbose logging
|
|
15
|
+
*
|
|
16
|
+
* 1. build dist default export
|
|
17
|
+
* no params
|
|
18
|
+
* default package config
|
|
19
|
+
* use ./config/jpack.js
|
|
20
|
+
* use ./config/config.json
|
|
21
|
+
* 2. build custom config
|
|
22
|
+
* name (default to custom)
|
|
23
|
+
* default package config
|
|
24
|
+
* use ./config/jpack.js
|
|
25
|
+
* use ./config/config.json
|
|
26
|
+
* custom package config
|
|
27
|
+
* use [ABS_PATH_TO_CONFIG].json or json string
|
|
28
|
+
*/
|
|
9
29
|
|
|
10
30
|
export default async function jPackBuild({
|
|
11
|
-
|
|
31
|
+
action = null,
|
|
12
32
|
name = null,
|
|
13
|
-
|
|
33
|
+
config = null,
|
|
14
34
|
debug = false
|
|
15
35
|
} = {}) {
|
|
16
36
|
|
|
17
|
-
LogMe.log('---');
|
|
18
|
-
|
|
19
37
|
if (debug) {
|
|
20
38
|
process.env.DEBUG = true;
|
|
21
39
|
}
|
|
22
40
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (!target || target === 'dist') {
|
|
26
|
-
target = '';
|
|
27
|
-
name = '';
|
|
28
|
-
zip = false;
|
|
41
|
+
if (!action || action !== 'build') {
|
|
42
|
+
action = 'dist';
|
|
29
43
|
}
|
|
30
44
|
|
|
31
|
-
if (
|
|
32
|
-
|
|
45
|
+
if (config) {
|
|
46
|
+
action = 'build';
|
|
33
47
|
}
|
|
34
48
|
|
|
35
|
-
if (
|
|
36
|
-
name = 'export';
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!name) {
|
|
49
|
+
if (action === 'dist') {
|
|
40
50
|
name = 'default';
|
|
51
|
+
config = null;
|
|
52
|
+
} else {
|
|
53
|
+
// Sanitize the build folder name
|
|
54
|
+
if (name) {
|
|
55
|
+
name = name.replace(/[^a-zA-Z0-9\-\_]/g, '');
|
|
56
|
+
name = name.toLowerCase();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!name) {
|
|
60
|
+
name = 'custom';
|
|
61
|
+
}
|
|
41
62
|
}
|
|
42
63
|
|
|
43
|
-
LogMe.log('
|
|
44
|
-
LogMe.log('
|
|
45
|
-
LogMe.log('
|
|
46
|
-
LogMe.log('
|
|
64
|
+
LogMe.log('---');
|
|
65
|
+
LogMe.log('action: ' + action);
|
|
66
|
+
LogMe.log('name: ' + name);
|
|
67
|
+
LogMe.log('config: ' + (config ? 'yes' : 'no'));
|
|
68
|
+
LogMe.log('debug: ' + (debug ? 'enabled' : 'disabled'));
|
|
47
69
|
LogMe.log('---');
|
|
48
70
|
|
|
49
|
-
jPackConfig.set('buildZip', zip);
|
|
50
71
|
jPackConfig.set('buildName', name);
|
|
72
|
+
jPackConfig.set('action', action);
|
|
73
|
+
jPackConfig.set('debug', debug);
|
|
51
74
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
targetPath = path.join(jPackConfig.get('basePath'), 'build', target);
|
|
55
|
-
jPackConfig.set('buildTarget', targetPath);
|
|
56
|
-
if (!fs.existsSync(targetPath)) {
|
|
57
|
-
fs.mkdirSync(targetPath, { recursive: true });
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
LogMe.log('Empty or create dist directory');
|
|
61
|
-
targetPath = path.join(jPackConfig.get('basePath'), 'dist');
|
|
62
|
-
jPackConfig.set('buildTarget', targetPath);
|
|
63
|
-
cleanBuildFolder(targetPath);
|
|
64
|
-
|
|
65
|
-
const targetCfgPath = path.join(targetPath, 'config.json');
|
|
66
|
-
if (!fs.existsSync(targetCfgPath)) {
|
|
67
|
-
const defaultCfgPath = path.join(jPackConfig.get('basePath'), 'config', 'config.json');
|
|
68
|
-
if (fs.existsSync(defaultCfgPath)) {
|
|
69
|
-
LogMe.log('Copy default config.json file');
|
|
70
|
-
fs.copyFileSync(defaultCfgPath, targetCfgPath);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
75
|
+
try {
|
|
76
|
+
LogMe.log('Load jPack config');
|
|
74
77
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (fs.existsSync(defaultCfgPath)) {
|
|
79
|
-
LogMe.log('Copy default config.json file');
|
|
80
|
-
fs.copyFileSync(defaultCfgPath, targetCfgPath);
|
|
78
|
+
const jpack = path.join(jPackConfig.get('basePath'), 'config', 'jpack.js');
|
|
79
|
+
if (!fs.existsSync(jpack)) {
|
|
80
|
+
throw new Error('Default jPack config not found in ' + jpack);
|
|
81
81
|
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (fs.existsSync(defaultCfgPath)) {
|
|
85
|
-
LogMe.log('Load default config file');
|
|
86
|
-
LogMe.log(defaultCfgPath);
|
|
87
|
-
jPackConfig.loadFromJson(defaultCfgPath);
|
|
88
|
-
}
|
|
89
82
|
|
|
90
|
-
|
|
91
|
-
if (fs.existsSync(cfgPath)) {
|
|
92
|
-
LogMe.log(`Load client config file`);
|
|
93
|
-
LogMe.log(cfgPath);
|
|
94
|
-
jPackConfig.loadFromJson(cfgPath);
|
|
95
|
-
}
|
|
83
|
+
require(jpack);
|
|
96
84
|
|
|
97
|
-
try {
|
|
98
85
|
jPackConfig.setPackageVersion();
|
|
99
|
-
checkConfig();
|
|
100
|
-
await doBuild();
|
|
101
86
|
} catch (error) {
|
|
102
|
-
LogMe.error(`Failed to load configuration file: ${cfgPath}`);
|
|
103
87
|
LogMe.error(error.message);
|
|
104
88
|
process.exit(1);
|
|
105
89
|
}
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
async function doBuild() {
|
|
109
|
-
LogMe.log('---');
|
|
110
|
-
LogMe.dir(jPackConfig.all());
|
|
111
|
-
LogMe.log('---');
|
|
112
90
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
91
|
+
if (config) {
|
|
92
|
+
LogMe.log('Load the build config');
|
|
93
|
+
try {
|
|
94
|
+
if (config.substr(0, 1) === '{') {
|
|
95
|
+
LogMe.log(' JSON string');
|
|
96
|
+
jPackConfig.sets(JSON.parse(config));
|
|
97
|
+
} else {
|
|
98
|
+
LogMe.log(' JSON file');
|
|
99
|
+
jPackConfig.sets(loadJson(config));
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
LogMe.error(' ' + error.message);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
117
106
|
|
|
118
|
-
|
|
119
|
-
file: jPackConfig.get('assetsPath') + '/js/' + jPackConfig.get('alias') + '.min.js',
|
|
120
|
-
format: "iife",
|
|
121
|
-
name: jPackConfig.get('name'),
|
|
122
|
-
sourcemap: false,
|
|
123
|
-
};
|
|
107
|
+
jPackConfig.validate();
|
|
124
108
|
|
|
125
109
|
try {
|
|
126
|
-
LogMe.log('
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
LogMe.log('Rollup build completed successfully.');
|
|
110
|
+
LogMe.log('Empty the target directory');
|
|
111
|
+
LogMe.log(' TargetPath: ' + jPackConfig.get('targetPath'));
|
|
112
|
+
emptyTargetPath(jPackConfig.get('targetPath'));
|
|
130
113
|
} catch (error) {
|
|
131
|
-
|
|
114
|
+
LogMe.error(' ' + error.message);
|
|
132
115
|
process.exit(1);
|
|
133
116
|
}
|
|
134
|
-
}
|
|
135
117
|
|
|
136
|
-
|
|
137
|
-
LogMe.log('checkTargetDirectory()');
|
|
118
|
+
LogMe.log('Launch build ...');
|
|
138
119
|
|
|
139
|
-
|
|
140
|
-
LogMe.
|
|
141
|
-
|
|
142
|
-
|
|
120
|
+
try {
|
|
121
|
+
LogMe.log('---');
|
|
122
|
+
LogMe.dir(jPackConfig.all());
|
|
123
|
+
LogMe.log('---');
|
|
124
|
+
|
|
125
|
+
const inputOptions = {
|
|
126
|
+
input: jPackConfig.get('buildJsFilePath'),
|
|
127
|
+
plugins: jPackRollup(),
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const outputOptions = {
|
|
131
|
+
file: jPackConfig.get('targetRelativePath') + '/js/' + jPackConfig.get('alias') + '.min.js',
|
|
132
|
+
format: "iife",
|
|
133
|
+
name: jPackConfig.get('name'),
|
|
134
|
+
sourcemap: false,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
LogMe.log('Starting Rollup build...');
|
|
139
|
+
const bundle = await rollup(inputOptions);
|
|
140
|
+
await bundle.write(outputOptions);
|
|
141
|
+
LogMe.log('Rollup build completed successfully.');
|
|
142
|
+
} catch (error) {
|
|
143
|
+
console.error('Error during Rollup build:', error);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
143
146
|
|
|
144
|
-
|
|
145
|
-
LogMe.
|
|
147
|
+
LogMe.log('---');
|
|
148
|
+
LogMe.log('Build completed successfully');
|
|
149
|
+
LogMe.log('---');
|
|
146
150
|
process.exit(1);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const cfgPath = path.join(targetPath, 'config.json');
|
|
150
|
-
|
|
151
|
-
if (!fs.existsSync(cfgPath)) {
|
|
152
|
-
LogMe.warn(' config.json not found in target path');
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const files = fs.readdirSync(targetPath)
|
|
157
|
-
.filter(file => file !== 'config.json');
|
|
158
|
-
|
|
159
|
-
if (files.length > 0) {
|
|
160
|
-
LogMe.error('Build target can only contain config.json');
|
|
151
|
+
} catch (error) {
|
|
152
|
+
LogMe.error(error.message);
|
|
161
153
|
process.exit(1);
|
|
162
154
|
}
|
|
163
|
-
|
|
164
|
-
return cfgPath;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function checkConfig() {
|
|
168
|
-
const basePath = jPackConfig.get('basePath');
|
|
169
|
-
|
|
170
|
-
const buildName = jPackConfig.get('buildName')
|
|
171
|
-
.replace(/[^a-zA-Z0-9]/g, ''); // Sanitize the build folder name
|
|
172
|
-
|
|
173
|
-
jPackConfig.set('buildName', buildName);
|
|
174
|
-
|
|
175
|
-
if (buildName === 'default') {
|
|
176
|
-
jPackConfig.set('assetsPath', 'dist');
|
|
177
|
-
jPackConfig.set('importPrefix', '../');
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
jPackConfig.set('assetsPath', 'build/' + buildName);
|
|
181
|
-
jPackConfig.set('importPrefix', '../../');
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
jPackConfig.set('assetsFullpath', path.join(basePath, jPackConfig.get('assetsPath')));
|
|
185
|
-
jPackConfig.set('buildJsFilePath', path.join(basePath, jPackConfig.get('assetsPath'), 'build.js'));
|
|
186
|
-
jPackConfig.set('buildTemplatePath', path.join(basePath, 'config', 'jpack.template'));
|
|
187
|
-
jPackConfig.set('wrapperPath', path.join(basePath, 'config', 'jpack.wrapper.js'));
|
|
188
|
-
|
|
189
|
-
const onCheckConfig = jPackConfig.get('onCheckConfig');
|
|
190
|
-
if (typeof onCheckConfig === 'function') {
|
|
191
|
-
onCheckConfig();
|
|
192
|
-
}
|
|
193
|
-
}
|
|
155
|
+
};
|
package/lib/Cli.js
CHANGED
|
@@ -3,17 +3,16 @@ import { hideBin } from 'yargs/helpers';
|
|
|
3
3
|
import jPackBuild from "./Build.js";
|
|
4
4
|
import jPackConfig from "./Config.js";
|
|
5
5
|
|
|
6
|
-
const jPackCli = function (
|
|
6
|
+
const jPackCli = function () {
|
|
7
7
|
jPackConfig.set('basePath', process.cwd());
|
|
8
|
-
jPackConfig.sets(cfg);
|
|
9
8
|
|
|
10
9
|
const command = yargs(hideBin(process.argv))
|
|
11
10
|
.usage('Usage: $0 <command> [options]')
|
|
12
|
-
.option('
|
|
13
|
-
alias: '
|
|
11
|
+
.option('action', {
|
|
12
|
+
alias: 'a',
|
|
14
13
|
type: 'string',
|
|
15
|
-
description: '
|
|
16
|
-
default: '',
|
|
14
|
+
description: 'Set the build action (dist or build)',
|
|
15
|
+
default: 'dist',
|
|
17
16
|
})
|
|
18
17
|
.option('name', {
|
|
19
18
|
alias: 'n',
|
|
@@ -21,11 +20,11 @@ const jPackCli = function (cfg) {
|
|
|
21
20
|
description: 'Set the build name',
|
|
22
21
|
default: '',
|
|
23
22
|
})
|
|
24
|
-
.option('
|
|
25
|
-
alias: '
|
|
26
|
-
type: '
|
|
27
|
-
description: '
|
|
28
|
-
default:
|
|
23
|
+
.option('config', {
|
|
24
|
+
alias: 'c',
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'Custom config absolute path or json string',
|
|
27
|
+
default: '',
|
|
29
28
|
})
|
|
30
29
|
.option('debug', {
|
|
31
30
|
alias: 'd',
|
package/lib/Config.js
CHANGED
|
@@ -4,6 +4,10 @@ import path from 'path';
|
|
|
4
4
|
const config = {};
|
|
5
5
|
|
|
6
6
|
const jPackConfig = {
|
|
7
|
+
/**
|
|
8
|
+
* Returns a shallow copy of the current config object
|
|
9
|
+
* replacing functions with 'fn'.
|
|
10
|
+
*/
|
|
7
11
|
all: function () {
|
|
8
12
|
const result = {};
|
|
9
13
|
for (const key in config) {
|
|
@@ -17,54 +21,90 @@ const jPackConfig = {
|
|
|
17
21
|
return result;
|
|
18
22
|
},
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const data = fs.readFileSync(cfgPath, 'utf8');
|
|
26
|
-
const json = JSON.parse(data);
|
|
27
|
-
this.sets(json);
|
|
28
|
-
},
|
|
29
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Loads the version from package.json and sets it in the config under 'version'.
|
|
26
|
+
*/
|
|
30
27
|
setPackageVersion: function () {
|
|
31
28
|
const pkgPath = path.join(jPackConfig.get('basePath'), 'package.json');
|
|
29
|
+
|
|
32
30
|
if (fs.existsSync(pkgPath)) {
|
|
33
31
|
const data = fs.readFileSync(pkgPath, 'utf8');
|
|
34
32
|
const json = JSON.parse(data);
|
|
33
|
+
|
|
35
34
|
if (json.version) {
|
|
36
35
|
this.set('version', json.version);
|
|
36
|
+
return;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
|
|
40
|
+
this.set('version', '0.0.1');
|
|
39
41
|
},
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Validates and prepares the config object, setting paths and defaults as needed.
|
|
45
|
+
* Throws if required fields are missing.
|
|
46
|
+
*/
|
|
47
|
+
validate: function () {
|
|
42
48
|
if (!config.basePath) {
|
|
43
49
|
throw new Error('Invalid configuration: basePath is required.');
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
if (!config.
|
|
47
|
-
throw new Error('Invalid configuration:
|
|
52
|
+
if (!config.buildName) {
|
|
53
|
+
throw new Error('Invalid configuration: buildName is required.');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (config.action === 'dist') {
|
|
57
|
+
config.importPrefix = '../';
|
|
58
|
+
config.targetRelativePath = 'dist';
|
|
59
|
+
config.targetPath = path.join(config.basePath, 'dist');
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
config.importPrefix = '../../';
|
|
63
|
+
config.targetPath = path.join(config.basePath, 'build', config.buildName);
|
|
64
|
+
config.targetRelativePath = 'build/' + config.buildName;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
config.buildJsFilePath = path.join(config.targetPath, 'build.js');
|
|
68
|
+
config.buildTemplatePath = path.join(config.basePath, 'config', 'jpack.template');
|
|
69
|
+
config.wrapperPath = path.join(config.basePath, 'config', 'jpack.wrapper.js');
|
|
70
|
+
|
|
71
|
+
if (typeof config.onCheckConfig === 'function') {
|
|
72
|
+
config.onCheckConfig();
|
|
48
73
|
}
|
|
49
74
|
|
|
50
75
|
if (!config.alias) {
|
|
51
76
|
config.alias = config.name.toLowerCase();
|
|
52
77
|
config.alias = config.alias.replace(/\s+/g, '-');
|
|
53
78
|
}
|
|
54
|
-
|
|
55
|
-
if (!config.cfg) {
|
|
56
|
-
config.cfg = config.alias;
|
|
57
|
-
}
|
|
58
79
|
},
|
|
59
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Merges a new config object into the current config.
|
|
83
|
+
* @param {Object} newConfig - The config object to merge.
|
|
84
|
+
*/
|
|
60
85
|
sets: (newConfig) => {
|
|
61
|
-
|
|
86
|
+
if (typeof newConfig !== 'object' || newConfig === null) {
|
|
87
|
+
throw new Error('Invalid configuration: newConfig must be an object.');
|
|
88
|
+
}
|
|
89
|
+
newConfig.array.forEach(element => {
|
|
90
|
+
this.set(element, newConfig[element]);
|
|
91
|
+
});
|
|
62
92
|
},
|
|
63
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Gets a config value by key, or returns the default if not set.
|
|
96
|
+
* @param {string} key - The config key.
|
|
97
|
+
* @param {*} def - The default value if key is not set.
|
|
98
|
+
*/
|
|
64
99
|
get(key, def) {
|
|
65
100
|
return config[key] || def;
|
|
66
101
|
},
|
|
67
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Sets a config value by key.
|
|
105
|
+
* @param {string} key - The config key.
|
|
106
|
+
* @param {*} value - The value to set.
|
|
107
|
+
*/
|
|
68
108
|
set(key, value) {
|
|
69
109
|
config[key] = value;
|
|
70
110
|
}
|
package/lib/Rollup.js
CHANGED
|
@@ -6,22 +6,18 @@ import json from "@rollup/plugin-json";
|
|
|
6
6
|
import resolve from "@rollup/plugin-node-resolve";
|
|
7
7
|
import commonjs from "@rollup/plugin-commonjs";
|
|
8
8
|
import terser from '@rollup/plugin-terser';
|
|
9
|
-
import { execSync } from 'child_process';
|
|
10
9
|
|
|
11
10
|
import jPackConfig from "./Config.js";
|
|
12
11
|
import LogMe from "./LogMe.js";
|
|
13
|
-
import {
|
|
12
|
+
import { emptyTargetPath } from './utils.js';
|
|
14
13
|
|
|
15
14
|
export default async function jPackRollup(config) {
|
|
16
|
-
const assetsPath = jPackConfig.get('assetsPath');
|
|
17
|
-
|
|
18
15
|
return [
|
|
19
16
|
{
|
|
20
17
|
name: 'beforeBuild',
|
|
21
18
|
buildStart() {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
cleanBuildFolder(assetsPath);
|
|
19
|
+
LogMe.log('Prepare build folder');
|
|
20
|
+
emptyTargetPath(jPackConfig.get('targetPath'));
|
|
25
21
|
},
|
|
26
22
|
},
|
|
27
23
|
|
|
@@ -44,7 +40,7 @@ export default async function jPackRollup(config) {
|
|
|
44
40
|
limit: 0,
|
|
45
41
|
emitFiles: true,
|
|
46
42
|
fileName: '[name][extname]',
|
|
47
|
-
destDir:
|
|
43
|
+
destDir: jPackConfig.get('targetRelativePath') + '/fonts/',
|
|
48
44
|
}),
|
|
49
45
|
|
|
50
46
|
url({
|
|
@@ -52,7 +48,7 @@ export default async function jPackRollup(config) {
|
|
|
52
48
|
limit: 0,
|
|
53
49
|
emitFiles: true,
|
|
54
50
|
fileName: '[name][extname]',
|
|
55
|
-
destDir:
|
|
51
|
+
destDir: jPackConfig.get('targetRelativePath') + '/images/',
|
|
56
52
|
}),
|
|
57
53
|
|
|
58
54
|
json(), // Handle JSON imports
|
|
@@ -77,6 +73,9 @@ export default async function jPackRollup(config) {
|
|
|
77
73
|
];
|
|
78
74
|
};
|
|
79
75
|
|
|
76
|
+
function cleanBuildFolder() {
|
|
77
|
+
}
|
|
78
|
+
|
|
80
79
|
function generateBuildJs() {
|
|
81
80
|
LogMe.log('Generate the build.js file ...');
|
|
82
81
|
|
|
@@ -154,13 +153,13 @@ function onPacked() {
|
|
|
154
153
|
|
|
155
154
|
function moveCssFiles() {
|
|
156
155
|
LogMe.log('Moving CSS files from js/ to css/ ...');
|
|
157
|
-
const
|
|
156
|
+
const targetPath = jPackConfig.get('targetPath');
|
|
158
157
|
|
|
159
|
-
fs.readdirSync(
|
|
158
|
+
fs.readdirSync(targetRelativePath + '/js')
|
|
160
159
|
.filter(file => file.endsWith('.css'))
|
|
161
160
|
.forEach(file => {
|
|
162
|
-
const oldPath = path.join(
|
|
163
|
-
const newPath = path.join(
|
|
161
|
+
const oldPath = path.join(targetRelativePath + '/js', file);
|
|
162
|
+
const newPath = path.join(targetRelativePath + '/css', file);
|
|
164
163
|
fs.mkdirSync(path.dirname(newPath), { recursive: true });
|
|
165
164
|
fs.renameSync(oldPath, newPath);
|
|
166
165
|
LogMe.log('- ' + file);
|
|
@@ -176,83 +175,13 @@ function cleanupBuild() {
|
|
|
176
175
|
fs.unlinkSync(jPackConfig.get('buildJsFilePath'));
|
|
177
176
|
}
|
|
178
177
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
execSync(`cd ${jPackConfig.get('assetsFullpath')} && zip -r ${zipFilePath} .`, { stdio: 'inherit' });
|
|
187
|
-
LogMe.log('-> ' + zipFilePath);
|
|
188
|
-
|
|
189
|
-
if (jPackConfig.get('buildTarget')) {
|
|
190
|
-
LogMe.log('Transfer zip file ...');
|
|
191
|
-
const zipTargetPath = path.join(jPackConfig.get('buildTarget'), jPackConfig.get('buildName') + '.zip');
|
|
192
|
-
fs.copyFileSync(zipFilePath, zipTargetPath);
|
|
193
|
-
LogMe.log('-> ' + zipTargetPath);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
emptyBuildFolder = true;
|
|
197
|
-
ignoreRemove.push(zipFilePath);
|
|
198
|
-
}
|
|
199
|
-
else if (jPackConfig.get('buildTarget') && jPackConfig.get('assetsPath') !== 'dist') {
|
|
200
|
-
LogMe.log('Copy generated build folder ...');
|
|
201
|
-
|
|
202
|
-
fs.mkdirSync(jPackConfig.get('buildTarget'), { recursive: true });
|
|
203
|
-
|
|
204
|
-
// Iterate over the files and directories in jPackConfig.get('assetsPath')
|
|
205
|
-
fs.readdirSync(jPackConfig.get('assetsPath')).forEach(file => {
|
|
206
|
-
const sourcePath = path.join(jPackConfig.get('assetsPath'), file);
|
|
207
|
-
const destinationPath = path.join(jPackConfig.get('buildTarget'), file);
|
|
208
|
-
|
|
209
|
-
if (fs.lstatSync(sourcePath).isDirectory()) {
|
|
210
|
-
// Recursively copy directories
|
|
211
|
-
fs.mkdirSync(destinationPath, { recursive: true });
|
|
212
|
-
fs.readdirSync(sourcePath).forEach(subFile => {
|
|
213
|
-
const subSourcePath = path.join(sourcePath, subFile);
|
|
214
|
-
const subDestinationPath = path.join(destinationPath, subFile);
|
|
215
|
-
fs.copyFileSync(subSourcePath, subDestinationPath);
|
|
216
|
-
LogMe.log('- Copied file: ' + subDestinationPath);
|
|
217
|
-
});
|
|
218
|
-
} else {
|
|
219
|
-
// Copy files
|
|
220
|
-
fs.copyFileSync(sourcePath, destinationPath);
|
|
221
|
-
LogMe.log('- Copied file: ' + destinationPath);
|
|
178
|
+
fs.readdirSync(jPackConfig.get('targetPath')).forEach(file => {
|
|
179
|
+
const filePath = path.join(jPackConfig.get('targetPath'), file);
|
|
180
|
+
if (fs.lstatSync(filePath).isDirectory()) {
|
|
181
|
+
if (fs.readdirSync(filePath).length === 0) {
|
|
182
|
+
fs.rmdirSync(filePath);
|
|
183
|
+
LogMe.log('Removed empty folder: ' + filePath);
|
|
222
184
|
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
emptyBuildFolder = true;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if (emptyBuildFolder) {
|
|
229
|
-
LogMe.log('Cleaning up build folder ...');
|
|
230
|
-
|
|
231
|
-
fs.readdirSync(jPackConfig.get('assetsPath')).forEach(file => {
|
|
232
|
-
const filePath = path.join(jPackConfig.get('assetsPath'), file);
|
|
233
|
-
if (fs.lstatSync(filePath).isDirectory()) {
|
|
234
|
-
fs.rmSync(filePath, { recursive: true, force: true });
|
|
235
|
-
LogMe.log('Removed folder: ' + filePath);
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
if (filePath.endsWith('.zip')) {
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
fs.unlinkSync(filePath);
|
|
243
|
-
LogMe.log('Removed file: ' + filePath);
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
fs.readdirSync(jPackConfig.get('assetsPath')).forEach(file => {
|
|
249
|
-
const filePath = path.join(jPackConfig.get('assetsPath'), file);
|
|
250
|
-
if (fs.lstatSync(filePath).isDirectory()) {
|
|
251
|
-
if (fs.readdirSync(filePath).length === 0) {
|
|
252
|
-
fs.rmdirSync(filePath);
|
|
253
|
-
LogMe.log('Removed empty folder: ' + filePath);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
258
187
|
}
|
package/lib/index.js
CHANGED
|
@@ -3,14 +3,11 @@ import jPackCli from './Cli.js';
|
|
|
3
3
|
import jPackConfig from './Config.js';
|
|
4
4
|
import LogMe from './LogMe.js';
|
|
5
5
|
import jPackRollup from './Rollup.js';
|
|
6
|
-
import { removeEmptyDirs, cleanBuildFolder } from './utils.js';
|
|
7
6
|
|
|
8
7
|
export {
|
|
9
8
|
jPackBuild,
|
|
10
9
|
jPackCli,
|
|
11
10
|
jPackConfig,
|
|
12
11
|
LogMe,
|
|
13
|
-
jPackRollup
|
|
14
|
-
removeEmptyDirs,
|
|
15
|
-
cleanBuildFolder
|
|
12
|
+
jPackRollup
|
|
16
13
|
}
|
package/lib/utils.js
CHANGED
|
@@ -1,43 +1,87 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
|
|
3
4
|
import LogMe from './LogMe.js';
|
|
4
5
|
|
|
5
|
-
export function
|
|
6
|
-
if (!fs.existsSync(
|
|
6
|
+
export function emptyTargetPath(targetPath) {
|
|
7
|
+
if (!fs.existsSync(targetPath)) {
|
|
8
|
+
fs.mkdirSync(targetPath, { recursive: true });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (!fs.lstatSync(targetPath).isDirectory()) {
|
|
12
|
+
throw new Error(`Target path is not a directory`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let files = fs.readdirSync(targetPath);
|
|
7
16
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
17
|
+
if (files.length > 0) {
|
|
18
|
+
for (const file of files) {
|
|
19
|
+
const fullPath = path.join(targetPath, file);
|
|
20
|
+
if (fs.lstatSync(fullPath).isDirectory()) {
|
|
21
|
+
try {
|
|
22
|
+
emptyTargetPath(fullPath);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
LogMe.error('Failed to empty directory: ' + fullPath);
|
|
25
|
+
LogMe.error(error.message);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
fs.unlinkSync(fullPath);
|
|
30
|
+
LogMe.log(' [RM] ' + fullPath);
|
|
31
|
+
}
|
|
13
32
|
}
|
|
33
|
+
|
|
34
|
+
files = fs.readdirSync(targetPath);
|
|
14
35
|
}
|
|
15
36
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
fs.rmdirSync(
|
|
37
|
+
if (files.length === 0) {
|
|
38
|
+
LogMe.log(' [RM] ' + targetPath);
|
|
39
|
+
fs.rmdirSync(targetPath);
|
|
19
40
|
}
|
|
20
41
|
};
|
|
21
42
|
|
|
22
|
-
export function
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
fs.
|
|
41
|
-
|
|
43
|
+
export function loadJson(filePath) {
|
|
44
|
+
try {
|
|
45
|
+
if (!fs.existsSync(filePath)) {
|
|
46
|
+
throw new Error('File not found');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const data = fs.readFileSync(filePath, 'utf8');
|
|
50
|
+
const json = JSON.parse(data);
|
|
51
|
+
return json;
|
|
52
|
+
|
|
53
|
+
} catch (error) {
|
|
54
|
+
throw new Error(`Failed to load JSON file: ${filePath}\n${error.message}`);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export function loadJsonConfigs(...configs) {
|
|
59
|
+
const loadedConfigs = [];
|
|
60
|
+
for (const configPath of configs) {
|
|
61
|
+
if (!fs.existsSync(configPath)) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
loadedConfigs.push(loadJson(configPath));
|
|
65
|
+
}
|
|
66
|
+
let mergedConfig = {};
|
|
67
|
+
for (const conf of loadedConfigs) {
|
|
68
|
+
mergedConfig = deepMerge(mergedConfig, conf);
|
|
69
|
+
}
|
|
70
|
+
return mergedConfig;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
function isObject(item) {
|
|
74
|
+
return (item && typeof item === 'object' && !Array.isArray(item));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function deepMerge(target, source) {
|
|
78
|
+
for (const key in source) {
|
|
79
|
+
if (isObject(source[key])) {
|
|
80
|
+
if (!target[key]) Object.assign(target, { [key]: {} });
|
|
81
|
+
deepMerge(target[key], source[key]);
|
|
82
|
+
} else {
|
|
83
|
+
target[key] = source[key];
|
|
84
|
+
}
|
|
42
85
|
}
|
|
43
|
-
|
|
86
|
+
return target;
|
|
87
|
+
}
|