UNPKG

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