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.

128 lines 6.29 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 fs_1 = require("fs"); const path_1 = require("path"); const webpack_sources_1 = require("webpack-sources"); const babel_multi_target_options_1 = require("../babel.multi.target.options"); const plugin_name_1 = require("../plugin.name"); const safari_nomodule_fix_dependency_1 = require("./safari.nomodule.fix.dependency"); class SafariNoModuleFixPlugin { constructor(mode) { this.mode = mode; } apply(compiler) { compiler.hooks.afterPlugins.tap(plugin_name_1.PLUGIN_NAME, () => { if (this.mode === babel_multi_target_options_1.SafariNoModuleFix.external) { this.initExternal(compiler); } this.initHtmlUpdate(compiler); return compiler; }); } initExternal(compiler) { // set up the dependency to be handled by the NormalModuleFactory // compiler.hooks.compilation.tap( // this.constructor.name, // (compilation: Compilation, { normalModuleFactory }: { normalModuleFactory: NormalModuleFactory }) => { // (compilation.dependencyFactories as Map<any, any>).set( // SafariNoModuleFixDependency, // normalModuleFactory // ); // } // ); // // // add the nomodule fix file as an additional entry so that it gets put into its own file // compiler.hooks.make.tapPromise(PLUGIN_NAME, (compilation: Compilation) => { // const dep = new SafariNoModuleFixDependency(); // return new Promise((resolve, reject) => compilation.addEntry(dep.context, dep, dep.filename, (err: Error) => { // if (err) { // return reject(); // } // resolve(); // })); // }); /** * add the nomodule fix script as an additionalAsset * This has the benefit of avoiding the webpack bootstrap boilerplate getting added, which would be completely * useless and wasted bytes since it's not going to be loading any other dependencies. However, it also means skipping * the rest of the JS infrastructure, so no loaders or uglificiation :( * * TODO: maybe it's possible to conditionally mess with the mainTemplate so that it can be loaded like a real entry, but skip all the boilerplate */ compiler.hooks.compilation.tap(plugin_name_1.PLUGIN_NAME, (compilation) => { if (!compilation.name) { return; } compilation.hooks.additionalAssets.tapPromise(plugin_name_1.PLUGIN_NAME, () => __awaiter(this, void 0, void 0, function* () { compilation.assets[safari_nomodule_fix_dependency_1.SafariNoModuleFixDependency.filename] = new webpack_sources_1.RawSource(fs_1.readFileSync(safari_nomodule_fix_dependency_1.SafariNoModuleFixDependency.path, 'utf-8')); return; })); 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; } }); } initHtmlUpdate(compiler) { 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(plugin_name_1.PLUGIN_NAME, (compilation) => { if (compilation.name) { return; } compilation.hooks.htmlWebpackPluginAlterAssetTags.tapPromise(`${plugin_name_1.PLUGIN_NAME} add safari nomodule fix tags`, (htmlPluginData) => __awaiter(this, void 0, void 0, function* () { htmlPluginData.head.unshift(this.createSafariNoModuleFixTag()); return htmlPluginData; })); }); } createSafariNoModuleFixTag() { // TODO: minify the nomodule fix js const tag = { tagName: 'script', closeTag: true, attributes: { nomodule: true, type: 'application/javascript', }, }; if (this.mode === babel_multi_target_options_1.SafariNoModuleFix.external) { tag.attributes.src = '/' + safari_nomodule_fix_dependency_1.SafariNoModuleFixDependency.filename; return tag; } const fixContent = fs_1.readFileSync(path_1.resolve(__dirname, 'safari.nomodule.fix.js')); if (this.mode === true || this.mode === babel_multi_target_options_1.SafariNoModuleFix.inline) { tag.innerHTML = fixContent .toString('utf-8'); return tag; } tag.attributes.src = 'data:application/javascript'; const isBase64 = this.mode === babel_multi_target_options_1.SafariNoModuleFix.inlineDataBase64; if (isBase64) { tag.attributes.src += `;base64,${fixContent.toString('base64')}`; return tag; } tag.attributes.src += ',' + encodeURIComponent(fixContent.toString('utf-8') .replace(/\n/g, '') .replace(/\s{2,}/g, ' ')); return tag; } } exports.SafariNoModuleFixPlugin = SafariNoModuleFixPlugin; //# sourceMappingURL=safari.nomodule.fix.plugin.js.map