@regru/webpack-babel-multi-target-plugin
Version:
A Webpack plugin that works with Babel to allow deployment of ES2015 builds targeted to modern browsers, with an ES5 fallback for legacy browsers.
191 lines • 6.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const constants_1 = require("./constants");
const defaults_1 = require("./defaults");
// webpack doesn't actually export things from the `compilation` namespace, so can only use them to
// type checking, not anything at runtime like instanceof
// so, need to do this instead
const SIG = {
module: [
'disconnect',
'unseal',
'isEntryModule',
'isInChunk',
],
entrypoint: [
'isInitial',
'getFiles',
'getRuntimeChunk',
'setRuntimeChunk',
],
chunk: [
'hasRuntime',
'canBeInitial',
'isOnlyInitial',
'hasEntryModule',
'addModule',
'removeModule',
'setModules',
'getNumberOfModules',
'addGroup',
'isInGroup',
'canBeIntegrated',
],
chunkGroup: [
'unshiftChunk',
'insertChunk',
'pushChunk',
'replaceChunk',
'isInitial',
'addChild',
'getChildren',
'getNumberOfChildren',
],
};
function hasSig(obj, sig) {
return sig.every(name => typeof obj[name] === 'function');
}
function isModule(obj) {
return hasSig(obj, SIG.module);
}
function isEntrypoint(obj) {
return hasSig(obj, SIG.entrypoint);
}
function isChunkGroup(obj) {
return hasSig(obj, SIG.chunkGroup);
}
function isChunk(obj) {
return hasSig(obj, SIG.chunk);
}
class BabelTarget {
constructor(info) {
Object.assign(this, info);
}
getTargetedAssetName(name) {
return this.tagAssetsWithKey ? `${name}.${this.key}` : name;
}
getTargetedRequest(request) {
const tag = `babel-target=${this.key}`;
if (request.includes(tag)) {
return request;
}
if (request.includes('babel-target=')) {
throw new Error('The request was already tagged with a different target');
}
// need to make separate "requests" for the dev server client, but using the query breaks it, so use a hash instead
const joiner = request.startsWith(constants_1.DEV_SERVER_CLIENT) ?
'#' :
request.includes('?') && !request.includes('imports-loader') && !request.includes('exports-loader') ? '&' : '?';
return request + joiner + tag;
}
static isTaggedRequest(request) {
return /[?&]babel-target=\w+/.test(request);
}
static getTargetFromTag(request, targets) {
if (!BabelTarget.isTaggedRequest(request)) {
return undefined;
}
const key = request.match(/\bbabel-target=(\w+)/)[1];
return targets.find(target => target.key === key);
}
static getTargetFromModule(module) {
if (module.options && module.options.babelTarget) {
return module.options.babelTarget;
}
if (!module.reasons) {
return undefined;
}
for (const reason of module.reasons) {
if (reason.dependency && reason.dependency.babelTarget) {
return reason.dependency.babelTarget;
}
if (reason.module) {
const target = BabelTarget.getTargetFromModule(reason.module);
if (target) {
return target;
}
}
}
return undefined;
}
static getTargetFromEntrypoint(entrypoint) {
return BabelTarget.getTargetFromModule(entrypoint.runtimeChunk.entryModule);
}
// eslint-disable-next-line
static getTargetFromGroup(group) {
return undefined;
}
static getTargetFromChunk(chunk) {
if (chunk.entryModule) {
return BabelTarget.getTargetFromModule(chunk.entryModule);
}
return undefined;
}
static findTarget(source) {
if (isModule(source)) {
return BabelTarget.getTargetFromModule(source);
}
if (isEntrypoint(source)) {
return BabelTarget.getTargetFromEntrypoint(source);
}
if (isChunkGroup(source)) {
return BabelTarget.getTargetFromGroup(source);
}
if (isChunk(source)) {
return BabelTarget.getTargetFromChunk(source);
}
return undefined;
}
}
exports.BabelTarget = BabelTarget;
class BabelTargetFactory {
constructor(presetOptions, plugins) {
this.presetOptions = presetOptions;
this.plugins = plugins;
}
createBabelTarget(profileName, options, loaderOptions) {
const browsers = options.browsers || defaults_1.DEFAULT_BROWSERS[profileName];
const key = options.key || profileName;
const info = Object.assign({}, defaults_1.DEFAULT_TARGET_INFO[profileName], options, {
profileName,
browsers,
key,
options: this.createTransformOptions(key, browsers, loaderOptions),
});
return new BabelTarget(info);
}
createTransformOptions(key, browsers, loaderOptions) {
const mergedPresetOptions = Object.assign({}, defaults_1.DEFAULT_BABEL_PRESET_OPTIONS, this.presetOptions, {
targets: {
browsers,
},
}, {
modules: false,
});
const cacheDirectory = this.getCacheDirectory(key, loaderOptions.cacheDirectory);
return {
presets: [
['@babel/preset-env', mergedPresetOptions],
],
plugins: [
...defaults_1.DEFAULT_BABEL_PLUGINS,
...this.plugins,
],
cacheDirectory,
};
}
getCacheDirectory(key, option) {
if (option === false) {
return undefined;
}
if (option === true || typeof option === 'undefined') {
return `node_modules/.cache/babel-loader/${key}`;
}
if (typeof option === 'function') {
return option(key);
}
return option;
}
}
exports.BabelTargetFactory = BabelTargetFactory;
//# sourceMappingURL=babel-target.js.map