1 | 'use strict';
|
2 |
|
3 | function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
4 |
|
5 | const _ = require('underscore');
|
6 | const path = require('path');
|
7 | const webpack = require('webpack');
|
8 | const fs = require('fs-extra');
|
9 | const writePkg = require('write-pkg');
|
10 |
|
11 | const server_config = require('../webpack/webpack.config.server.js');
|
12 | const client_config = require('../webpack/webpack.config.client.js');
|
13 | const createStrategy = require('./strategy');
|
14 | const generateServerStrategy = require('./generateServerStrategy');
|
15 | const generateClient = require('./generateClient');
|
16 | const generateIncludes = require('./generateIncludes');
|
17 |
|
18 | const PROJECT_DIR = process.cwd();
|
19 | const DIST_DIR = path.resolve(PROJECT_DIR, 'dist');
|
20 | const MODULES_DIR = path.resolve(PROJECT_DIR, 'node_modules');
|
21 | const LIB_DIR = path.resolve(DIST_DIR, 'lib');
|
22 | const packageJson = require(path.resolve(PROJECT_DIR, 'package.json'));
|
23 |
|
24 | let stdin = process.stdin;
|
25 | let stdout = process.stdout;
|
26 |
|
27 | const mapValues = (obj, iterator) => {
|
28 | const keys = Object.keys(obj);
|
29 | const mapped = {};
|
30 | keys.forEach(key => {
|
31 | mapped[key] = iterator(obj[key], key, obj);
|
32 | });
|
33 | return mapped;
|
34 | };
|
35 |
|
36 | const getDependencies = () => {
|
37 | const nodeModuleDir = path.resolve(PROJECT_DIR, 'node_modules');
|
38 | const deps = Object.assign({}, packageJson.dependencies, packageJson.devDependencies);
|
39 | return mapValues(deps, (_, name) => {
|
40 | const pjf = path.resolve(nodeModuleDir, name, 'package.json');
|
41 | const pj = require(pjf);
|
42 | return pj.version;
|
43 | });
|
44 | };
|
45 |
|
46 | const runWebpack = (config, options) => {
|
47 | return new Promise((resolve, reject) => {
|
48 | config = config(options);
|
49 | webpack(config, (err, stats) => {
|
50 | if (err) return reject(err);
|
51 | const errors = stats.toJson('errors-only').errors.toString();
|
52 | if (errors) return reject(errors);
|
53 | resolve();
|
54 | });
|
55 | });
|
56 | };
|
57 |
|
58 | const copyStatic = (() => {
|
59 | var _ref = _asyncToGenerator(function* () {
|
60 | const src = packageJson.linc && packageJson.linc.staticDir;
|
61 | if (src) {
|
62 | const dirname = path.basename(src);
|
63 | const dest = path.resolve(DIST_DIR, 'static', dirname);
|
64 | console.log(`Copying ${src} to ${dest}`);
|
65 | return fs.copy(src, dest, {
|
66 | overwrite: true,
|
67 | dereference: true,
|
68 | preserveTimestamps: true
|
69 | });
|
70 | }
|
71 | });
|
72 |
|
73 | return function copyStatic() {
|
74 | return _ref.apply(this, arguments);
|
75 | };
|
76 | })();
|
77 |
|
78 | const makeBabelAbsolute = babelOptions => {
|
79 | if (Array.isArray(babelOptions)) {
|
80 | babelOptions[0] = path.resolve(MODULES_DIR, babelOptions[0]);
|
81 | return babelOptions;
|
82 | } else {
|
83 | return path.resolve(MODULES_DIR, babelOptions);
|
84 | }
|
85 | };
|
86 |
|
87 | const mergeOptions = (acc, curr) => {
|
88 | acc.alias = Object.assign({}, acc.alias, curr.alias);
|
89 | if (curr.babel && curr.babel.presets) {
|
90 | const presets = curr.babel.presets.map(makeBabelAbsolute);
|
91 | acc.babel.presets = acc.babel.presets.concat(presets);
|
92 | }
|
93 | if (curr.babel && curr.babel.plugins) {
|
94 | const plugins = curr.babel.plugins.map(makeBabelAbsolute);
|
95 | acc.babel.plugins = acc.babel.plugins.concat(plugins);
|
96 | }
|
97 | if (Array.isArray(curr.plugins)) {
|
98 | acc.plugins = acc.plugins.concat(curr.plugins);
|
99 | } else if (curr.plugins) {
|
100 | acc.plugins.push(curr.plugins);
|
101 | }
|
102 | return acc;
|
103 | };
|
104 |
|
105 | const getConfigFragments = strategy => {
|
106 | const all = strategy.libs.map(lib => {
|
107 | try {
|
108 | return require(`./libs/config_client/${lib}`).configFragment;
|
109 | } catch (e) {}
|
110 | }).filter(e => !!e);
|
111 |
|
112 | const empty = { imports: [], values: [] };
|
113 | return all.reduce((acc, curr) => {
|
114 | if (curr.imports) acc.imports.push(curr.imports);
|
115 | if (curr.values) acc.values = acc.values.concat(curr.values);
|
116 | return acc;
|
117 | }, empty);
|
118 | };
|
119 |
|
120 | const getWebpackOptions = (strategy, env) => {
|
121 | const all = strategy.libs.map(lib => {
|
122 | try {
|
123 | return require(`./libs/config_client/${lib}`).webpackConfig;
|
124 | } catch (e) {}
|
125 | }).filter(e => !!e);
|
126 |
|
127 | const empty = { alias: {}, babel: { presets: [], plugins: [] }, plugins: [] };
|
128 | const options = all.map(e => e(DIST_DIR)[env]).reduce(mergeOptions, empty);
|
129 | return options;
|
130 | };
|
131 |
|
132 | const readOnce = () => new Promise(resolve => {
|
133 | stdin.once('data', resolve);
|
134 | });
|
135 |
|
136 | const ask = (() => {
|
137 | var _ref2 = _asyncToGenerator(function* (question, suggestion) {
|
138 | stdout.write(`${question}: `);
|
139 |
|
140 | let answer = yield readOnce();
|
141 | if (answer) {
|
142 | answer = answer.toString().trim();
|
143 | if (answer.length > 0) {
|
144 | return answer;
|
145 | }
|
146 | }
|
147 | stdout.write(`${suggestion}\n`);
|
148 | return ask(question, suggestion);
|
149 | });
|
150 |
|
151 | return function ask(_x, _x2) {
|
152 | return _ref2.apply(this, arguments);
|
153 | };
|
154 | })();
|
155 |
|
156 | const getSourceDir = (() => {
|
157 | var _ref3 = _asyncToGenerator(function* () {
|
158 | stdin.resume();
|
159 | const srcDir = yield ask('Directory containing your source code', 'Please provide a valid directory.');
|
160 | stdin.pause();
|
161 | return srcDir;
|
162 | });
|
163 |
|
164 | return function getSourceDir() {
|
165 | return _ref3.apply(this, arguments);
|
166 | };
|
167 | })();
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 | const getOptionValue = (() => {
|
175 | var _ref4 = _asyncToGenerator(function* (option) {
|
176 | stdin.resume();
|
177 | const optionValue = yield ask(`${option.comment}, e.g., '${option.example ? option.example : option.default}'`, 'This is a mandatory field. Please enter a value.');
|
178 | stdin.pause();
|
179 | return optionValue;
|
180 | });
|
181 |
|
182 | return function getOptionValue(_x3) {
|
183 | return _ref4.apply(this, arguments);
|
184 | };
|
185 | })();
|
186 |
|
187 | const configLines = {
|
188 | top: ['const config = {', " // polyfills: 'default,fetch,Symbol,Symbol.iterator,Array.prototype.find',", ' // requestExtendedUserInfo: true,'],
|
189 | bottom: ['};', '', 'export default config']
|
190 | };
|
191 |
|
192 | const option = (() => {
|
193 | var _ref5 = _asyncToGenerator(function* (opt, memo, lvl) {
|
194 | const indent = ' '.repeat(lvl + 1);
|
195 | const keys = Object.keys(opt);
|
196 |
|
197 |
|
198 | const o = opt[keys[0]];
|
199 | const ks = Object.keys(o);
|
200 | if (typeof o[ks[0]] === 'object') {
|
201 |
|
202 | var _iteratorNormalCompletion = true;
|
203 | var _didIteratorError = false;
|
204 | var _iteratorError = undefined;
|
205 |
|
206 | try {
|
207 | for (var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
208 | let k = _step.value;
|
209 |
|
210 | memo.values = memo.values.concat(`${indent}${k}: {`);
|
211 | yield option(opt[k], memo, lvl + 1);
|
212 | memo.values = memo.values.concat(`${indent}},`);
|
213 | }
|
214 | } catch (err) {
|
215 | _didIteratorError = true;
|
216 | _iteratorError = err;
|
217 | } finally {
|
218 | try {
|
219 | if (!_iteratorNormalCompletion && _iterator.return) {
|
220 | _iterator.return();
|
221 | }
|
222 | } finally {
|
223 | if (_didIteratorError) {
|
224 | throw _iteratorError;
|
225 | }
|
226 | }
|
227 | }
|
228 | } else {
|
229 | let isRequired = false;
|
230 |
|
231 | var _iteratorNormalCompletion2 = true;
|
232 | var _didIteratorError2 = false;
|
233 | var _iteratorError2 = undefined;
|
234 |
|
235 | try {
|
236 | for (var _iterator2 = keys[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
237 | let k = _step2.value;
|
238 |
|
239 | let optn = opt[k];
|
240 | let s;
|
241 | if (optn.required) {
|
242 | isRequired = true;
|
243 | s = `${indent}${k}: ${yield getOptionValue(optn)}`;
|
244 | } else {
|
245 | if (optn.example) {
|
246 | s = `${indent}// ${k}: ${optn.example}`;
|
247 | } else if (optn.default) {
|
248 | s = `${indent}// ${k}: ${optn.default}`;
|
249 | }
|
250 | }
|
251 | if (s) {
|
252 | memo.values = memo.values.concat(`${s},`);
|
253 | }
|
254 | }
|
255 | } catch (err) {
|
256 | _didIteratorError2 = true;
|
257 | _iteratorError2 = err;
|
258 | } finally {
|
259 | try {
|
260 | if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
261 | _iterator2.return();
|
262 | }
|
263 | } finally {
|
264 | if (_didIteratorError2) {
|
265 | throw _iteratorError2;
|
266 | }
|
267 | }
|
268 | }
|
269 |
|
270 | memo.required.push(isRequired);
|
271 | }
|
272 | });
|
273 |
|
274 | return function option(_x4, _x5, _x6) {
|
275 | return _ref5.apply(this, arguments);
|
276 | };
|
277 | })();
|
278 |
|
279 | const createConfigFileContents = (() => {
|
280 | var _ref6 = _asyncToGenerator(function* (all) {
|
281 | const memo = {
|
282 | values: configLines.top,
|
283 | required: []
|
284 | };
|
285 | var _iteratorNormalCompletion3 = true;
|
286 | var _didIteratorError3 = false;
|
287 | var _iteratorError3 = undefined;
|
288 |
|
289 | try {
|
290 | for (var _iterator3 = all.values[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
291 | let x = _step3.value;
|
292 |
|
293 | yield option(x, memo, 0);
|
294 | }
|
295 | } catch (err) {
|
296 | _didIteratorError3 = true;
|
297 | _iteratorError3 = err;
|
298 | } finally {
|
299 | try {
|
300 | if (!_iteratorNormalCompletion3 && _iterator3.return) {
|
301 | _iterator3.return();
|
302 | }
|
303 | } finally {
|
304 | if (_didIteratorError3) {
|
305 | throw _iteratorError3;
|
306 | }
|
307 | }
|
308 | }
|
309 |
|
310 | memo.values = memo.values.concat(configLines.bottom);
|
311 |
|
312 |
|
313 |
|
314 | const imports = _.reduce(all.imports, function (m, v, i) {
|
315 | v.forEach(function (o) {
|
316 | return m.push(memo.required[i] ? o : `// ${o}`);
|
317 | });
|
318 | return m;
|
319 | }, []);
|
320 |
|
321 | return [imports.join('\n'), '', memo.values.join('\n'), ''].join('\n');
|
322 | });
|
323 |
|
324 | return function createConfigFileContents(_x7) {
|
325 | return _ref6.apply(this, arguments);
|
326 | };
|
327 | })();
|
328 |
|
329 | const writeFile = (file, contents) => new Promise((resolve, reject) => {
|
330 | return fs.writeFile(file, contents, err => {
|
331 | if (err) return reject(err);
|
332 |
|
333 | stdout.write(`**\n** Created new config file ${file}\n**\n`);
|
334 | return resolve();
|
335 | });
|
336 | });
|
337 |
|
338 | const createConfigFile = (() => {
|
339 | var _ref7 = _asyncToGenerator(function* (strategy) {
|
340 | const CONFIG_FILENAME = 'src/linc.config.js';
|
341 | const configFile = path.join(process.cwd(), CONFIG_FILENAME);
|
342 |
|
343 |
|
344 | if (!fs.existsSync(configFile)) {
|
345 | const all = getConfigFragments(strategy);
|
346 | const contents = yield createConfigFileContents(all);
|
347 | writeFile(configFile, contents);
|
348 | }
|
349 | });
|
350 |
|
351 | return function createConfigFile(_x8) {
|
352 | return _ref7.apply(this, arguments);
|
353 | };
|
354 | })();
|
355 |
|
356 | const postBuild = (() => {
|
357 | var _ref8 = _asyncToGenerator(function* () {
|
358 | const linc = packageJson.linc || {};
|
359 | if (!linc.sourceDir) {
|
360 | linc.sourceDir = yield getSourceDir();
|
361 | yield writePkg(packageJson);
|
362 | }
|
363 | });
|
364 |
|
365 | return function postBuild() {
|
366 | return _ref8.apply(this, arguments);
|
367 | };
|
368 | })();
|
369 |
|
370 | const build = (() => {
|
371 | var _ref9 = _asyncToGenerator(function* (opts, callback) {
|
372 | if (!callback) {
|
373 | callback = opts;
|
374 | } else {
|
375 | stdin = opts.stdin || stdin;
|
376 | stdout = opts.stdout || stdout;
|
377 | }
|
378 |
|
379 | const strategy = createStrategy(getDependencies());
|
380 | yield createConfigFile(strategy);
|
381 | yield generateClient(path.resolve(DIST_DIR, 'client.js'), strategy);
|
382 | const serverStrategy = generateServerStrategy(path.resolve(DIST_DIR, 'server-strategy.js'), strategy);
|
383 | console.log('Creating a client package. This can take a minute or two..');
|
384 | const staticCopy = copyStatic();
|
385 | yield runWebpack(client_config, getWebpackOptions(strategy, 'client'));
|
386 | console.log('Created client package');
|
387 |
|
388 | yield generateIncludes(path.resolve(LIB_DIR, 'includes.js'), path.resolve(LIB_DIR, 'includes'));
|
389 |
|
390 | console.log('Now working on server package');
|
391 | yield serverStrategy;
|
392 | yield runWebpack(server_config, getWebpackOptions(strategy, 'server'));
|
393 | yield staticCopy;
|
394 | console.log('Created server package');
|
395 |
|
396 | console.log('Running post build operations');
|
397 | yield postBuild();
|
398 |
|
399 | console.log('We have created an overview of your bundles in dist/bundle-report.html');
|
400 |
|
401 | callback();
|
402 | });
|
403 |
|
404 | return function build(_x9, _x10) {
|
405 | return _ref9.apply(this, arguments);
|
406 | };
|
407 | })();
|
408 |
|
409 | module.exports = build;
|
410 |
|
\ | No newline at end of file |