-
Notifications
You must be signed in to change notification settings - Fork 4
/
builder.js
147 lines (130 loc) · 3.53 KB
/
builder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
const fs = require('fs');
const path = require('path');
const util = require('util');
const { minify } = require('terser');
const readdir = util.promisify(fs.readdir);
const readFile = util.promisify(fs.readFile);
const { sync } = require('./src/icons');
/**source code */
const filesDirectory = './src/';
/** optimized code for production destination */
const buildDestination = './bin/index.min.js';
/**
* @main
* build (minify) for production
*
* custom code -> merge all files, update scope hoisting (requires) then create index.min.js
*
* terser- > minify
*/
async function build() {
//check
await checkSourceCode(filesDirectory);
await checkDestFolder(buildDestination);
//reset
fs.writeFileSync(buildDestination, '', () => {});
let files;
try {
files = await readdir(filesDirectory);
} catch (err) {
console.log(err);
}
if (files === undefined) {
console.log('files not found');
} else {
//get content from files
const getData = async () => {
return Promise.all(files.map(file => read(file)));
};
//run terser to optimize/minify code
const minifyData = async data => {
const mini = await minify({ data });
return mini.code;
};
getData().then(data => {
requires = findRequires(data.join('\n'));
data = deleteRequiresFromFile(data.join('\n'));
const hoist = requires + data; // <- hoist fix
minifyData(hoist).then(minifiedData => {
const bin = '#!/usr/bin/env node\n';
fs.appendFileSync(buildDestination, bin + minifiedData);
console.log(sync, 'build complete!');
});
});
}
}
/**
* read file content
* @param {String|Buffer} file
*/
async function read(file) {
let content;
try {
content = await readFile(
path.join(filesDirectory, file),
(err, data) => {
if (err) console.log(err);
return data;
}
);
} catch (err) {
console.log(err);
}
return content;
}
/**
* @description find required node_modules or './' requires
* @example const fs = require('fs')
* //will return this line
* @param {String} data - the code
*/
function findRequires(data) {
return data
.toString()
.split('\n')
.map(item => {
if (item.match('require')) return item;
})
.filter(item => item !== undefined)
.filter(item => !item.match("'./")) //remove local imports <-
.join('\n');
}
/**
* @description delete all require('node_module') lines in code
* @example const fs = require('fs')
*
* @summary will delete this line from code
* @param {String} data - the code
*/
function deleteRequiresFromFile(data) {
return data
.toString()
.split('\n')
.map(item => {
if (!item.match('require')) return item;
})
.join('\n');
}
/**
* verify if source code folder and files exist
* @param {string} folderPath
*/
function checkSourceCode(folderPath) {
if (fs.existsSync(folderPath)) {
return true;
} else {
throw new Error('source code error: ', folderPath, ' not found');
}
}
/**
* verify if build destination folder exists, if not create it
* @param {string} folderPath
*/
function checkDestFolder(folderPath) {
if (fs.existsSync(folderPath)) {
return true;
} else {
fs.mkdirSync(folderPath.split('/')[1]);
}
}
build();