1 |
|
2 | ;
|
3 |
|
4 | let clone = require('clone');
|
5 | let co = require('co');
|
6 | let empty = require('is-empty');
|
7 | let fs = require('mz/fs');
|
8 | let glob = require('globby');
|
9 | let merge = require('merge-array');
|
10 | let path = require('path');
|
11 | let resolve = require('resolve').sync;
|
12 |
|
13 | // single export
|
14 | exports = module.exports = co.wrap(load);
|
15 | exports.sync = loadSync;
|
16 |
|
17 | /**
|
18 | * Loads a mako configuration file.
|
19 | *
|
20 | * @param {String} file The absolute pathname to the config file to load.
|
21 | * @param {Array} [overrides] User-supplied entries. (overrides config)
|
22 | * @return {Object}
|
23 | */
|
24 | function* load(file, overrides) {
|
25 | let config = JSON.parse(yield fs.readFile(file, 'utf8'));
|
26 | let dir = path.dirname(file);
|
27 | let env = config[process.env.NODE_ENV || 'development'];
|
28 |
|
29 | if (env) {
|
30 | if (env.entries) merge(config.entries, env.entries);
|
31 | if (env.plugins) merge(config.plugins, env.plugins);
|
32 | }
|
33 |
|
34 | return {
|
35 | entries: yield normalizeEntries(overrides, config.entries, dir),
|
36 | plugins: normalizePlugins(config.plugins, dir)
|
37 | };
|
38 | }
|
39 |
|
40 | /**
|
41 | * Synchronous version of load.
|
42 | *
|
43 | * @param {String} file The absolute pathname to the config file to load.
|
44 | * @param {Array} [overrides] User-supplied entries. (overrides config)
|
45 | * @return {Object}
|
46 | */
|
47 | function loadSync(file, overrides) {
|
48 | let config = JSON.parse(fs.readFileSync(file, 'utf8'));
|
49 | let dir = path.dirname(file);
|
50 | let env = config[process.env.NODE_ENV || 'development'];
|
51 |
|
52 | if (env) {
|
53 | if (env.entries) merge(config.entries, env.entries);
|
54 | if (env.plugins) merge(config.plugins, env.plugins);
|
55 | }
|
56 |
|
57 | return {
|
58 | entries: normalizeEntriesSync(overrides, config.entries, dir),
|
59 | plugins: normalizePlugins(config.plugins, dir)
|
60 | };
|
61 | }
|
62 |
|
63 | /**
|
64 | * Normalizes the list of entries. By default, the config file will contain a
|
65 | * complete list of entries. If the user passes a list of entries via the CLI,
|
66 | * that list will be used instead.
|
67 | *
|
68 | * It will return a flattened array of absolute file paths, with any globs
|
69 | * already expanded.
|
70 | *
|
71 | * @param {Array} input The input list from the user. (if specified)
|
72 | * @param {Array} config The list specified in the config file.
|
73 | * @param {String} root The location of the config file.
|
74 | * @return {Array}
|
75 | */
|
76 | function* normalizeEntries(input, config, root) {
|
77 | let list = !empty(input) ? input : config;
|
78 | return yield glob(list, { cwd: root, realpath: true });
|
79 | }
|
80 |
|
81 | /**
|
82 | * Synchronous version of normalizeEntries.
|
83 | *
|
84 | * @param {Array} input The input list from the user. (if specified)
|
85 | * @param {Array} config The list specified in the config file.
|
86 | * @param {String} root The location of the config file.
|
87 | * @return {Array}
|
88 | */
|
89 | function normalizeEntriesSync(input, config, root) {
|
90 | let list = !empty(input) ? input : config;
|
91 | return glob.sync(list, { cwd: root, realpath: true });
|
92 | }
|
93 |
|
94 | /**
|
95 | * Normalizes the list of plugins. For each plugin specified in the config,
|
96 | * it will initialize. (with arguments if supplied) The return value is a flat
|
97 | * list of plugin functions.
|
98 | *
|
99 | * When a plugin is specified only as a string, it will be initialized without
|
100 | * arguments. (basically accepting the defaults)
|
101 | *
|
102 | * When a plugin is specified as an array, the first item is the plugin name,
|
103 | * all other items will be forwarded as arguments.
|
104 | *
|
105 | * @param {Array} config The list of plugins specified in the config.
|
106 | * @param {String} root The location of the config file.
|
107 | * @return {Array}
|
108 | */
|
109 | function normalizePlugins(config, root) {
|
110 | if (!config) return [];
|
111 | return config
|
112 | .map(plugin => {
|
113 | if (typeof plugin === 'string') return [ plugin ];
|
114 | return clone(plugin);
|
115 | })
|
116 | .map(plugin => {
|
117 | let fn = require(resolve(plugin[0], { basedir: root }));
|
118 | return fn.apply(null, plugin.slice(1));
|
119 | });
|
120 | }
|