UNPKG

6.39 kBJavaScriptView Raw
1import Fs from 'fs';
2import Path from 'path';
3import Util from 'util';
4import Rollup from 'rollup';
5import Readline from 'readline';
6import Babel from '@babel/core';
7
8let WATCHER_BUSY = false;
9
10export const ReadFile = Util.promisify(Fs.readFile);
11export const ReadFolder = Util.promisify(Fs.readdir);
12export const WriteFile = Util.promisify(Fs.writeFile);
13
14export const Bundler = async function (option) {
15
16 const bundled = await Rollup.rollup({
17 input: option.input
18 });
19
20 const generated = await bundled.generate({
21 name: option.name,
22 indent: option.indent,
23 format: option.format,
24 treeshake: option.treeshake
25 });
26
27 return generated.output[0].code;
28};
29
30export const Transformer = async function (option) {
31
32 const transformed = Babel.transform(option.code, {
33 sourceMaps: false,
34 moduleId: option.name,
35 minified: option.minify,
36 comments: option.comments,
37 plugins: [
38 [ 'module:fast-async', {
39 spec: true
40 } ]
41 ],
42 presets: [
43 [ '@babel/preset-env', {
44 modules: false,
45 targets: { ie: '11' },
46 exclude: [
47 'transform-regenerator',
48 'transform-async-to-generator',
49 'proposal-async-generator-functions'
50 ]
51 } ]
52 ]
53 });
54
55 return transformed.code;
56};
57
58export const Presser = async function (listener, exit) {
59 Readline.emitKeypressEvents(process.stdin);
60
61 process.stdin.setRawMode(true);
62
63 process.stdin.on('keypress', function (key, data) {
64 if (data.ctrl && data.name === 'c') {
65 Promise.resolve().then(function () {
66 if (typeof exit === 'function') {
67 return exit();
68 }
69 }).then(function () {
70 process.exit();
71 }).catch(console.error);
72 } else {
73 Promise.resolve().then(function () {
74 if (typeof listener === 'function') {
75 return listener(key);
76 }
77 }).catch(console.error);
78 }
79 });
80};
81
82export const Watcher = async function (data, listener) {
83 const paths = await ReadFolder(data);
84
85 for (const path of paths) {
86 const item = Path.resolve(Path.join(data, path));
87
88 if (item.includes('.')) {
89 Fs.watch(item, function (type, name) {
90 if (WATCHER_BUSY) {
91 return;
92 } else {
93 WATCHER_BUSY = true;
94 Promise.resolve().then(function () {
95 return listener(type, name);
96 }).then(function () {
97 WATCHER_BUSY = false;
98 }).catch(function (error) {
99 console.error(error);
100 WATCHER_BUSY = false;
101 });
102 }
103 });
104 } else {
105 await Watcher(item, listener);
106 }
107
108 }
109
110};
111
112export const Argumenter = async function (args) {
113 const result = {};
114
115 // need to account for random = signs
116
117 args.forEach(function (arg) {
118 if (arg.includes('=')) {
119 let [ name, value ] = arg.split('=');
120
121 if (
122 (value[0] === '[' && value[value.length-1] === ']') ||
123 (value[0] === '{' && value[value.length-1] === '}')
124 ) {
125 value = JSON.parse(value);
126 } else if (value.includes(',')) {
127 value = value.split(',');
128 } else if (value === 'true') {
129 value = true;
130 } else if (value === 'false') {
131 value = false;
132 }
133
134 result[name] = value;
135 }
136 });
137
138 return result;
139};
140
141export const Packer = async function (option) {
142 option = Object.assign({}, option || {});
143
144 if (!option.input) return console.error('input path required');
145 if (!option.output) return console.error('output path required');
146
147 option.indent = option.indent || '\t';
148 option.format = option.format || 'umd';
149
150 option.header = option.header === undefined ? null : option.header;
151 option.comments = option.comments === undefined ? false : option.comments;
152 option.treeshake = option.treeshake === undefined ? true : option.treeshake;
153
154 option.bundle = option.bundle === undefined ? false : option.bundle;
155 option.transform = option.transform === undefined ? false : option.transform;
156
157 option.name = option.name || '';
158 option.input = Path.resolve(option.inputFolder || '', option.input);
159 option.output = Path.resolve(option.outputFolder || '', option.output);
160
161 option.minify = option.minify === undefined ? option.output.includes('.min.') : option.minify;
162 // option.name = option.name ? `${option.name[0].toUpperCase()}${option.name.slice(1).toLowerCase()}` : '';
163
164 option.code = null;
165
166 if (option.bundle) {
167 option.code = await Bundler(option);
168 }
169
170 if (option.transform) {
171 option.code = await Transformer(option);
172 }
173
174 if (!option.code) {
175 option.code = await ReadFile(option.input);
176 }
177
178 if (option.header) {
179 option.code = `${option.header}${option.code}`;
180 }
181
182 await WriteFile(option.output, option.code);
183
184};
185
186(async function () {
187 const args = process.argv.slice(2);
188
189 if (args.length === 0) return;
190
191 const opt = await Argumenter(args);
192
193 if (opt.config) {
194
195 const path = Path.resolve(opt.config);
196 const extension = Path.extname(path);
197
198 if (extension === '.js' || extension === '.mjs') {
199 Object.assign(opt, (await import(path)).default);
200 } else {
201 return console.error('\nPacker - invalid file extension');
202 }
203
204 }
205
206 console.log('\nPacker Started');
207
208 if (Array.isArray(opt.output)) {
209 for (let output of opt.output) {
210 output = typeof output === 'string' ? { output } : output;
211 console.log(`\toutput: ${Path.join(opt.outputFolder || '', output.output)}`);
212 await Packer(Object.assign({}, opt, output));
213 }
214 } else {
215 console.log(`\toutput: ${Path.join(opt.outputFolder || '', opt.output)}`);
216 await Packer(opt);
217 }
218
219 console.log('Packer Ended\n');
220
221}()).catch(console.error);