UNPKG

10.9 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7
8function _gensync() {
9 const data = require("gensync");
10
11 _gensync = function () {
12 return data;
13 };
14
15 return data;
16}
17
18var _async = require("../gensync-utils/async");
19
20var _util = require("./util");
21
22var context = require("../index");
23
24var _plugin = require("./plugin");
25
26var _item = require("./item");
27
28var _configChain = require("./config-chain");
29
30var _deepArray = require("./helpers/deep-array");
31
32function _traverse() {
33 const data = require("@babel/traverse");
34
35 _traverse = function () {
36 return data;
37 };
38
39 return data;
40}
41
42var _caching = require("./caching");
43
44var _options = require("./validation/options");
45
46var _plugins = require("./validation/plugins");
47
48var _configApi = require("./helpers/config-api");
49
50var _partial = require("./partial");
51
52var Context = require("./cache-contexts");
53
54var _default = _gensync()(function* loadFullConfig(inputOpts) {
55 var _opts$assumptions;
56
57 const result = yield* (0, _partial.default)(inputOpts);
58
59 if (!result) {
60 return null;
61 }
62
63 const {
64 options,
65 context,
66 fileHandling
67 } = result;
68
69 if (fileHandling === "ignored") {
70 return null;
71 }
72
73 const optionDefaults = {};
74 const {
75 plugins,
76 presets
77 } = options;
78
79 if (!plugins || !presets) {
80 throw new Error("Assertion failure - plugins and presets exist");
81 }
82
83 const presetContext = Object.assign({}, context, {
84 targets: options.targets
85 });
86
87 const toDescriptor = item => {
88 const desc = (0, _item.getItemDescriptor)(item);
89
90 if (!desc) {
91 throw new Error("Assertion failure - must be config item");
92 }
93
94 return desc;
95 };
96
97 const presetsDescriptors = presets.map(toDescriptor);
98 const initialPluginsDescriptors = plugins.map(toDescriptor);
99 const pluginDescriptorsByPass = [[]];
100 const passes = [];
101 const externalDependencies = [];
102 const ignored = yield* enhanceError(context, function* recursePresetDescriptors(rawPresets, pluginDescriptorsPass) {
103 const presets = [];
104
105 for (let i = 0; i < rawPresets.length; i++) {
106 const descriptor = rawPresets[i];
107
108 if (descriptor.options !== false) {
109 try {
110 var preset = yield* loadPresetDescriptor(descriptor, presetContext);
111 } catch (e) {
112 if (e.code === "BABEL_UNKNOWN_OPTION") {
113 (0, _options.checkNoUnwrappedItemOptionPairs)(rawPresets, i, "preset", e);
114 }
115
116 throw e;
117 }
118
119 externalDependencies.push(preset.externalDependencies);
120
121 if (descriptor.ownPass) {
122 presets.push({
123 preset: preset.chain,
124 pass: []
125 });
126 } else {
127 presets.unshift({
128 preset: preset.chain,
129 pass: pluginDescriptorsPass
130 });
131 }
132 }
133 }
134
135 if (presets.length > 0) {
136 pluginDescriptorsByPass.splice(1, 0, ...presets.map(o => o.pass).filter(p => p !== pluginDescriptorsPass));
137
138 for (const {
139 preset,
140 pass
141 } of presets) {
142 if (!preset) return true;
143 pass.push(...preset.plugins);
144 const ignored = yield* recursePresetDescriptors(preset.presets, pass);
145 if (ignored) return true;
146 preset.options.forEach(opts => {
147 (0, _util.mergeOptions)(optionDefaults, opts);
148 });
149 }
150 }
151 })(presetsDescriptors, pluginDescriptorsByPass[0]);
152 if (ignored) return null;
153 const opts = optionDefaults;
154 (0, _util.mergeOptions)(opts, options);
155 const pluginContext = Object.assign({}, presetContext, {
156 assumptions: (_opts$assumptions = opts.assumptions) != null ? _opts$assumptions : {}
157 });
158 yield* enhanceError(context, function* loadPluginDescriptors() {
159 pluginDescriptorsByPass[0].unshift(...initialPluginsDescriptors);
160
161 for (const descs of pluginDescriptorsByPass) {
162 const pass = [];
163 passes.push(pass);
164
165 for (let i = 0; i < descs.length; i++) {
166 const descriptor = descs[i];
167
168 if (descriptor.options !== false) {
169 try {
170 var plugin = yield* loadPluginDescriptor(descriptor, pluginContext);
171 } catch (e) {
172 if (e.code === "BABEL_UNKNOWN_PLUGIN_PROPERTY") {
173 (0, _options.checkNoUnwrappedItemOptionPairs)(descs, i, "plugin", e);
174 }
175
176 throw e;
177 }
178
179 pass.push(plugin);
180 externalDependencies.push(plugin.externalDependencies);
181 }
182 }
183 }
184 })();
185 opts.plugins = passes[0];
186 opts.presets = passes.slice(1).filter(plugins => plugins.length > 0).map(plugins => ({
187 plugins
188 }));
189 opts.passPerPreset = opts.presets.length > 0;
190 return {
191 options: opts,
192 passes: passes,
193 externalDependencies: (0, _deepArray.finalize)(externalDependencies)
194 };
195});
196
197exports.default = _default;
198
199function enhanceError(context, fn) {
200 return function* (arg1, arg2) {
201 try {
202 return yield* fn(arg1, arg2);
203 } catch (e) {
204 if (!/^\[BABEL\]/.test(e.message)) {
205 e.message = `[BABEL] ${context.filename || "unknown"}: ${e.message}`;
206 }
207
208 throw e;
209 }
210 };
211}
212
213const makeDescriptorLoader = apiFactory => (0, _caching.makeWeakCache)(function* ({
214 value,
215 options,
216 dirname,
217 alias
218}, cache) {
219 if (options === false) throw new Error("Assertion failure");
220 options = options || {};
221 const externalDependencies = [];
222 let item = value;
223
224 if (typeof value === "function") {
225 const factory = (0, _async.maybeAsync)(value, `You appear to be using an async plugin/preset, but Babel has been called synchronously`);
226 const api = Object.assign({}, context, apiFactory(cache, externalDependencies));
227
228 try {
229 item = yield* factory(api, options, dirname);
230 } catch (e) {
231 if (alias) {
232 e.message += ` (While processing: ${JSON.stringify(alias)})`;
233 }
234
235 throw e;
236 }
237 }
238
239 if (!item || typeof item !== "object") {
240 throw new Error("Plugin/Preset did not return an object.");
241 }
242
243 if ((0, _async.isThenable)(item)) {
244 yield* [];
245 throw new Error(`You appear to be using a promise as a plugin, ` + `which your current version of Babel does not support. ` + `If you're using a published plugin, ` + `you may need to upgrade your @babel/core version. ` + `As an alternative, you can prefix the promise with "await". ` + `(While processing: ${JSON.stringify(alias)})`);
246 }
247
248 if (externalDependencies.length > 0 && (!cache.configured() || cache.mode() === "forever")) {
249 let error = `A plugin/preset has external untracked dependencies ` + `(${externalDependencies[0]}), but the cache `;
250
251 if (!cache.configured()) {
252 error += `has not been configured to be invalidated when the external dependencies change. `;
253 } else {
254 error += ` has been configured to never be invalidated. `;
255 }
256
257 error += `Plugins/presets should configure their cache to be invalidated when the external ` + `dependencies change, for example using \`api.cache.invalidate(() => ` + `statSync(filepath).mtimeMs)\` or \`api.cache.never()\`\n` + `(While processing: ${JSON.stringify(alias)})`;
258 throw new Error(error);
259 }
260
261 return {
262 value: item,
263 options,
264 dirname,
265 alias,
266 externalDependencies: (0, _deepArray.finalize)(externalDependencies)
267 };
268});
269
270const pluginDescriptorLoader = makeDescriptorLoader(_configApi.makePluginAPI);
271const presetDescriptorLoader = makeDescriptorLoader(_configApi.makePresetAPI);
272
273function* loadPluginDescriptor(descriptor, context) {
274 if (descriptor.value instanceof _plugin.default) {
275 if (descriptor.options) {
276 throw new Error("Passed options to an existing Plugin instance will not work.");
277 }
278
279 return descriptor.value;
280 }
281
282 return yield* instantiatePlugin(yield* pluginDescriptorLoader(descriptor, context), context);
283}
284
285const instantiatePlugin = (0, _caching.makeWeakCache)(function* ({
286 value,
287 options,
288 dirname,
289 alias,
290 externalDependencies
291}, cache) {
292 const pluginObj = (0, _plugins.validatePluginObject)(value);
293 const plugin = Object.assign({}, pluginObj);
294
295 if (plugin.visitor) {
296 plugin.visitor = _traverse().default.explode(Object.assign({}, plugin.visitor));
297 }
298
299 if (plugin.inherits) {
300 const inheritsDescriptor = {
301 name: undefined,
302 alias: `${alias}$inherits`,
303 value: plugin.inherits,
304 options,
305 dirname
306 };
307 const inherits = yield* (0, _async.forwardAsync)(loadPluginDescriptor, run => {
308 return cache.invalidate(data => run(inheritsDescriptor, data));
309 });
310 plugin.pre = chain(inherits.pre, plugin.pre);
311 plugin.post = chain(inherits.post, plugin.post);
312 plugin.manipulateOptions = chain(inherits.manipulateOptions, plugin.manipulateOptions);
313 plugin.visitor = _traverse().default.visitors.merge([inherits.visitor || {}, plugin.visitor || {}]);
314
315 if (inherits.externalDependencies.length > 0) {
316 if (externalDependencies.length === 0) {
317 externalDependencies = inherits.externalDependencies;
318 } else {
319 externalDependencies = (0, _deepArray.finalize)([externalDependencies, inherits.externalDependencies]);
320 }
321 }
322 }
323
324 return new _plugin.default(plugin, options, alias, externalDependencies);
325});
326
327const validateIfOptionNeedsFilename = (options, descriptor) => {
328 if (options.test || options.include || options.exclude) {
329 const formattedPresetName = descriptor.name ? `"${descriptor.name}"` : "/* your preset */";
330 throw new Error([`Preset ${formattedPresetName} requires a filename to be set when babel is called directly,`, `\`\`\``, `babel.transform(code, { filename: 'file.ts', presets: [${formattedPresetName}] });`, `\`\`\``, `See https://babeljs.io/docs/en/options#filename for more information.`].join("\n"));
331 }
332};
333
334const validatePreset = (preset, context, descriptor) => {
335 if (!context.filename) {
336 const {
337 options
338 } = preset;
339 validateIfOptionNeedsFilename(options, descriptor);
340
341 if (options.overrides) {
342 options.overrides.forEach(overrideOptions => validateIfOptionNeedsFilename(overrideOptions, descriptor));
343 }
344 }
345};
346
347function* loadPresetDescriptor(descriptor, context) {
348 const preset = instantiatePreset(yield* presetDescriptorLoader(descriptor, context));
349 validatePreset(preset, context, descriptor);
350 return {
351 chain: yield* (0, _configChain.buildPresetChain)(preset, context),
352 externalDependencies: preset.externalDependencies
353 };
354}
355
356const instantiatePreset = (0, _caching.makeWeakCacheSync)(({
357 value,
358 dirname,
359 alias,
360 externalDependencies
361}) => {
362 return {
363 options: (0, _options.validate)("preset", value),
364 alias,
365 dirname,
366 externalDependencies
367 };
368});
369
370function chain(a, b) {
371 const fns = [a, b].filter(Boolean);
372 if (fns.length <= 1) return fns[0];
373 return function (...args) {
374 for (const fn of fns) {
375 fn.apply(this, args);
376 }
377 };
378}
\No newline at end of file