1 | import Fs from 'fs';
|
2 | import Path from 'path';
|
3 | import Util from 'util';
|
4 | import Rollup from 'rollup';
|
5 | import Readline from 'readline';
|
6 | import Babel from '@babel/core';
|
7 |
|
8 | let WATCHER_BUSY = false;
|
9 |
|
10 | export const ReadFile = Util.promisify(Fs.readFile);
|
11 | export const ReadFolder = Util.promisify(Fs.readdir);
|
12 | export const WriteFile = Util.promisify(Fs.writeFile);
|
13 |
|
14 | export 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 |
|
30 | export 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 |
|
58 | export 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 |
|
82 | export 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 |
|
112 | export const Argumenter = async function (args) {
|
113 | const result = {};
|
114 |
|
115 |
|
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 |
|
141 | export 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 |
|
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);
|