1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = getUserConfig;
|
7 | exports.watchConfigs = watchConfigs;
|
8 | exports.unwatchConfigs = unwatchConfigs;
|
9 |
|
10 | var _fs = require("fs");
|
11 |
|
12 | var _path = require("path");
|
13 |
|
14 | var _assert = _interopRequireDefault(require("assert"));
|
15 |
|
16 | var _stripJsonComments = _interopRequireDefault(require("strip-json-comments"));
|
17 |
|
18 | var _didyoumean = _interopRequireDefault(require("didyoumean"));
|
19 |
|
20 | var _chalk = _interopRequireDefault(require("chalk"));
|
21 |
|
22 | var _lodash = _interopRequireDefault(require("lodash.isequal"));
|
23 |
|
24 | var _isPlainObject = _interopRequireDefault(require("is-plain-object"));
|
25 |
|
26 | var _reactDevUtils = require("../reactDevUtils");
|
27 |
|
28 | var _watch = require("./watch");
|
29 |
|
30 | var _getPlugins = _interopRequireDefault(require("./getPlugins"));
|
31 |
|
32 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
33 |
|
34 | function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
35 |
|
36 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
37 |
|
38 | const debug = require('debug')('af-webpack:getUserConfig');
|
39 |
|
40 | const plugins = (0, _getPlugins.default)();
|
41 | const pluginNames = plugins.map(p => p.name);
|
42 | const pluginsMapByName = plugins.reduce((memo, p) => {
|
43 | memo[p.name] = p;
|
44 | return memo;
|
45 | }, {});
|
46 | let devServer = null;
|
47 | const USER_CONFIGS = 'USER_CONFIGS';
|
48 |
|
49 | function throwError(msg) {
|
50 | printError(msg);
|
51 | throw new Error(msg);
|
52 | }
|
53 |
|
54 | function printError(messages) {
|
55 | if (devServer) {
|
56 | devServer.sockWrite(devServer.sockets, 'errors', typeof messages === 'string' ? [messages] : messages);
|
57 | }
|
58 | }
|
59 |
|
60 | function reload() {
|
61 | devServer.sockWrite(devServer.sockets, 'content-changed');
|
62 | }
|
63 |
|
64 | function restart(why) {
|
65 | (0, _reactDevUtils.clearConsole)();
|
66 | console.log(_chalk.default.green(`Since ${why}, try to restart the server`));
|
67 | (0, _watch.unwatch)();
|
68 | devServer.close();
|
69 | process.send({
|
70 | type: 'RESTART'
|
71 | });
|
72 | }
|
73 |
|
74 | function merge(oldObj, newObj) {
|
75 | for (const key in newObj) {
|
76 | if (Array.isArray(newObj[key]) && Array.isArray(oldObj[key])) {
|
77 | oldObj[key] = oldObj[key].concat(newObj[key]);
|
78 | } else if ((0, _isPlainObject.default)(newObj[key]) && (0, _isPlainObject.default)(oldObj[key])) {
|
79 | oldObj[key] = Object.assign(oldObj[key], newObj[key]);
|
80 | } else {
|
81 | oldObj[key] = newObj[key];
|
82 | }
|
83 | }
|
84 | }
|
85 |
|
86 | function replaceNpmVariables(value, pkg) {
|
87 | if (typeof value === 'string') {
|
88 | return value.replace('$npm_package_name', pkg.name).replace('$npm_package_version', pkg.version);
|
89 | } else {
|
90 | return value;
|
91 | }
|
92 | }
|
93 |
|
94 | function getUserConfig(opts = {}) {
|
95 | const _opts$cwd = opts.cwd,
|
96 | cwd = _opts$cwd === void 0 ? process.cwd() : _opts$cwd,
|
97 | _opts$configFile = opts.configFile,
|
98 | configFile = _opts$configFile === void 0 ? '.webpackrc' : _opts$configFile,
|
99 | _opts$disabledConfigs = opts.disabledConfigs,
|
100 | disabledConfigs = _opts$disabledConfigs === void 0 ? [] : _opts$disabledConfigs,
|
101 | preprocessor = opts.preprocessor;
|
102 |
|
103 |
|
104 | const rcFile = (0, _path.resolve)(cwd, configFile);
|
105 | const jsRCFile = (0, _path.resolve)(cwd, `${configFile}.js`);
|
106 | (0, _assert.default)(!((0, _fs.existsSync)(rcFile) && (0, _fs.existsSync)(jsRCFile)), `${configFile} file and ${configFile}.js file can not exist at the same time.`);
|
107 | let config = {};
|
108 |
|
109 | if ((0, _fs.existsSync)(rcFile)) {
|
110 | config = JSON.parse((0, _stripJsonComments.default)((0, _fs.readFileSync)(rcFile, 'utf-8')));
|
111 | }
|
112 |
|
113 | if ((0, _fs.existsSync)(jsRCFile)) {
|
114 |
|
115 | delete require.cache[jsRCFile];
|
116 | config = require(jsRCFile);
|
117 |
|
118 | if (config.default) {
|
119 | config = config.default;
|
120 | }
|
121 | }
|
122 |
|
123 | if (typeof preprocessor === 'function') {
|
124 | config = preprocessor(config);
|
125 | }
|
126 |
|
127 |
|
128 | const context = {
|
129 | cwd
|
130 | };
|
131 |
|
132 | let errorMsg = null;
|
133 | Object.keys(config).forEach(key => {
|
134 |
|
135 | if (disabledConfigs.includes(key)) {
|
136 | errorMsg = `Configuration item ${key} is disabled, please remove it.`;
|
137 | }
|
138 |
|
139 |
|
140 | if (!pluginNames.includes(key)) {
|
141 | const guess = (0, _didyoumean.default)(key, pluginNames);
|
142 | const affix = guess ? `do you meen ${guess} ?` : 'please remove it.';
|
143 | errorMsg = `Configuration item ${key} is not valid, ${affix}`;
|
144 | } else {
|
145 |
|
146 | const plugin = pluginsMapByName[key];
|
147 |
|
148 | if (plugin.validate) {
|
149 | try {
|
150 | plugin.validate.call(context, config[key]);
|
151 | } catch (e) {
|
152 | errorMsg = e.message;
|
153 | }
|
154 | }
|
155 | }
|
156 | });
|
157 |
|
158 | if (errorMsg) {
|
159 | if (
|
160 |
|
161 | opts.setConfig) {
|
162 | opts.setConfig(config);
|
163 | }
|
164 |
|
165 | throwError(errorMsg);
|
166 | }
|
167 |
|
168 |
|
169 | if (config.env) {
|
170 | if (config.env[process.env.NODE_ENV]) {
|
171 | merge(config, config.env[process.env.NODE_ENV]);
|
172 | }
|
173 |
|
174 | delete config.env;
|
175 | }
|
176 |
|
177 |
|
178 | const pkgFile = (0, _path.resolve)(cwd, 'package.json');
|
179 |
|
180 | if (Object.keys(config).length && (0, _fs.existsSync)(pkgFile)) {
|
181 | const pkg = JSON.parse((0, _fs.readFileSync)(pkgFile, 'utf-8'));
|
182 | config = Object.keys(config).reduce((memo, key) => {
|
183 | memo[key] = replaceNpmVariables(config[key], pkg);
|
184 | return memo;
|
185 | }, {});
|
186 | }
|
187 |
|
188 | let configFailed = false;
|
189 |
|
190 | function watchConfigsAndRun(_devServer, watchOpts = {}) {
|
191 | devServer = _devServer;
|
192 | const watcher = watchConfigs(opts);
|
193 |
|
194 | if (watcher) {
|
195 | watcher.on('all', () => {
|
196 | try {
|
197 | if (watchOpts.beforeChange) {
|
198 | watchOpts.beforeChange();
|
199 | }
|
200 |
|
201 | const _getUserConfig = getUserConfig(_objectSpread({}, opts, {
|
202 | setConfig(newConfig) {
|
203 | config = newConfig;
|
204 | }
|
205 |
|
206 | })),
|
207 | newConfig = _getUserConfig.config;
|
208 |
|
209 |
|
210 | if (configFailed) {
|
211 | configFailed = false;
|
212 | reload();
|
213 | }
|
214 |
|
215 |
|
216 | var _iteratorNormalCompletion = true;
|
217 | var _didIteratorError = false;
|
218 | var _iteratorError = undefined;
|
219 |
|
220 | try {
|
221 | for (var _iterator = plugins[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
222 | const plugin = _step.value;
|
223 | const name = plugin.name,
|
224 | onChange = plugin.onChange;
|
225 |
|
226 | if (!(0, _lodash.default)(newConfig[name], config[name])) {
|
227 | debug(`Config ${name} changed, from ${JSON.stringify(config[name])} to ${JSON.stringify(newConfig[name])}`);
|
228 | (onChange || restart.bind(null, `${name} changed`)).call(null, {
|
229 | name,
|
230 | val: config[name],
|
231 | newVal: newConfig[name],
|
232 | config,
|
233 | newConfig
|
234 | });
|
235 | }
|
236 | }
|
237 | } catch (err) {
|
238 | _didIteratorError = true;
|
239 | _iteratorError = err;
|
240 | } finally {
|
241 | try {
|
242 | if (!_iteratorNormalCompletion && _iterator.return != null) {
|
243 | _iterator.return();
|
244 | }
|
245 | } finally {
|
246 | if (_didIteratorError) {
|
247 | throw _iteratorError;
|
248 | }
|
249 | }
|
250 | }
|
251 | } catch (e) {
|
252 | configFailed = true;
|
253 | console.error(_chalk.default.red(`Watch handler failed, since ${e.message}`));
|
254 | console.error(e);
|
255 | }
|
256 | });
|
257 | }
|
258 | }
|
259 |
|
260 | debug(`UserConfig: ${JSON.stringify(config)}`);
|
261 | return {
|
262 | config,
|
263 | watch: watchConfigsAndRun
|
264 | };
|
265 | }
|
266 |
|
267 | function watchConfigs(opts = {}) {
|
268 | const _opts$cwd2 = opts.cwd,
|
269 | cwd = _opts$cwd2 === void 0 ? process.cwd() : _opts$cwd2,
|
270 | _opts$configFile2 = opts.configFile,
|
271 | configFile = _opts$configFile2 === void 0 ? '.webpackrc' : _opts$configFile2;
|
272 | const rcFile = (0, _path.resolve)(cwd, configFile);
|
273 | const jsRCFile = (0, _path.resolve)(cwd, `${configFile}.js`);
|
274 | return (0, _watch.watch)(USER_CONFIGS, [rcFile, jsRCFile]);
|
275 | }
|
276 |
|
277 | function unwatchConfigs() {
|
278 | (0, _watch.unwatch)(USER_CONFIGS);
|
279 | } |
\ | No newline at end of file |