es-dev-server
Version:
Development server for modern web apps
130 lines • 6.44 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCompatibilityTransform = void 0;
const tslib_1 = require("tslib");
const minimatch_1 = tslib_1.__importDefault(require("minimatch"));
const babel_transform_1 = require("./babel-transform");
const constants_1 = require("../constants");
const utils_1 = require("./utils");
function createCompatibilityTransform(cfg) {
/** @type {Map} */
const babelTransforms = new Map();
const minCompatibilityTransform = babel_transform_1.createMinCompatibilityBabelTransform(cfg);
const maxCompatibilityTransform = babel_transform_1.createMaxCompatibilityBabelTransform(cfg);
/**
* Gets the babel compatibility transform for the given user agent. Caches
* babel previously created configs.
*/
function getAutoCompatibilityBabelTranform(file) {
const { browserTarget } = file.uaCompat;
if (!browserTarget) {
throw new Error('No browsertarget');
}
const cachedTransform = babelTransforms.get(browserTarget);
if (cachedTransform) {
return cachedTransform;
}
const babelTransform = babel_transform_1.createCompatibilityBabelTransform({
browserTarget,
readUserBabelConfig: cfg.readUserBabelConfig,
customBabelConfig: cfg.customBabelConfig,
});
babelTransforms.set(browserTarget, babelTransform);
return babelTransform;
}
function isAutoModernTransform(file) {
return cfg.compatibilityMode === constants_1.compatibilityModes.AUTO && file.uaCompat.modern;
}
/**
* Gets the compatibility transform function based on the compatibility
* mode.
*/
function getCompatibilityBabelTranform(file) {
switch (cfg.compatibilityMode) {
case constants_1.compatibilityModes.AUTO:
case constants_1.compatibilityModes.ALWAYS: {
// if this is an auto modern transform, we can skip compatibility transformation
// and just do the custom user transformation
if (cfg.compatibilityMode === constants_1.compatibilityModes.AUTO && isAutoModernTransform(file)) {
return babel_transform_1.createBabelTransform(cfg);
}
return file.uaCompat.browserTarget
? getAutoCompatibilityBabelTranform(file)
: // fall back to max if browser target couldn't be found
maxCompatibilityTransform;
}
case constants_1.compatibilityModes.MIN:
return minCompatibilityTransform;
case constants_1.compatibilityModes.MAX:
return maxCompatibilityTransform;
case constants_1.compatibilityModes.NONE:
return babel_transform_1.createBabelTransform(cfg);
default:
throw new Error(`Unknown compatibility mode: ${cfg.compatibilityMode}`);
}
}
/**
* Returns whether we should do a babel transform, we try to minimize this for performance.
*/
function shouldTransformBabel(file) {
const hasCustomUserConfig = cfg.customBabelConfig || cfg.readUserBabelConfig;
const includeInCustom = hasCustomUserConfig &&
(cfg.customBabelInclude.length === 0 ||
cfg.customBabelInclude.some(pattern => minimatch_1.default(file.filePath, pattern)));
const excludeInCustom = hasCustomUserConfig &&
cfg.customBabelExclude.some(pattern => minimatch_1.default(file.filePath, pattern));
const customUserTransform = hasCustomUserConfig && includeInCustom && !excludeInCustom;
// no compatibility and no custom user transform
if (cfg.compatibilityMode === constants_1.compatibilityModes.NONE && !customUserTransform) {
return false;
}
// auto transform can be skipped for modern browsers if there is no user-defined config
if (!customUserTransform && isAutoModernTransform(file)) {
return false;
}
const excludeFromModern = cfg.babelModernExclude.some(pattern => minimatch_1.default(file.filePath, pattern));
const onlyModernTransform = file.uaCompat.modern && cfg.compatibilityMode !== constants_1.compatibilityModes.MAX;
// if this is only a modern transform, we can skip it if this file is excluded
if (onlyModernTransform && excludeFromModern) {
return false;
}
// we need to run babel if compatibility is turned on, or the user has defined a custom config and we need to include this file
return cfg.compatibilityMode !== constants_1.compatibilityModes.NONE || customUserTransform;
}
/**
* Returns whether we should transform modules to systemjs
*/
function shouldTransformModules(file) {
if (cfg.babelModuleExclude.some(pattern => minimatch_1.default(file.filePath, pattern))) {
return false;
}
return file.transformModule;
}
async function compatibilityTransform(file) {
const excludeFromBabel = cfg.babelExclude.some(pattern => minimatch_1.default(file.filePath, pattern));
const transformBabel = !excludeFromBabel && shouldTransformBabel(file);
const transformModules = shouldTransformModules(file);
let transformedCode = file.code;
utils_1.logDebug(`Compatibility transform babel: ${transformBabel}, ` +
`modules: ${transformModules} ` +
`for request: ${file.filePath}`);
/**
* Transform code to a compatible format based on the compatibility setting. We keep ESM syntax
* in this step, this will be transformed later if necessary.
*/
if (transformBabel) {
const compatTransform = getCompatibilityBabelTranform(file);
transformedCode = await compatTransform(file.filePath, transformedCode);
}
/**
* If this browser doesn't support es modules, compile it to systemjs using babel.
*/
if (transformModules) {
transformedCode = await babel_transform_1.polyfillModulesTransform(file.filePath, transformedCode);
}
return transformedCode;
}
return compatibilityTransform;
}
exports.createCompatibilityTransform = createCompatibilityTransform;
//# sourceMappingURL=compatibility-transform.js.map