jizy-packer 2.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 +2 -0
- package/bin/jpack.js +38 -0
- package/lib/Build.js +188 -0
- package/lib/Config.js +73 -0
- package/lib/LogMe.js +25 -0
- package/lib/Rollup.js +258 -0
- package/lib/utils.js +43 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-present Joffrey Demetz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
package/bin/jpack.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import yargs from "yargs/yargs";
|
|
2
|
+
import { hideBin } from 'yargs/helpers';
|
|
3
|
+
import jPackBuild from "../Build.js";
|
|
4
|
+
import jPackConfig from "../Config.js";
|
|
5
|
+
|
|
6
|
+
jPackConfig.set('basePath', process.cwd());
|
|
7
|
+
|
|
8
|
+
const command = yargs(hideBin(process.argv))
|
|
9
|
+
.usage('Usage: $0 <command> [options]')
|
|
10
|
+
.option('target', {
|
|
11
|
+
alias: 't',
|
|
12
|
+
type: 'string',
|
|
13
|
+
description: 'Target path',
|
|
14
|
+
default: '',
|
|
15
|
+
})
|
|
16
|
+
.option('name', {
|
|
17
|
+
alias: 'n',
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Set the build name',
|
|
20
|
+
default: '',
|
|
21
|
+
})
|
|
22
|
+
.option('zip', {
|
|
23
|
+
alias: 'z',
|
|
24
|
+
type: 'boolean',
|
|
25
|
+
description: 'Create a zip file',
|
|
26
|
+
default: false,
|
|
27
|
+
})
|
|
28
|
+
.option('debug', {
|
|
29
|
+
alias: 'd',
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
description: 'Enable debug mode',
|
|
32
|
+
default: false,
|
|
33
|
+
})
|
|
34
|
+
.help()
|
|
35
|
+
.alias('help', 'h');
|
|
36
|
+
|
|
37
|
+
const argv = command.parse();
|
|
38
|
+
jPackBuild(argv);
|
package/lib/Build.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { rollup } from 'rollup';
|
|
4
|
+
|
|
5
|
+
import LogMe from "./LogMe.js";
|
|
6
|
+
import jPackConfig from "./Config.js";
|
|
7
|
+
import jPackRollup from "./Rollup.js";
|
|
8
|
+
import { cleanBuildFolder } from '../utils.js';
|
|
9
|
+
|
|
10
|
+
export default async function jPackBuild({
|
|
11
|
+
target = null,
|
|
12
|
+
name = null,
|
|
13
|
+
zip = false,
|
|
14
|
+
debug = false
|
|
15
|
+
} = {}) {
|
|
16
|
+
|
|
17
|
+
LogMe.log('---');
|
|
18
|
+
|
|
19
|
+
if (debug) {
|
|
20
|
+
process.env.DEBUG = true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
LogMe.log('Build project...');
|
|
24
|
+
|
|
25
|
+
if (!target || target === 'dist') {
|
|
26
|
+
target = '';
|
|
27
|
+
name = '';
|
|
28
|
+
zip = false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (zip && !name) {
|
|
32
|
+
name = 'zip';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (target && !name) {
|
|
36
|
+
name = 'export';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!name) {
|
|
40
|
+
name = 'default';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
LogMe.log(' Target: ' + target);
|
|
44
|
+
LogMe.log(' Name: ' + name);
|
|
45
|
+
LogMe.log(' Zip: ' + (zip ? 'enabled' : 'disabled'));
|
|
46
|
+
LogMe.log(' Debug: ' + (debug ? 'enabled' : 'disabled'));
|
|
47
|
+
LogMe.log('---');
|
|
48
|
+
|
|
49
|
+
jPackConfig.set('buildZip', zip);
|
|
50
|
+
jPackConfig.set('buildName', name);
|
|
51
|
+
|
|
52
|
+
if (target) {
|
|
53
|
+
jPackConfig.set('buildTarget', jPackConfig.get('basePath') + '/build/' + target);
|
|
54
|
+
} else {
|
|
55
|
+
LogMe.log('Empty or create dist directory');
|
|
56
|
+
const targetPath = path.join(jPackConfig.get('basePath'), 'dist');
|
|
57
|
+
jPackConfig.set('buildTarget', targetPath);
|
|
58
|
+
cleanBuildFolder(targetPath);
|
|
59
|
+
|
|
60
|
+
const targetCfgPath = path.join(targetPath, 'config.json');
|
|
61
|
+
if (!fs.existsSync(targetCfgPath)) {
|
|
62
|
+
const defaultCfgPath = path.join(jPackConfig.get('basePath'), 'config', 'config.json');
|
|
63
|
+
if (fs.existsSync(defaultCfgPath)) {
|
|
64
|
+
LogMe.log('Copy default config.json file');
|
|
65
|
+
fs.copyFileSync(defaultCfgPath, targetCfgPath);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const defaultCfgPath = path.join(jPackConfig.get('basePath'), 'config', 'config.json');
|
|
71
|
+
const targetCfgPath = path.join(jPackConfig.get('buildTarget'), 'config.json');
|
|
72
|
+
if (!fs.existsSync(targetCfgPath)) {
|
|
73
|
+
if (fs.existsSync(defaultCfgPath)) {
|
|
74
|
+
LogMe.log('Copy default config.json file');
|
|
75
|
+
fs.copyFileSync(defaultCfgPath, targetCfgPath);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (fs.existsSync(defaultCfgPath)) {
|
|
80
|
+
LogMe.log('Load default config file');
|
|
81
|
+
LogMe.log(defaultCfgPath);
|
|
82
|
+
jPackConfig.loadFromJson(defaultCfgPath);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const cfgPath = checkTargetDirectory(jPackConfig.get('buildTarget'));
|
|
86
|
+
if (fs.existsSync(cfgPath)) {
|
|
87
|
+
LogMe.log(`Load client config file`);
|
|
88
|
+
LogMe.log(cfgPath);
|
|
89
|
+
jPackConfig.loadFromJson(cfgPath);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
jPackConfig.setPackageVersion();
|
|
94
|
+
checkConfig();
|
|
95
|
+
await doBuild();
|
|
96
|
+
} catch (error) {
|
|
97
|
+
LogMe.error(`Failed to load configuration file: ${cfgPath}`);
|
|
98
|
+
LogMe.error(error.message);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
async function doBuild() {
|
|
104
|
+
LogMe.log('---');
|
|
105
|
+
LogMe.dir(jPackConfig.all());
|
|
106
|
+
LogMe.log('---');
|
|
107
|
+
|
|
108
|
+
const inputOptions = {
|
|
109
|
+
input: jPackConfig.get('buildJsFilePath'),
|
|
110
|
+
plugins: jPackRollup(),
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const outputOptions = {
|
|
114
|
+
file: jPackConfig.get('assetsPath') + '/js/' + jPackConfig.get('alias') + '.min.js',
|
|
115
|
+
format: "iife",
|
|
116
|
+
name: jPackConfig.get('name'),
|
|
117
|
+
sourcemap: false,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
LogMe.log('Starting Rollup build...');
|
|
122
|
+
const bundle = await rollup(inputOptions);
|
|
123
|
+
await bundle.write(outputOptions);
|
|
124
|
+
LogMe.log('Rollup build completed successfully.');
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error('Error during Rollup build:', error);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function checkTargetDirectory(targetPath) {
|
|
132
|
+
LogMe.log('checkTargetDirectory()');
|
|
133
|
+
|
|
134
|
+
if (!fs.existsSync(targetPath)) {
|
|
135
|
+
LogMe.error(`Does not exist: ${targetPath}`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!fs.lstatSync(targetPath).isDirectory()) {
|
|
140
|
+
LogMe.error(`Is not a directory: ${targetPath}`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const cfgPath = path.join(targetPath, 'config.json');
|
|
145
|
+
|
|
146
|
+
if (!fs.existsSync(cfgPath)) {
|
|
147
|
+
LogMe.warn(' config.json not found in target path');
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const files = fs.readdirSync(targetPath)
|
|
152
|
+
.filter(file => file !== 'config.json');
|
|
153
|
+
|
|
154
|
+
if (files.length > 0) {
|
|
155
|
+
LogMe.error('Build target can only contain config.json');
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return cfgPath;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function checkConfig() {
|
|
163
|
+
const basePath = jPackConfig.get('basePath');
|
|
164
|
+
|
|
165
|
+
const buildName = jPackConfig.get('buildName')
|
|
166
|
+
.replace(/[^a-zA-Z0-9]/g, ''); // Sanitize the build folder name
|
|
167
|
+
|
|
168
|
+
jPackConfig.set('buildName', buildName);
|
|
169
|
+
|
|
170
|
+
if (buildName === 'default') {
|
|
171
|
+
jPackConfig.set('assetsPath', 'dist');
|
|
172
|
+
jPackConfig.set('importPrefix', '../');
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
jPackConfig.set('assetsPath', 'build/' + buildName);
|
|
176
|
+
jPackConfig.set('importPrefix', '../../');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
jPackConfig.set('assetsFullpath', path.join(basePath, jPackConfig.get('assetsPath')));
|
|
180
|
+
jPackConfig.set('buildJsFilePath', path.join(basePath, jPackConfig.get('assetsPath'), 'build.js'));
|
|
181
|
+
jPackConfig.set('buildTemplatePath', path.join(basePath, 'config', 'jpack.template'));
|
|
182
|
+
jPackConfig.set('wrapperPath', path.join(basePath, 'config', 'jpack.wrapper.js'));
|
|
183
|
+
|
|
184
|
+
const onCheckConfig = jPackConfig.get('onCheckConfig');
|
|
185
|
+
if (typeof onCheckConfig === 'function') {
|
|
186
|
+
onCheckConfig();
|
|
187
|
+
}
|
|
188
|
+
}
|
package/lib/Config.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
const config = {};
|
|
5
|
+
|
|
6
|
+
const jPackConfig = {
|
|
7
|
+
all: function () {
|
|
8
|
+
const result = {};
|
|
9
|
+
for (const key in config) {
|
|
10
|
+
if (typeof config[key] === 'function') {
|
|
11
|
+
result[key] = 'fn';
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
result[key] = config[key];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
loadFromJson: function (cfgPath) {
|
|
21
|
+
if (!fs.existsSync(cfgPath)) {
|
|
22
|
+
throw new Error(`Configuration file not found: ${cfgPath}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const data = fs.readFileSync(cfgPath, 'utf8');
|
|
26
|
+
const json = JSON.parse(data);
|
|
27
|
+
this.sets(json);
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
setPackageVersion: function () {
|
|
31
|
+
const pkgPath = path.join(jPackConfig.get('basePath'), 'package.json');
|
|
32
|
+
if (fs.existsSync(pkgPath)) {
|
|
33
|
+
const data = fs.readFileSync(pkgPath, 'utf8');
|
|
34
|
+
const json = JSON.parse(data);
|
|
35
|
+
if (json.version) {
|
|
36
|
+
this.set('version', json.version);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
check: function () {
|
|
42
|
+
if (!config.basePath) {
|
|
43
|
+
throw new Error('Invalid configuration: basePath is required.');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!config.name) {
|
|
47
|
+
throw new Error('Invalid configuration: name is required.');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!config.alias) {
|
|
51
|
+
config.alias = config.name.toLowerCase();
|
|
52
|
+
config.alias = config.alias.replace(/\s+/g, '-');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!config.cfg) {
|
|
56
|
+
config.cfg = config.alias;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
sets: (newConfig) => {
|
|
61
|
+
Object.assign(config, newConfig);
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
get(key, def) {
|
|
65
|
+
return config[key] || def;
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
set(key, value) {
|
|
69
|
+
config[key] = value;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export default jPackConfig;
|
package/lib/LogMe.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const LogMe = {
|
|
2
|
+
doLog: (method, ...message) => {
|
|
3
|
+
if (!process.env.DEBUG) {
|
|
4
|
+
return;
|
|
5
|
+
}
|
|
6
|
+
console[method](...message);
|
|
7
|
+
},
|
|
8
|
+
log: (...message) => {
|
|
9
|
+
LogMe.doLog('log', ...message);
|
|
10
|
+
},
|
|
11
|
+
warn: (...message) => {
|
|
12
|
+
LogMe.doLog('warn', ...message);
|
|
13
|
+
},
|
|
14
|
+
error: (...message) => {
|
|
15
|
+
LogMe.doLog('error', ...message);
|
|
16
|
+
},
|
|
17
|
+
debug: (...message) => {
|
|
18
|
+
LogMe.doLog('debug', ...message);
|
|
19
|
+
},
|
|
20
|
+
dir: (...message) => {
|
|
21
|
+
LogMe.doLog('dir', ...message);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default LogMe;
|
package/lib/Rollup.js
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import postcss from "rollup-plugin-postcss";
|
|
4
|
+
import url from "@rollup/plugin-url";
|
|
5
|
+
import json from "@rollup/plugin-json";
|
|
6
|
+
import resolve from "@rollup/plugin-node-resolve";
|
|
7
|
+
import commonjs from "@rollup/plugin-commonjs";
|
|
8
|
+
import terser from '@rollup/plugin-terser';
|
|
9
|
+
import { execSync } from 'child_process';
|
|
10
|
+
|
|
11
|
+
import jPackConfig from "./Config.js";
|
|
12
|
+
import LogMe from "./LogMe.js";
|
|
13
|
+
import { cleanBuildFolder } from "./utils.js";
|
|
14
|
+
|
|
15
|
+
export default async function jPackRollup(config) {
|
|
16
|
+
const assetsPath = jPackConfig.get('assetsPath');
|
|
17
|
+
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
name: 'beforeBuild',
|
|
21
|
+
buildStart() {
|
|
22
|
+
// target folder exists so empty
|
|
23
|
+
// should not happen since it's required to have an empty target folder
|
|
24
|
+
cleanBuildFolder(assetsPath);
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
{
|
|
29
|
+
name: 'preprocess',
|
|
30
|
+
buildStart() {
|
|
31
|
+
generateBuildJs();
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
postcss({
|
|
36
|
+
extract: jPackConfig.get('alias') + '.min.css', // Save CSS to dist/css/
|
|
37
|
+
minimize: true, // Minify CSS
|
|
38
|
+
sourceMap: false, // Disable source map for CSS
|
|
39
|
+
extensions: ['.less'], // Process LESS files
|
|
40
|
+
}),
|
|
41
|
+
|
|
42
|
+
url({
|
|
43
|
+
include: ['**/*.woff', '**/*.woff2'],
|
|
44
|
+
limit: 0,
|
|
45
|
+
emitFiles: true,
|
|
46
|
+
fileName: '[name][extname]',
|
|
47
|
+
destDir: assetsPath + '/fonts/',
|
|
48
|
+
}),
|
|
49
|
+
|
|
50
|
+
url({
|
|
51
|
+
include: ['**/*.png'],
|
|
52
|
+
limit: 0,
|
|
53
|
+
emitFiles: true,
|
|
54
|
+
fileName: '[name][extname]',
|
|
55
|
+
destDir: assetsPath + '/images/',
|
|
56
|
+
}),
|
|
57
|
+
|
|
58
|
+
json(), // Handle JSON imports
|
|
59
|
+
resolve(), // Resolve Node.js modules
|
|
60
|
+
commonjs(), // Convert CommonJS modules to ES6
|
|
61
|
+
|
|
62
|
+
{
|
|
63
|
+
name: 'wrap',
|
|
64
|
+
renderChunk(code) {
|
|
65
|
+
return generateWrappedJs(code);
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
terser(),
|
|
70
|
+
|
|
71
|
+
{
|
|
72
|
+
name: 'jpacked',
|
|
73
|
+
writeBundle() {
|
|
74
|
+
onPacked();
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
];
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
function generateBuildJs() {
|
|
81
|
+
LogMe.log('Generate the build.js file ...');
|
|
82
|
+
|
|
83
|
+
// Read the build template
|
|
84
|
+
let code = fs.readFileSync(jPackConfig.get('buildTemplatePath'), 'utf8');
|
|
85
|
+
|
|
86
|
+
// append config callback
|
|
87
|
+
const onGenerateBuildJs = jPackConfig.get('onGenerateBuildJs');
|
|
88
|
+
if (typeof onGenerateBuildJs === 'function') {
|
|
89
|
+
console.log('Calling onGenerateBuildJs callback');
|
|
90
|
+
code = onGenerateBuildJs(code);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
code = code.replace(/{{PREFIX}}/g, jPackConfig.get('importPrefix'));
|
|
94
|
+
|
|
95
|
+
fs.writeFileSync(jPackConfig.get('buildJsFilePath'), code, 'utf8');
|
|
96
|
+
|
|
97
|
+
if (fs.existsSync(jPackConfig.get('buildJsFilePath'))) {
|
|
98
|
+
LogMe.log('Generated build successfully in "' + jPackConfig.get('buildJsFilePath') + '"');
|
|
99
|
+
} else {
|
|
100
|
+
console.error('Error: Generated build file not found: ' + jPackConfig.get('buildJsFilePath'));
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function generateWrappedJs(code) {
|
|
106
|
+
LogMe.log('Generate the wrapper.js file ...');
|
|
107
|
+
|
|
108
|
+
const date = new Date();
|
|
109
|
+
const wrapper = fs.readFileSync(jPackConfig.get('wrapperPath'), 'utf8');
|
|
110
|
+
|
|
111
|
+
const marker = '// @CODE';
|
|
112
|
+
const codePosition = wrapper.indexOf(marker);
|
|
113
|
+
if (codePosition === -1) {
|
|
114
|
+
console.error('Error: "// @CODE" not found in wrapper file');
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Insert code after the marker (keeping the marker and its line)
|
|
119
|
+
const markerEnd = codePosition + marker.length;
|
|
120
|
+
// Find the end of the line (so code is inserted after the marker's line)
|
|
121
|
+
const lineEnd = wrapper.indexOf('\n', markerEnd);
|
|
122
|
+
let insertPos = lineEnd !== -1 ? lineEnd + 1 : markerEnd;
|
|
123
|
+
|
|
124
|
+
let wrapped = wrapper.slice(0, insertPos) + code + '\n' + wrapper.slice(insertPos);
|
|
125
|
+
|
|
126
|
+
wrapped = wrapped.replace(marker, '');
|
|
127
|
+
wrapped = wrapped.replace(/@VERSION/g, jPackConfig.get('version'));
|
|
128
|
+
wrapped = wrapped.replace(/@BUNDLE/g, jPackConfig.get('buildName'));
|
|
129
|
+
wrapped = wrapped.replace(/@DATE/g, date.toISOString().replace(/:\d+\.\d+Z$/, "Z"));
|
|
130
|
+
|
|
131
|
+
const onGenerateWrappedJs = jPackConfig.get('onGenerateWrappedJs');
|
|
132
|
+
if (typeof onGenerateWrappedJs === 'function') {
|
|
133
|
+
wrapped = onGenerateWrappedJs(wrapped);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return wrapped;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function onPacked() {
|
|
140
|
+
LogMe.log('Build completed successfully.');
|
|
141
|
+
|
|
142
|
+
moveCssFiles();
|
|
143
|
+
|
|
144
|
+
const onPacked = jPackConfig.get('onPacked');
|
|
145
|
+
if (typeof onPacked === 'function') {
|
|
146
|
+
onPacked();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Cleanup the build folder
|
|
150
|
+
cleanupBuild();
|
|
151
|
+
|
|
152
|
+
LogMe.log('Build process completed.');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function moveCssFiles() {
|
|
156
|
+
LogMe.log('Moving CSS files from js/ to css/ ...');
|
|
157
|
+
const assetsPath = jPackConfig.get('assetsPath');
|
|
158
|
+
|
|
159
|
+
fs.readdirSync(assetsPath + '/js')
|
|
160
|
+
.filter(file => file.endsWith('.css'))
|
|
161
|
+
.forEach(file => {
|
|
162
|
+
const oldPath = path.join(assetsPath + '/js', file);
|
|
163
|
+
const newPath = path.join(assetsPath + '/css', file);
|
|
164
|
+
fs.mkdirSync(path.dirname(newPath), { recursive: true });
|
|
165
|
+
fs.renameSync(oldPath, newPath);
|
|
166
|
+
LogMe.log('- ' + file);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function cleanupBuild() {
|
|
171
|
+
LogMe.log('Cleaning up generated build ...');
|
|
172
|
+
|
|
173
|
+
// Remove the generated build.js file
|
|
174
|
+
if (fs.existsSync(jPackConfig.get('buildJsFilePath'))) {
|
|
175
|
+
LogMe.log('Removed generated build.js file');
|
|
176
|
+
fs.unlinkSync(jPackConfig.get('buildJsFilePath'));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
let emptyBuildFolder = false;
|
|
180
|
+
const ignoreRemove = [];
|
|
181
|
+
|
|
182
|
+
if (jPackConfig.get('buildZip')) {
|
|
183
|
+
LogMe.log('Creating zip file ...');
|
|
184
|
+
const zipFilePath = path.join(jPackConfig.get('assetsFullpath'), jPackConfig.get('buildName') + '.zip');
|
|
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);
|
|
222
|
+
}
|
|
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
|
+
}
|
|
258
|
+
}
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import LogMe from './LogMe.js';
|
|
4
|
+
|
|
5
|
+
export function removeEmptyDirs(dir) {
|
|
6
|
+
if (!fs.existsSync(dir)) return;
|
|
7
|
+
|
|
8
|
+
const files = fs.readdirSync(dir);
|
|
9
|
+
for (const file of files) {
|
|
10
|
+
const fullPath = path.join(dir, file);
|
|
11
|
+
if (fs.lstatSync(fullPath).isDirectory()) {
|
|
12
|
+
removeEmptyDirs(fullPath);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// After removing subdirs, check if current dir is empty
|
|
17
|
+
if (fs.readdirSync(dir).length === 0) {
|
|
18
|
+
fs.rmdirSync(dir);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export function cleanBuildFolder(buildPath) {
|
|
23
|
+
LogMe.log('cleanBuildFolder()');
|
|
24
|
+
|
|
25
|
+
if (fs.existsSync(buildPath)) {
|
|
26
|
+
LogMe.log(' Cleanup');
|
|
27
|
+
fs.readdirSync(buildPath).forEach(file => {
|
|
28
|
+
if (file !== 'config.json') {
|
|
29
|
+
const filePath = path.join(buildPath, file);
|
|
30
|
+
if (fs.lstatSync(filePath).isDirectory()) {
|
|
31
|
+
fs.rmSync(filePath, { recursive: true, force: true });
|
|
32
|
+
LogMe.log(' - [RM] ' + filePath);
|
|
33
|
+
} else {
|
|
34
|
+
fs.unlinkSync(filePath);
|
|
35
|
+
LogMe.log(' - [RM] ' + filePath);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
} else {
|
|
40
|
+
fs.mkdirSync(buildPath, { recursive: true });
|
|
41
|
+
LogMe.log(' Created target directory');
|
|
42
|
+
}
|
|
43
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jizy-packer",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"lib/*.js"
|
|
7
|
+
],
|
|
8
|
+
"bin": {
|
|
9
|
+
"jizy-pack": "./bin/jpack.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"build:export": "node ./bin/jpack.js -t perso",
|
|
14
|
+
"build:export-debug": "node ./bin/jpack.js -t perso --debug",
|
|
15
|
+
"build:dist": "node ./bin/jpack.js -t dist -n default",
|
|
16
|
+
"build:dist-debug": "node ./bin/jpack.js -t dist -n default --debug"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/joffreydemetz/jizy-packer.git"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"jizy",
|
|
24
|
+
"packer",
|
|
25
|
+
"utilities"
|
|
26
|
+
],
|
|
27
|
+
"author": "Joffrey Demetz <joffrey.demetz@gmail.com> (https://joffreydemetz.com/)",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"description": "CLI app to generate optimized builds.",
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@babel/core": "^7.26.10",
|
|
32
|
+
"@babel/preset-env": "^7.26.9",
|
|
33
|
+
"@rollup/plugin-commonjs": "^28.0.3",
|
|
34
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
35
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
36
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
37
|
+
"@rollup/plugin-url": "^8.0.2",
|
|
38
|
+
"autoprefixer": "^10.4.21",
|
|
39
|
+
"babel-jest": "^29.7.0",
|
|
40
|
+
"clean-css": "^5.3.3",
|
|
41
|
+
"cross-env": "^7.0.3",
|
|
42
|
+
"cssnano": "^7.0.6",
|
|
43
|
+
"jest": "^29.7.0",
|
|
44
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
45
|
+
"jsdom": "^26.1.0",
|
|
46
|
+
"less": "^4.3.0",
|
|
47
|
+
"less-plugin-clean-css": "^1.6.0",
|
|
48
|
+
"postcss": "^8.5.3",
|
|
49
|
+
"rollup": "^4.40.1",
|
|
50
|
+
"rollup-plugin-copy": "^3.5.0",
|
|
51
|
+
"rollup-plugin-delete": "^3.0.1",
|
|
52
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
53
|
+
"yargs": "^17.7.2"
|
|
54
|
+
},
|
|
55
|
+
"jest": {
|
|
56
|
+
"testEnvironment": "jsdom",
|
|
57
|
+
"transform": {
|
|
58
|
+
"^.+\\.js$": "babel-jest"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|