1 | const path = require('path');
|
2 | const fs = require('fs');
|
3 |
|
4 | const DEFAULT_OPTIONS = {
|
5 | 'entry': { type: String, default: 'app' },
|
6 | 'src': { type: String, default: 'src' },
|
7 | 'target': { type: String, default: 'weapp' },
|
8 | 'static': { type: [String, Array], default: 'static' },
|
9 | 'output': { type: String, default: 'weapp' },
|
10 | 'platform': { type: String },
|
11 | 'wpyExt': { type: String, default: '.wpy' },
|
12 | 'eslint': { type: Boolean, default: true },
|
13 | 'cliLogs': { type: Boolean, default: false },
|
14 | 'build.web': { type: Object },
|
15 | 'build.web.htmlTemplate': { type: String },
|
16 | 'build.web.htmlOutput': { type: String },
|
17 | 'build.web.jsOutput': { type: String },
|
18 | 'build.web.resolve': { type: Object, link: 'resolve' },
|
19 | 'resolve': { type: Object, default: {} },
|
20 | 'compilers': { type: Object },
|
21 | 'plugins': { type: Array, default: []},
|
22 | 'appConfig': { type: Object },
|
23 | 'appConfig.noPromiseAPI': { type: Array, default: []}
|
24 | };
|
25 |
|
26 |
|
27 | const DEFAULT_CONFIG = path.resolve('wepy.config.js');
|
28 |
|
29 | function setValue (obj, key, val) {
|
30 | let arr = key.split('.');
|
31 | let left = obj;
|
32 | for (let i = 0, l = arr.length; i < l; i++) {
|
33 | if (i == l - 1) {
|
34 | left[arr[i]] = val;
|
35 | } else {
|
36 | if (typeof left[arr[i]] !== 'object') {
|
37 | left[arr[i]] = {};
|
38 | }
|
39 | left = left[arr[i]];
|
40 | }
|
41 | }
|
42 | return obj;
|
43 | }
|
44 |
|
45 | function getValue (obj, key) {
|
46 | let arr = key.split('.');
|
47 | let left = obj;
|
48 | let rst;
|
49 | for (let i = 0, l = arr.length; i < l; i++) {
|
50 | if (i == l - 1) {
|
51 | rst = left[arr[i]];
|
52 | } else {
|
53 | if (typeof left[arr[i]] === 'undefined') {
|
54 | break;
|
55 | }
|
56 | left = left[arr[i]];
|
57 | }
|
58 | }
|
59 | return rst;
|
60 | }
|
61 |
|
62 | function check (t, val) {
|
63 | if (Array.isArray(t)) {
|
64 | return t.some((type) => check(type, val));
|
65 | }
|
66 | switch (t) {
|
67 | case String:
|
68 | return typeof(val) === 'string';
|
69 | case Number:
|
70 | return typeof(val) === 'number';
|
71 | case Boolean:
|
72 | return typeof(val) === 'boolean';
|
73 | case Function:
|
74 | return typeof(val) === 'function';
|
75 | case Object:
|
76 | return typeof(val) === 'object';
|
77 | case Array:
|
78 | return toString.call(val) === '[object Array]';
|
79 | default:
|
80 | return val instanceof t;
|
81 | }
|
82 | }
|
83 |
|
84 | function parse (opt = {}, baseOpt = DEFAULT_OPTIONS, fromCommandLine) {
|
85 |
|
86 | let ret = {};
|
87 |
|
88 | for (let k in baseOpt) {
|
89 | let defaultItem = baseOpt[k];
|
90 | let val = getValue(opt, k);
|
91 |
|
92 | if (val === undefined) {
|
93 | if (defaultItem.default !== undefined && !fromCommandLine) {
|
94 | setValue(ret, k, defaultItem.default);
|
95 | }
|
96 | } else {
|
97 | if (!check(defaultItem.type, val)) {
|
98 | throw `Unexpected type: ${k} expect a ${defaultItem.type.name}`;
|
99 | }
|
100 | setValue(ret, k, val);
|
101 | }
|
102 | }
|
103 | return ret;
|
104 | }
|
105 |
|
106 | function convert (args) {
|
107 | if (!fs.existsSync(DEFAULT_CONFIG)) {
|
108 | throw `No configuration file found in the current directory.`
|
109 | }
|
110 |
|
111 | let opt = require(DEFAULT_CONFIG);
|
112 | let argOpt = parse(args, DEFAULT_OPTIONS, true);
|
113 |
|
114 | argOpt.watch = !!args.watch;
|
115 | argOpt.noCache = !!args.noCache;
|
116 |
|
117 | return Object.assign({}, parse(opt), argOpt);
|
118 | }
|
119 |
|
120 | exports = module.exports = {
|
121 | setValue: setValue,
|
122 | getValue: getValue,
|
123 | parse: parse,
|
124 | convert: convert
|
125 | }
|