UNPKG

@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.

112 lines 5.63 kB
"use strict"; 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 plugin_name_1 = require("./plugin.name"); const targeted_chunk_1 = require("./targeted.chunk"); // Works with HtmlWebpackPlugin to make sure the targeted assets are referenced correctly // Tags for assets whose target has `esModule` set are updated with the `"type"="module"` attribute // Tags for assets whose target has `noModule` set are updated with the `"nomodule"` attribute /** * @internalapi */ class BabelMultiTargetHtmlUpdater { constructor(targets) { this.targets = targets; } updateScriptTags(chunkMap, tags) { tags .forEach((tag) => { if (tag.tagName !== 'script') { return; } const targetedChunks = chunkMap.get(tag.attributes.src); // chunks that are added outside of an entry point (e.g. by HtmlWebpackIncludeAssetsPlugin) will not be targeted if (!targetedChunks) { return; } const targets = targetedChunks.map(targetedChunk => targetedChunk.target); if (!targets || !targets.length) { return; } // if this file is referenced by multiple targets, don't change the tag // this can happen with vendor chunks that don't get transpiled if (!targets.every((target, index) => index === 0 || target === targets[index - 1])) { return; } const target = targets[0]; if (target.esModule) { tag.attributes.type = 'module'; return; } if (target.noModule) { tag.attributes.nomodule = true; } }); } // expands any provided chunk names (for options.chunks or options.excludeChunks) to include the targeted versions // of each chunk. also includes the original chunk name if all targets are tagged so that CSS assets are included // or excluded as expected // also relevant: NormalizeCssChunks.extractCssChunks mapChunkNames(chunkNames) { const allTaggedWithKey = this.targets.every(target => target.tagAssetsWithKey); return chunkNames.reduce((result, name) => { if (allTaggedWithKey) { result.push(name); } this.targets.forEach(target => { result.push(target.getTargetedAssetName(name)); }); return result; }, []); } apply(compiler) { compiler.hooks.afterPlugins.tap(plugin_name_1.PLUGIN_NAME, () => { 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; } // not sure if this is a problem since webpack will wait for dependencies to load, but sorting // by auto/dependency will result in a cyclic dependency error for lazy-loaded routes htmlWebpackPlugin.options.chunksSortMode = 'none'; if (htmlWebpackPlugin.options.chunks !== 'all' && htmlWebpackPlugin.options.chunks && htmlWebpackPlugin.options.chunks.length) { htmlWebpackPlugin.options.chunks = this.mapChunkNames(htmlWebpackPlugin.options.chunks); } if (htmlWebpackPlugin.options.excludeChunks && htmlWebpackPlugin.options.excludeChunks.length) { htmlWebpackPlugin.options.excludeChunks = this.mapChunkNames(htmlWebpackPlugin.options.excludeChunks); } compiler.hooks.compilation.tap(plugin_name_1.PLUGIN_NAME, (compilation) => { if (compilation.name) { return; } compilation.hooks.htmlWebpackPluginAlterAssetTags.tapPromise(`${plugin_name_1.PLUGIN_NAME} update asset tags`, (htmlPluginData) => __awaiter(this, void 0, void 0, function* () { const chunkMap = compilation.chunkGroups.reduce((result, chunkGroup) => { chunkGroup.chunks.forEach((chunk) => { chunk.files.forEach((file) => { result.set(file, chunkGroup, chunk); }); }); return result; }, new targeted_chunk_1.TargetedChunkMap(compiler.options.output.publicPath)); this.updateScriptTags(chunkMap, htmlPluginData.head); this.updateScriptTags(chunkMap, htmlPluginData.body); return htmlPluginData; })); }); }); } } exports.BabelMultiTargetHtmlUpdater = BabelMultiTargetHtmlUpdater; //# sourceMappingURL=babel.multi.target.html.updater.js.map