@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.
107 lines • 5.41 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const babel_target_1 = require("./babel-target");
class NormalizeModuleIdsPlugin {
apply(compiler) {
this.applyModuleIdNormalizing(compiler);
this.applyConditionJsonpCallback(compiler);
this.applyHtmlWebpackTagOrdering(compiler);
}
pluginName(desc) {
return `${NormalizeModuleIdsPlugin.name}${desc ? ': ' : ''}${desc || ''}`;
}
applyModuleIdNormalizing(compiler) {
compiler.hooks.compilation.tap(this.pluginName(), (compilation) => {
if (compilation.name) {
return;
}
compilation.hooks.moduleIds.tap(this.pluginName(), (modules) => {
modules.forEach((module) => {
if (babel_target_1.BabelTarget.isTaggedRequest(module.id)) {
const queryIndex = module.id.indexOf('?');
const ogId = module.id.substring(0, queryIndex);
const query = module.id.substring(queryIndex + 1);
const queryParts = query.split('&').filter((part) => !part.startsWith('babel-target'));
if (!queryParts.length) {
module.id = ogId;
}
else {
module.id = `${ogId}?${queryParts.join('&')}`;
}
}
});
});
});
}
applyConditionJsonpCallback(compiler) {
compiler.hooks.afterPlugins.tap(this.pluginName(), () => {
compiler.hooks.thisCompilation.tap(this.pluginName(), (compilation) => {
if (compilation.name) {
return;
}
compilation.mainTemplate.hooks.beforeStartup.tap(this.pluginName('conditional jsonp callback'), (source) => {
const insertPointCode = 'var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n';
const insertPoint = source.indexOf(insertPointCode);
if (insertPoint < 0) {
return;
}
const before = source.substring(0, insertPoint);
const after = source.substring(insertPoint);
return `${before}if (jsonpArray.push.name === 'webpackJsonpCallback') return;\n${after}`;
});
});
return compiler;
});
}
applyHtmlWebpackTagOrdering(compiler) {
compiler.hooks.afterPlugins.tap(this.pluginName(), () => {
const htmlWebpackPlugin = compiler.options.plugins
// instanceof can act wonky since we don't actually keep our own dependency on html-webpack-plugin
// should we?
.find(plugin => plugin.constructor.name === 'HtmlWebpackPlugin');
if (!htmlWebpackPlugin) {
return;
}
compiler.hooks.compilation.tap(this.pluginName(), (compilation) => {
if (compilation.name) {
return;
}
compilation.hooks.htmlWebpackPluginAlterAssetTags.tapPromise(this.pluginName('reorder asset tags'), (htmlPluginData) => __awaiter(this, void 0, void 0, function* () {
const tags = htmlPluginData.body.slice(0);
// re-sort the tags so that es module tags are rendered first, otherwise maintaining the original order
htmlPluginData.body.sort((a, b) => {
const aIndex = tags.indexOf(a);
const bIndex = tags.indexOf(b);
if (a.tagName !== 'script' || b.tagName !== 'script' ||
!a.attributes || !b.attributes ||
!a.attributes.src || !b.attributes.src ||
(a.attributes.type !== 'module' && b.attributes.type !== 'module')) {
// use the original order
return aIndex - bIndex;
}
if (a.attributes.type === 'module') {
return -1;
}
return 1;
});
htmlPluginData.body.forEach((tag) => {
if (tag.tagName === 'script' && tag.attributes && tag.attributes.nomodule) {
tag.attributes.defer = true;
}
});
return htmlPluginData;
}));
});
});
}
}
exports.NormalizeModuleIdsPlugin = NormalizeModuleIdsPlugin;
//# sourceMappingURL=normalize.module.ids.plugin.js.map