UNPKG

@plugin-web-update-notice/webpack

Version:
1 lines 10 kB
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/ban-ts-comment */\r\nimport { accessSync, constants, readFileSync, writeFileSync } from 'fs'\r\nimport { resolve } from 'path'\r\nimport type { Options } from '@plugin-web-update-notification/core'\r\nimport {\r\n DIRECTORY_NAME,\r\n INJECT_SCRIPT_FILE_NAME,\r\n INJECT_STYLE_FILE_NAME,\r\n JSON_FILE_NAME,\r\n NOTIFICATION_ANCHOR_CLASS_NAME,\r\n generateJSONFileContent,\r\n generateJsFileContent,\r\n getFileHash,\r\n getVersion,\r\n get__Dirname,\r\n} from '@plugin-web-update-notification/core'\r\nimport type { Compilation, Compiler } from 'webpack'\r\n\r\nconst pluginName = 'WebUpdateNotificationPlugin'\r\n\r\ntype PluginOptions = Options & {\r\n /** index.html file path, by default, we will look up path.resolve(webpackOutputPath, './index.html') */\r\n indexHtmlFilePath?: string\r\n}\r\n\r\n/**\r\n * It injects the hash into the HTML, and injects the notification anchor and the stylesheet and the\r\n * script into the HTML\r\n * @param {string} html - The original HTML of the page\r\n * @param {string} version - The hash of the current commit\r\n * @param {Options} options - Options\r\n * @param cssFileHash\r\n * @param jsFileHash\r\n * @returns The html of the page with the injected script and css.\r\n */\r\nfunction injectPluginHtml(\r\n html: string,\r\n version: string,\r\n options: Options,\r\n { cssFileHash, jsFileHash }: { jsFileHash: string; cssFileHash: string },\r\n) {\r\n const { customNotificationHTML, hiddenDefaultNotification, injectFileBase = '/' } = options\r\n\r\n const versionScript = `<script>window.pluginWebUpdateNotice_version = '${version}';</script>`\r\n const cssLinkHtml = customNotificationHTML || hiddenDefaultNotification ? '' : `<link rel=\"stylesheet\" href=\"${injectFileBase}${DIRECTORY_NAME}/${INJECT_STYLE_FILE_NAME}.${cssFileHash}.css\">`\r\n let res = html\r\n\r\n res = res.replace(\r\n '<head>',\r\n `<head>\r\n ${cssLinkHtml}\r\n <script src=\"${injectFileBase}${DIRECTORY_NAME}/${INJECT_SCRIPT_FILE_NAME}.${jsFileHash}.js\"></script>\r\n ${versionScript}`,\r\n )\r\n\r\n if (!hiddenDefaultNotification)\r\n res = res.replace('</body>', `<div class=\"${NOTIFICATION_ANCHOR_CLASS_NAME}\"></div></body>`)\r\n\r\n return res\r\n}\r\n\r\n/**\r\n * It injects the hash into the HTML, and injects the notification anchor and the stylesheet and the\r\n * script into the HTML\r\n * @param {string} html - The original HTML of the page\r\n * @param {string} version - The hash of the current commit\r\n * @param {Options} options - Options\r\n * @param injectStyleContent\r\n * @param injectScriptContent\r\n * @returns The html of the page with the injected script and css.\r\n */\r\nfunction injectPluginHTMLInline(html: string, version: string, options: Options, {\r\n injectStyleContent,\r\n injectScriptContent,\r\n}: { injectStyleContent: string; injectScriptContent: string }) {\r\n const { customNotificationHTML, hiddenDefaultNotification } = options\r\n\r\n const versionScript = `<script>window.pluginWebUpdateNotice_version = '${version}';</script>`\r\n\r\n let pluginStyle: string\r\n if (customNotificationHTML || hiddenDefaultNotification)\r\n pluginStyle = ''\r\n else\r\n pluginStyle = `<style>${injectStyleContent}</style>`\r\n\r\n let res = html\r\n\r\n const pluginScript = `<script>${injectScriptContent}</script>`\r\n\r\n res = res.replace(\r\n '<head>',\r\n `<head>\r\n ${pluginStyle}\r\n ${pluginScript}\r\n ${versionScript}`,\r\n )\r\n\r\n if (!hiddenDefaultNotification)\r\n res = res.replace('</body>', `<div class=\"${NOTIFICATION_ANCHOR_CLASS_NAME}\"></div></body>`)\r\n\r\n return res\r\n}\r\n\r\nclass WebUpdateNotificationPlugin {\r\n options: PluginOptions\r\n\r\n constructor(options: PluginOptions) {\r\n this.options = options || {}\r\n }\r\n\r\n apply(compiler: Compiler) {\r\n /** inject script file hash */\r\n let jsFileHash = ''\r\n /** inject css file hash */\r\n let cssFileHash = ''\r\n // inject script file content\r\n let injectScriptContent = ''\r\n // inject css file content\r\n let injectStyleContent = ''\r\n\r\n const { publicPath } = compiler.options.output\r\n if (this.options.injectFileBase === undefined)\r\n this.options.injectFileBase = typeof publicPath === 'string' ? publicPath : '/'\r\n\r\n const {\r\n hiddenDefaultNotification,\r\n versionType,\r\n indexHtmlFilePath,\r\n customVersion,\r\n silence,\r\n microApp,\r\n } = this.options\r\n let version = ''\r\n version = versionType === 'custom' ? getVersion(versionType, customVersion!) : getVersion(versionType!)\r\n\r\n compiler.hooks.emit.tap(pluginName, (compilation: Compilation) => {\r\n // const outputPath = compiler.outputPath\r\n const jsonFileContent = generateJSONFileContent(version, silence)\r\n // @ts-expect-error\r\n compilation.assets[`${DIRECTORY_NAME}/${JSON_FILE_NAME}.json`] = {\r\n source: () => jsonFileContent,\r\n size: () => jsonFileContent.length,\r\n }\r\n if (!hiddenDefaultNotification) {\r\n injectStyleContent = readFileSync(`${get__Dirname()}/${INJECT_STYLE_FILE_NAME}.css`, 'utf8')\r\n cssFileHash = getFileHash(injectStyleContent)\r\n\r\n // @ts-expect-error\r\n compilation.assets[`${DIRECTORY_NAME}/${INJECT_STYLE_FILE_NAME}.${cssFileHash}.css`] = {\r\n source: () => injectStyleContent,\r\n size: () => injectStyleContent.length,\r\n }\r\n }\r\n\r\n const filePath = resolve(`${get__Dirname()}/${INJECT_SCRIPT_FILE_NAME}.js`)\r\n injectScriptContent = generateJsFileContent(\r\n readFileSync(filePath, 'utf8').toString(),\r\n version,\r\n this.options,\r\n )\r\n jsFileHash = getFileHash(injectScriptContent)\r\n\r\n // @ts-expect-error\r\n compilation.assets[`${DIRECTORY_NAME}/${INJECT_SCRIPT_FILE_NAME}.${jsFileHash}.js`] = {\r\n source: () => injectScriptContent,\r\n size: () => injectScriptContent.length,\r\n }\r\n })\r\n\r\n compiler.hooks.afterEmit.tap(pluginName, () => {\r\n const htmlFilePath = resolve(compiler.outputPath, indexHtmlFilePath || './index.html')\r\n try {\r\n accessSync(htmlFilePath, constants.F_OK)\r\n\r\n let html = readFileSync(htmlFilePath, 'utf8')\r\n // micro-app environment will inject script into index.html\r\n if (microApp)\r\n html = injectPluginHTMLInline(html, version, this.options, { injectStyleContent, injectScriptContent })\r\n // normal environment\r\n else\r\n html = injectPluginHtml(html, version, this.options, { jsFileHash, cssFileHash })\r\n\r\n writeFileSync(htmlFilePath, html)\r\n }\r\n catch (error) {\r\n console.error(error)\r\n console.error(`${pluginName} failed to inject the plugin into the HTML file. index.html(${htmlFilePath}) not found.`)\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport { WebUpdateNotificationPlugin }\r\n"],"mappings":"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","names":["src_exports","__export","WebUpdateNotificationPlugin","__toCommonJS","import_fs","import_path","import_core","pluginName","injectPluginHtml","html","version","options","cssFileHash","jsFileHash","customNotificationHTML","hiddenDefaultNotification","injectFileBase","versionScript","cssLinkHtml","res","injectPluginHTMLInline","injectStyleContent","injectScriptContent","pluginStyle","pluginScript","compiler","publicPath","versionType","indexHtmlFilePath","customVersion","silence","microApp","compilation","jsonFileContent","filePath","htmlFilePath","error"]}