UNPKG

18.6 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.buildPresetChain = buildPresetChain;
7exports.buildPresetChainWalker = void 0;
8exports.buildRootChain = buildRootChain;
9function _path() {
10 const data = require("path");
11 _path = function () {
12 return data;
13 };
14 return data;
15}
16function _debug() {
17 const data = require("debug");
18 _debug = function () {
19 return data;
20 };
21 return data;
22}
23var _options = require("./validation/options.js");
24var _patternToRegex = require("./pattern-to-regex.js");
25var _printer = require("./printer.js");
26var _rewriteStackTrace = require("../errors/rewrite-stack-trace.js");
27var _configError = require("../errors/config-error.js");
28var _index = require("./files/index.js");
29var _caching = require("./caching.js");
30var _configDescriptors = require("./config-descriptors.js");
31const debug = _debug()("babel:config:config-chain");
32function* buildPresetChain(arg, context) {
33 const chain = yield* buildPresetChainWalker(arg, context);
34 if (!chain) return null;
35 return {
36 plugins: dedupDescriptors(chain.plugins),
37 presets: dedupDescriptors(chain.presets),
38 options: chain.options.map(o => normalizeOptions(o)),
39 files: new Set()
40 };
41}
42const buildPresetChainWalker = exports.buildPresetChainWalker = makeChainWalker({
43 root: preset => loadPresetDescriptors(preset),
44 env: (preset, envName) => loadPresetEnvDescriptors(preset)(envName),
45 overrides: (preset, index) => loadPresetOverridesDescriptors(preset)(index),
46 overridesEnv: (preset, index, envName) => loadPresetOverridesEnvDescriptors(preset)(index)(envName),
47 createLogger: () => () => {}
48});
49const loadPresetDescriptors = (0, _caching.makeWeakCacheSync)(preset => buildRootDescriptors(preset, preset.alias, _configDescriptors.createUncachedDescriptors));
50const loadPresetEnvDescriptors = (0, _caching.makeWeakCacheSync)(preset => (0, _caching.makeStrongCacheSync)(envName => buildEnvDescriptors(preset, preset.alias, _configDescriptors.createUncachedDescriptors, envName)));
51const loadPresetOverridesDescriptors = (0, _caching.makeWeakCacheSync)(preset => (0, _caching.makeStrongCacheSync)(index => buildOverrideDescriptors(preset, preset.alias, _configDescriptors.createUncachedDescriptors, index)));
52const loadPresetOverridesEnvDescriptors = (0, _caching.makeWeakCacheSync)(preset => (0, _caching.makeStrongCacheSync)(index => (0, _caching.makeStrongCacheSync)(envName => buildOverrideEnvDescriptors(preset, preset.alias, _configDescriptors.createUncachedDescriptors, index, envName))));
53function* buildRootChain(opts, context) {
54 let configReport, babelRcReport;
55 const programmaticLogger = new _printer.ConfigPrinter();
56 const programmaticChain = yield* loadProgrammaticChain({
57 options: opts,
58 dirname: context.cwd
59 }, context, undefined, programmaticLogger);
60 if (!programmaticChain) return null;
61 const programmaticReport = yield* programmaticLogger.output();
62 let configFile;
63 if (typeof opts.configFile === "string") {
64 configFile = yield* (0, _index.loadConfig)(opts.configFile, context.cwd, context.envName, context.caller);
65 } else if (opts.configFile !== false) {
66 configFile = yield* (0, _index.findRootConfig)(context.root, context.envName, context.caller);
67 }
68 let {
69 babelrc,
70 babelrcRoots
71 } = opts;
72 let babelrcRootsDirectory = context.cwd;
73 const configFileChain = emptyChain();
74 const configFileLogger = new _printer.ConfigPrinter();
75 if (configFile) {
76 const validatedFile = validateConfigFile(configFile);
77 const result = yield* loadFileChain(validatedFile, context, undefined, configFileLogger);
78 if (!result) return null;
79 configReport = yield* configFileLogger.output();
80 if (babelrc === undefined) {
81 babelrc = validatedFile.options.babelrc;
82 }
83 if (babelrcRoots === undefined) {
84 babelrcRootsDirectory = validatedFile.dirname;
85 babelrcRoots = validatedFile.options.babelrcRoots;
86 }
87 mergeChain(configFileChain, result);
88 }
89 let ignoreFile, babelrcFile;
90 let isIgnored = false;
91 const fileChain = emptyChain();
92 if ((babelrc === true || babelrc === undefined) && typeof context.filename === "string") {
93 const pkgData = yield* (0, _index.findPackageData)(context.filename);
94 if (pkgData && babelrcLoadEnabled(context, pkgData, babelrcRoots, babelrcRootsDirectory)) {
95 ({
96 ignore: ignoreFile,
97 config: babelrcFile
98 } = yield* (0, _index.findRelativeConfig)(pkgData, context.envName, context.caller));
99 if (ignoreFile) {
100 fileChain.files.add(ignoreFile.filepath);
101 }
102 if (ignoreFile && shouldIgnore(context, ignoreFile.ignore, null, ignoreFile.dirname)) {
103 isIgnored = true;
104 }
105 if (babelrcFile && !isIgnored) {
106 const validatedFile = validateBabelrcFile(babelrcFile);
107 const babelrcLogger = new _printer.ConfigPrinter();
108 const result = yield* loadFileChain(validatedFile, context, undefined, babelrcLogger);
109 if (!result) {
110 isIgnored = true;
111 } else {
112 babelRcReport = yield* babelrcLogger.output();
113 mergeChain(fileChain, result);
114 }
115 }
116 if (babelrcFile && isIgnored) {
117 fileChain.files.add(babelrcFile.filepath);
118 }
119 }
120 }
121 if (context.showConfig) {
122 console.log(`Babel configs on "${context.filename}" (ascending priority):\n` + [configReport, babelRcReport, programmaticReport].filter(x => !!x).join("\n\n") + "\n-----End Babel configs-----");
123 }
124 const chain = mergeChain(mergeChain(mergeChain(emptyChain(), configFileChain), fileChain), programmaticChain);
125 return {
126 plugins: isIgnored ? [] : dedupDescriptors(chain.plugins),
127 presets: isIgnored ? [] : dedupDescriptors(chain.presets),
128 options: isIgnored ? [] : chain.options.map(o => normalizeOptions(o)),
129 fileHandling: isIgnored ? "ignored" : "transpile",
130 ignore: ignoreFile || undefined,
131 babelrc: babelrcFile || undefined,
132 config: configFile || undefined,
133 files: chain.files
134 };
135}
136function babelrcLoadEnabled(context, pkgData, babelrcRoots, babelrcRootsDirectory) {
137 if (typeof babelrcRoots === "boolean") return babelrcRoots;
138 const absoluteRoot = context.root;
139 if (babelrcRoots === undefined) {
140 return pkgData.directories.indexOf(absoluteRoot) !== -1;
141 }
142 let babelrcPatterns = babelrcRoots;
143 if (!Array.isArray(babelrcPatterns)) {
144 babelrcPatterns = [babelrcPatterns];
145 }
146 babelrcPatterns = babelrcPatterns.map(pat => {
147 return typeof pat === "string" ? _path().resolve(babelrcRootsDirectory, pat) : pat;
148 });
149 if (babelrcPatterns.length === 1 && babelrcPatterns[0] === absoluteRoot) {
150 return pkgData.directories.indexOf(absoluteRoot) !== -1;
151 }
152 return babelrcPatterns.some(pat => {
153 if (typeof pat === "string") {
154 pat = (0, _patternToRegex.default)(pat, babelrcRootsDirectory);
155 }
156 return pkgData.directories.some(directory => {
157 return matchPattern(pat, babelrcRootsDirectory, directory, context);
158 });
159 });
160}
161const validateConfigFile = (0, _caching.makeWeakCacheSync)(file => ({
162 filepath: file.filepath,
163 dirname: file.dirname,
164 options: (0, _options.validate)("configfile", file.options, file.filepath)
165}));
166const validateBabelrcFile = (0, _caching.makeWeakCacheSync)(file => ({
167 filepath: file.filepath,
168 dirname: file.dirname,
169 options: (0, _options.validate)("babelrcfile", file.options, file.filepath)
170}));
171const validateExtendFile = (0, _caching.makeWeakCacheSync)(file => ({
172 filepath: file.filepath,
173 dirname: file.dirname,
174 options: (0, _options.validate)("extendsfile", file.options, file.filepath)
175}));
176const loadProgrammaticChain = makeChainWalker({
177 root: input => buildRootDescriptors(input, "base", _configDescriptors.createCachedDescriptors),
178 env: (input, envName) => buildEnvDescriptors(input, "base", _configDescriptors.createCachedDescriptors, envName),
179 overrides: (input, index) => buildOverrideDescriptors(input, "base", _configDescriptors.createCachedDescriptors, index),
180 overridesEnv: (input, index, envName) => buildOverrideEnvDescriptors(input, "base", _configDescriptors.createCachedDescriptors, index, envName),
181 createLogger: (input, context, baseLogger) => buildProgrammaticLogger(input, context, baseLogger)
182});
183const loadFileChainWalker = makeChainWalker({
184 root: file => loadFileDescriptors(file),
185 env: (file, envName) => loadFileEnvDescriptors(file)(envName),
186 overrides: (file, index) => loadFileOverridesDescriptors(file)(index),
187 overridesEnv: (file, index, envName) => loadFileOverridesEnvDescriptors(file)(index)(envName),
188 createLogger: (file, context, baseLogger) => buildFileLogger(file.filepath, context, baseLogger)
189});
190function* loadFileChain(input, context, files, baseLogger) {
191 const chain = yield* loadFileChainWalker(input, context, files, baseLogger);
192 chain == null || chain.files.add(input.filepath);
193 return chain;
194}
195const loadFileDescriptors = (0, _caching.makeWeakCacheSync)(file => buildRootDescriptors(file, file.filepath, _configDescriptors.createUncachedDescriptors));
196const loadFileEnvDescriptors = (0, _caching.makeWeakCacheSync)(file => (0, _caching.makeStrongCacheSync)(envName => buildEnvDescriptors(file, file.filepath, _configDescriptors.createUncachedDescriptors, envName)));
197const loadFileOverridesDescriptors = (0, _caching.makeWeakCacheSync)(file => (0, _caching.makeStrongCacheSync)(index => buildOverrideDescriptors(file, file.filepath, _configDescriptors.createUncachedDescriptors, index)));
198const loadFileOverridesEnvDescriptors = (0, _caching.makeWeakCacheSync)(file => (0, _caching.makeStrongCacheSync)(index => (0, _caching.makeStrongCacheSync)(envName => buildOverrideEnvDescriptors(file, file.filepath, _configDescriptors.createUncachedDescriptors, index, envName))));
199function buildFileLogger(filepath, context, baseLogger) {
200 if (!baseLogger) {
201 return () => {};
202 }
203 return baseLogger.configure(context.showConfig, _printer.ChainFormatter.Config, {
204 filepath
205 });
206}
207function buildRootDescriptors({
208 dirname,
209 options
210}, alias, descriptors) {
211 return descriptors(dirname, options, alias);
212}
213function buildProgrammaticLogger(_, context, baseLogger) {
214 var _context$caller;
215 if (!baseLogger) {
216 return () => {};
217 }
218 return baseLogger.configure(context.showConfig, _printer.ChainFormatter.Programmatic, {
219 callerName: (_context$caller = context.caller) == null ? void 0 : _context$caller.name
220 });
221}
222function buildEnvDescriptors({
223 dirname,
224 options
225}, alias, descriptors, envName) {
226 var _options$env;
227 const opts = (_options$env = options.env) == null ? void 0 : _options$env[envName];
228 return opts ? descriptors(dirname, opts, `${alias}.env["${envName}"]`) : null;
229}
230function buildOverrideDescriptors({
231 dirname,
232 options
233}, alias, descriptors, index) {
234 var _options$overrides;
235 const opts = (_options$overrides = options.overrides) == null ? void 0 : _options$overrides[index];
236 if (!opts) throw new Error("Assertion failure - missing override");
237 return descriptors(dirname, opts, `${alias}.overrides[${index}]`);
238}
239function buildOverrideEnvDescriptors({
240 dirname,
241 options
242}, alias, descriptors, index, envName) {
243 var _options$overrides2, _override$env;
244 const override = (_options$overrides2 = options.overrides) == null ? void 0 : _options$overrides2[index];
245 if (!override) throw new Error("Assertion failure - missing override");
246 const opts = (_override$env = override.env) == null ? void 0 : _override$env[envName];
247 return opts ? descriptors(dirname, opts, `${alias}.overrides[${index}].env["${envName}"]`) : null;
248}
249function makeChainWalker({
250 root,
251 env,
252 overrides,
253 overridesEnv,
254 createLogger
255}) {
256 return function* chainWalker(input, context, files = new Set(), baseLogger) {
257 const {
258 dirname
259 } = input;
260 const flattenedConfigs = [];
261 const rootOpts = root(input);
262 if (configIsApplicable(rootOpts, dirname, context, input.filepath)) {
263 flattenedConfigs.push({
264 config: rootOpts,
265 envName: undefined,
266 index: undefined
267 });
268 const envOpts = env(input, context.envName);
269 if (envOpts && configIsApplicable(envOpts, dirname, context, input.filepath)) {
270 flattenedConfigs.push({
271 config: envOpts,
272 envName: context.envName,
273 index: undefined
274 });
275 }
276 (rootOpts.options.overrides || []).forEach((_, index) => {
277 const overrideOps = overrides(input, index);
278 if (configIsApplicable(overrideOps, dirname, context, input.filepath)) {
279 flattenedConfigs.push({
280 config: overrideOps,
281 index,
282 envName: undefined
283 });
284 const overrideEnvOpts = overridesEnv(input, index, context.envName);
285 if (overrideEnvOpts && configIsApplicable(overrideEnvOpts, dirname, context, input.filepath)) {
286 flattenedConfigs.push({
287 config: overrideEnvOpts,
288 index,
289 envName: context.envName
290 });
291 }
292 }
293 });
294 }
295 if (flattenedConfigs.some(({
296 config: {
297 options: {
298 ignore,
299 only
300 }
301 }
302 }) => shouldIgnore(context, ignore, only, dirname))) {
303 return null;
304 }
305 const chain = emptyChain();
306 const logger = createLogger(input, context, baseLogger);
307 for (const {
308 config,
309 index,
310 envName
311 } of flattenedConfigs) {
312 if (!(yield* mergeExtendsChain(chain, config.options, dirname, context, files, baseLogger))) {
313 return null;
314 }
315 logger(config, index, envName);
316 yield* mergeChainOpts(chain, config);
317 }
318 return chain;
319 };
320}
321function* mergeExtendsChain(chain, opts, dirname, context, files, baseLogger) {
322 if (opts.extends === undefined) return true;
323 const file = yield* (0, _index.loadConfig)(opts.extends, dirname, context.envName, context.caller);
324 if (files.has(file)) {
325 throw new Error(`Configuration cycle detected loading ${file.filepath}.\n` + `File already loaded following the config chain:\n` + Array.from(files, file => ` - ${file.filepath}`).join("\n"));
326 }
327 files.add(file);
328 const fileChain = yield* loadFileChain(validateExtendFile(file), context, files, baseLogger);
329 files.delete(file);
330 if (!fileChain) return false;
331 mergeChain(chain, fileChain);
332 return true;
333}
334function mergeChain(target, source) {
335 target.options.push(...source.options);
336 target.plugins.push(...source.plugins);
337 target.presets.push(...source.presets);
338 for (const file of source.files) {
339 target.files.add(file);
340 }
341 return target;
342}
343function* mergeChainOpts(target, {
344 options,
345 plugins,
346 presets
347}) {
348 target.options.push(options);
349 target.plugins.push(...(yield* plugins()));
350 target.presets.push(...(yield* presets()));
351 return target;
352}
353function emptyChain() {
354 return {
355 options: [],
356 presets: [],
357 plugins: [],
358 files: new Set()
359 };
360}
361function normalizeOptions(opts) {
362 const options = Object.assign({}, opts);
363 delete options.extends;
364 delete options.env;
365 delete options.overrides;
366 delete options.plugins;
367 delete options.presets;
368 delete options.passPerPreset;
369 delete options.ignore;
370 delete options.only;
371 delete options.test;
372 delete options.include;
373 delete options.exclude;
374 if (hasOwnProperty.call(options, "sourceMap")) {
375 options.sourceMaps = options.sourceMap;
376 delete options.sourceMap;
377 }
378 return options;
379}
380function dedupDescriptors(items) {
381 const map = new Map();
382 const descriptors = [];
383 for (const item of items) {
384 if (typeof item.value === "function") {
385 const fnKey = item.value;
386 let nameMap = map.get(fnKey);
387 if (!nameMap) {
388 nameMap = new Map();
389 map.set(fnKey, nameMap);
390 }
391 let desc = nameMap.get(item.name);
392 if (!desc) {
393 desc = {
394 value: item
395 };
396 descriptors.push(desc);
397 if (!item.ownPass) nameMap.set(item.name, desc);
398 } else {
399 desc.value = item;
400 }
401 } else {
402 descriptors.push({
403 value: item
404 });
405 }
406 }
407 return descriptors.reduce((acc, desc) => {
408 acc.push(desc.value);
409 return acc;
410 }, []);
411}
412function configIsApplicable({
413 options
414}, dirname, context, configName) {
415 return (options.test === undefined || configFieldIsApplicable(context, options.test, dirname, configName)) && (options.include === undefined || configFieldIsApplicable(context, options.include, dirname, configName)) && (options.exclude === undefined || !configFieldIsApplicable(context, options.exclude, dirname, configName));
416}
417function configFieldIsApplicable(context, test, dirname, configName) {
418 const patterns = Array.isArray(test) ? test : [test];
419 return matchesPatterns(context, patterns, dirname, configName);
420}
421function ignoreListReplacer(_key, value) {
422 if (value instanceof RegExp) {
423 return String(value);
424 }
425 return value;
426}
427function shouldIgnore(context, ignore, only, dirname) {
428 if (ignore && matchesPatterns(context, ignore, dirname)) {
429 var _context$filename;
430 const message = `No config is applied to "${(_context$filename = context.filename) != null ? _context$filename : "(unknown)"}" because it matches one of \`ignore: ${JSON.stringify(ignore, ignoreListReplacer)}\` from "${dirname}"`;
431 debug(message);
432 if (context.showConfig) {
433 console.log(message);
434 }
435 return true;
436 }
437 if (only && !matchesPatterns(context, only, dirname)) {
438 var _context$filename2;
439 const message = `No config is applied to "${(_context$filename2 = context.filename) != null ? _context$filename2 : "(unknown)"}" because it fails to match one of \`only: ${JSON.stringify(only, ignoreListReplacer)}\` from "${dirname}"`;
440 debug(message);
441 if (context.showConfig) {
442 console.log(message);
443 }
444 return true;
445 }
446 return false;
447}
448function matchesPatterns(context, patterns, dirname, configName) {
449 return patterns.some(pattern => matchPattern(pattern, dirname, context.filename, context, configName));
450}
451function matchPattern(pattern, dirname, pathToTest, context, configName) {
452 if (typeof pattern === "function") {
453 return !!(0, _rewriteStackTrace.endHiddenCallStack)(pattern)(pathToTest, {
454 dirname,
455 envName: context.envName,
456 caller: context.caller
457 });
458 }
459 if (typeof pathToTest !== "string") {
460 throw new _configError.default(`Configuration contains string/RegExp pattern, but no filename was passed to Babel`, configName);
461 }
462 if (typeof pattern === "string") {
463 pattern = (0, _patternToRegex.default)(pattern, dirname);
464 }
465 return pattern.test(pathToTest);
466}
4670 && 0;
468
469//# sourceMappingURL=config-chain.js.map