UNPKG

11.4 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports.validateModulesOption = exports.validateLooseOption = exports.getTargets = exports.electronVersionToChromeVersion = exports.getCurrentNodeVersion = exports.isPluginRequired = exports.validIncludesAndExcludes = exports.MODULE_TRANSFORMATIONS = undefined;
5exports.validatePluginsOption = validatePluginsOption;
6exports.checkDuplicateIncludeExcludes = checkDuplicateIncludeExcludes;
7exports.default = buildPreset;
8
9var _plugins = require("../data/plugins.json");
10
11var _plugins2 = _interopRequireDefault(_plugins);
12
13var _pluginFeatures = require("../data/plugin-features");
14
15var _pluginFeatures2 = _interopRequireDefault(_pluginFeatures);
16
17var _builtIns = require("../data/built-ins.json");
18
19var _builtIns2 = _interopRequireDefault(_builtIns);
20
21var _browserslist = require("browserslist");
22
23var _browserslist2 = _interopRequireDefault(_browserslist);
24
25var _transformPolyfillRequirePlugin = require("./transform-polyfill-require-plugin");
26
27var _transformPolyfillRequirePlugin2 = _interopRequireDefault(_transformPolyfillRequirePlugin);
28
29var _electronToChromium = require("../data/electron-to-chromium");
30
31var _electronToChromium2 = _interopRequireDefault(_electronToChromium);
32
33function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34
35var MODULE_TRANSFORMATIONS = exports.MODULE_TRANSFORMATIONS = {
36 "amd": "transform-es2015-modules-amd",
37 "commonjs": "transform-es2015-modules-commonjs",
38 "systemjs": "transform-es2015-modules-systemjs",
39 "umd": "transform-es2015-modules-umd"
40};
41
42var defaultInclude = ["web.timers", "web.immediate", "web.dom.iterable"];
43
44var validIncludesAndExcludes = exports.validIncludesAndExcludes = [].concat(Object.keys(_pluginFeatures2.default), Object.keys(MODULE_TRANSFORMATIONS).map(function (m) {
45 return MODULE_TRANSFORMATIONS[m];
46}), Object.keys(_builtIns2.default), defaultInclude);
47
48/**
49 * Determine if a transformation is required
50 * @param {Object} supportedEnvironments An Object containing environment keys and the lowest
51 * supported version as a value
52 * @param {Object} plugin An Object containing environment keys and the lowest
53 * version the feature was implmented in as a value
54 * @return {Boolean} Whether or not the transformation is required
55 */
56var isPluginRequired = exports.isPluginRequired = function isPluginRequired(supportedEnvironments, plugin) {
57 if (supportedEnvironments.browsers) {
58 supportedEnvironments = getTargets(supportedEnvironments);
59 }
60
61 var targetEnvironments = Object.keys(supportedEnvironments);
62
63 if (targetEnvironments.length === 0) {
64 return true;
65 }
66
67 var isRequiredForEnvironments = targetEnvironments.filter(function (environment) {
68 // Feature is not implemented in that environment
69 if (!plugin[environment]) {
70 return true;
71 }
72
73 var lowestImplementedVersion = plugin[environment];
74 var lowestTargetedVersion = supportedEnvironments[environment];
75
76 if (lowestTargetedVersion < lowestImplementedVersion) {
77 return true;
78 }
79
80 return false;
81 });
82
83 return isRequiredForEnvironments.length > 0 ? true : false;
84};
85
86var isBrowsersQueryValid = function isBrowsersQueryValid(browsers) {
87 return typeof browsers === "string" || Array.isArray(browsers);
88};
89
90var browserNameMap = {
91 chrome: "chrome",
92 edge: "edge",
93 firefox: "firefox",
94 ie: "ie",
95 ios_saf: "ios",
96 safari: "safari"
97};
98
99var getLowestVersions = function getLowestVersions(browsers) {
100 return browsers.reduce(function (all, browser) {
101 var _browser$split = browser.split(" "),
102 browserName = _browser$split[0],
103 browserVersion = _browser$split[1];
104
105 if (browserName in browserNameMap) {
106 all[browserNameMap[browserName]] = parseInt(browserVersion);
107 }
108 return all;
109 }, {});
110};
111
112var mergeBrowsers = function mergeBrowsers(fromQuery, fromTarget) {
113 return Object.keys(fromTarget).reduce(function (queryObj, targKey) {
114 if (targKey !== "browsers") {
115 queryObj[targKey] = fromTarget[targKey];
116 }
117 return queryObj;
118 }, fromQuery);
119};
120
121var getCurrentNodeVersion = exports.getCurrentNodeVersion = function getCurrentNodeVersion() {
122 return parseFloat(process.versions.node);
123};
124
125var electronVersionToChromeVersion = exports.electronVersionToChromeVersion = function electronVersionToChromeVersion(semverVer) {
126 semverVer = String(semverVer);
127
128 if (semverVer === "1") {
129 semverVer = "1.0";
130 }
131
132 var m = semverVer.match(/^(\d+\.\d+)/);
133 if (!m) {
134 throw new Error("Electron version must be a semver version");
135 }
136
137 var result = _electronToChromium2.default[m[1]];
138 if (!result) {
139 throw new Error("Electron version " + m[1] + " is either too old or too new");
140 }
141
142 return result;
143};
144
145var _extends = Object.assign || function (target) {
146 for (var i = 1; i < arguments.length; i++) {
147 var source = arguments[i];
148 for (var key in source) {
149 if (Object.prototype.hasOwnProperty.call(source, key)) {
150 target[key] = source[key];
151 }
152 }
153 }
154 return target;
155};
156
157var getTargets = exports.getTargets = function getTargets() {
158 var targets = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
159
160 var targetOps = _extends({}, targets);
161
162 if (targetOps.node === true || targetOps.node === "current") {
163 targetOps.node = getCurrentNodeVersion();
164 }
165
166 // Rewrite Electron versions to their Chrome equivalents
167 if (targetOps.electron) {
168 targetOps.chrome = electronVersionToChromeVersion(targetOps.electron);
169 delete targetOps.electron;
170 }
171
172 var browserOpts = targetOps.browsers;
173 if (isBrowsersQueryValid(browserOpts)) {
174 var queryBrowsers = getLowestVersions((0, _browserslist2.default)(browserOpts));
175 return mergeBrowsers(queryBrowsers, targetOps);
176 }
177 return targetOps;
178};
179
180// TODO: Allow specifying plugins as either shortened or full name
181// babel-plugin-transform-es2015-classes
182// transform-es2015-classes
183var validateLooseOption = exports.validateLooseOption = function validateLooseOption() {
184 var looseOpt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
185
186 if (typeof looseOpt !== "boolean") {
187 throw new Error("Preset env: 'loose' option must be a boolean.");
188 }
189
190 return looseOpt;
191};
192
193var validateModulesOption = exports.validateModulesOption = function validateModulesOption() {
194 var modulesOpt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "commonjs";
195
196 if (modulesOpt !== false && Object.keys(MODULE_TRANSFORMATIONS).indexOf(modulesOpt) === -1) {
197 throw new Error("The 'modules' option must be 'false' to indicate no modules\n" + "or a module type which be be one of: 'commonjs' (default), 'amd', 'umd', 'systemjs'");
198 }
199
200 return modulesOpt;
201};
202
203function validatePluginsOption() {
204 var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
205 var type = arguments[1];
206
207 if (!Array.isArray(opts)) {
208 throw new Error("The '" + type + "' option must be an Array<string> of plugins/built-ins");
209 }
210
211 var unknownOpts = [];
212 opts.forEach(function (opt) {
213 if (validIncludesAndExcludes.indexOf(opt) === -1) {
214 unknownOpts.push(opt);
215 }
216 });
217
218 if (unknownOpts.length > 0) {
219 throw new Error("Invalid plugins/built-ins '" + unknownOpts + "' passed to '" + type + "' option.\n Check data/[plugin-features|built-in-features].js in babel-preset-env");
220 }
221
222 return {
223 all: opts,
224 plugins: opts.filter(function (opt) {
225 return !opt.match(/^(es\d+|web)\./);
226 }),
227 builtIns: opts.filter(function (opt) {
228 return opt.match(/^(es\d+|web)\./);
229 })
230 };
231}
232
233var validateIncludeOption = function validateIncludeOption(opts) {
234 return validatePluginsOption(opts, "include");
235};
236var validateExcludeOption = function validateExcludeOption(opts) {
237 return validatePluginsOption(opts, "exclude");
238};
239
240function checkDuplicateIncludeExcludes(include, exclude) {
241 var duplicates = [];
242 include.forEach(function (opt) {
243 if (exclude.indexOf(opt) >= 0) {
244 duplicates.push(opt);
245 }
246 });
247
248 if (duplicates.length > 0) {
249 throw new Error("Duplicate plugins/built-ins: '" + duplicates + "' found\n in both the \"include\" and \"exclude\" options.");
250 }
251}
252
253var hasBeenLogged = false;
254var hasBeenWarned = false;
255
256var logPlugin = function logPlugin(plugin, targets, list) {
257 var envList = list[plugin] || {};
258 var filteredList = Object.keys(targets).reduce(function (a, b) {
259 a[b] = envList[b];
260 return a;
261 }, {});
262 var logStr = "\n " + plugin + " " + JSON.stringify(filteredList);
263 console.log(logStr);
264};
265
266function buildPreset(context) {
267 var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
268
269 var loose = validateLooseOption(opts.loose);
270 var moduleType = validateModulesOption(opts.modules);
271 // TODO: remove whitelist in favor of include in next major
272 if (opts.whitelist && !hasBeenWarned) {
273 hasBeenWarned = true;
274 console.warn("The \"whitelist\" option has been deprecated\n in favor of \"include\" to match the newly added \"exclude\" option (instead of \"blacklist\").");
275 }
276 var include = validateIncludeOption(opts.whitelist || opts.include);
277 var exclude = validateExcludeOption(opts.exclude);
278 checkDuplicateIncludeExcludes(include.all, exclude.all);
279 var targets = getTargets(opts.targets);
280 var debug = opts.debug;
281 var useBuiltIns = opts.useBuiltIns;
282
283 var transformations = Object.keys(_plugins2.default).filter(function (pluginName) {
284 return isPluginRequired(targets, _plugins2.default[pluginName]);
285 });
286
287 var polyfills = void 0;
288 if (useBuiltIns) {
289 polyfills = Object.keys(_builtIns2.default).filter(function (builtInName) {
290 return isPluginRequired(targets, _builtIns2.default[builtInName]);
291 }).concat(defaultInclude).filter(function (plugin) {
292 return exclude.builtIns.indexOf(plugin) === -1;
293 }).concat(include.builtIns);
294 }
295
296 if (debug && !hasBeenLogged) {
297 hasBeenLogged = true;
298 console.log("babel-preset-env: `DEBUG` option");
299 console.log("");
300 console.log("Using targets: " + JSON.stringify(opts.targets, null, 2));
301 console.log("");
302 console.log("modules transform: " + moduleType);
303 console.log("");
304 console.log("Using plugins:");
305 transformations.forEach(function (transform) {
306 logPlugin(transform, opts.targets, _plugins2.default);
307 });
308 console.log("\nUsing polyfills:");
309 if (useBuiltIns && polyfills.length) {
310 polyfills.forEach(function (polyfill) {
311 logPlugin(polyfill, opts.targets, _builtIns2.default);
312 });
313 }
314 }
315
316 var allTransformations = transformations.filter(function (plugin) {
317 return exclude.plugins.indexOf(plugin) === -1;
318 }).concat(include.plugins);
319
320 var regenerator = allTransformations.indexOf("transform-regenerator") >= 0;
321 var modulePlugin = moduleType !== false && MODULE_TRANSFORMATIONS[moduleType];
322 var plugins = [];
323
324 modulePlugin && plugins.push([require("babel-plugin-" + modulePlugin), { loose: loose }]);
325
326 plugins.push.apply(plugins, allTransformations.map(function (pluginName) {
327 return [require("babel-plugin-" + pluginName), { loose: loose }];
328 }));
329
330 useBuiltIns && plugins.push([_transformPolyfillRequirePlugin2.default, { polyfills: polyfills, regenerator: regenerator }]);
331
332 return {
333 plugins: plugins
334 };
335}
\No newline at end of file