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 | const CONFIG_FILENAME = 'src/linc.config.js';
|
24 | const CONFIG_FILE = path.resolve(PROJECT_DIR, CONFIG_FILENAME);
|
25 |
|
26 | let stdin = process.stdin;
|
27 | let stdout = process.stdout;
|
28 |
|
29 | const 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 |
|
38 | const 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 |
|
48 | const 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 |
|
60 | const 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 |
|
80 | const 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 |
|
89 | const 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 |
|
107 | const 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 |
|
122 | const 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 |
|
134 | const readOnce = () => new Promise(resolve => {
|
135 | stdin.once('data', resolve);
|
136 | });
|
137 |
|
138 | const 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 |
|
158 | const 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 |
|
171 | const configLines = {
|
172 | top: ['const config = {', " // polyfills: 'default,fetch,Symbol,Symbol.iterator,Array.prototype.find',", ' // requestExtendedUserInfo: true,'],
|
173 | bottom: ['};', '', 'export default config']
|
174 | };
|
175 |
|
176 | const getOption = (() => {
|
177 | var _ref4 = _asyncToGenerator(function* (opt, memo, lvl) {
|
178 | const indent = ' '.repeat(lvl + 1);
|
179 | const keys = Object.keys(opt);
|
180 |
|
181 |
|
182 | const o = opt[keys[0]];
|
183 | const ks = Object.keys(o);
|
184 | if (typeof o[ks[0]] === 'object') {
|
185 |
|
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 |
|
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 |
|
263 | const 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 |
|
297 |
|
298 | const imports = _.reduce(all.imports, function (m, v, i) {
|
299 |
|
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 |
|
314 | const 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 |
|
323 | const hasConfigFile = () => fs.existsSync(CONFIG_FILE);
|
324 |
|
325 | const createConfigFile = (() => {
|
326 | var _ref6 = _asyncToGenerator(function* (strategy) {
|
327 |
|
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 |
|
340 | const 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 |
|
354 | const 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 |
|
393 | module.exports = build;
|
394 |
|
\ | No newline at end of file |