diff --git a/packages/bundler-webpack/package.json b/packages/bundler-webpack/package.json index fcc4355..c899c1b 100644 --- a/packages/bundler-webpack/package.json +++ b/packages/bundler-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@mainset/bundler-webpack", - "version": "0.2.0", + "version": "0.2.1-rc.1", "description": "Bundler for web apps", "homepage": "https://github.com/mainset/dev-stack-fe/tree/main/packages/bundler-webpack", "bugs": { diff --git a/packages/bundler-webpack/src/webpack-config/plugins/html-preload-css-webpack-plugin.mts b/packages/bundler-webpack/src/webpack-config/plugins/html-preload-css-webpack-plugin.mts new file mode 100644 index 0000000..cc58f09 --- /dev/null +++ b/packages/bundler-webpack/src/webpack-config/plugins/html-preload-css-webpack-plugin.mts @@ -0,0 +1,55 @@ +import type { HtmlTagObject } from 'html-webpack-plugin'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; +import type { Compilation, Compiler } from 'webpack'; + +/** + * HtmlPreloadCssWebpackPlugin + * Removes blinking CSS during SSR (Server-Side Rendering) by preloading CSS files. + * + * This plugin modifies the HTML output to add preload tags for CSS files. + * It hooks into the HtmlWebpackPlugin to alter the asset tag groups. + * + * The tag format will be: + * + * + * Added before: + * + */ +class HtmlPreloadCssWebpackPlugin { + apply(compiler: Compiler) { + compiler.hooks.compilation.tap( + 'HtmlPreloadCssWebpackPlugin', + (compilation: Compilation) => { + HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync( + 'HtmlPreloadCssWebpackPlugin', + (data, cb) => { + const newHeadTags: HtmlTagObject[] = []; + + data.headTags.forEach((tag) => { + if ( + tag.tagName === 'link' && + tag.attributes?.rel === 'stylesheet' + ) { + newHeadTags.push({ + ...tag, + attributes: { + ...tag.attributes, + rel: 'preload', + as: 'style', + }, + }); + } + + newHeadTags.push(tag); + }); + + data.headTags = newHeadTags; + cb(null, data); + }, + ); + }, + ); + } +} + +export { HtmlPreloadCssWebpackPlugin }; diff --git a/packages/bundler-webpack/src/webpack-config/plugins/index.mts b/packages/bundler-webpack/src/webpack-config/plugins/index.mts new file mode 100644 index 0000000..e217889 --- /dev/null +++ b/packages/bundler-webpack/src/webpack-config/plugins/index.mts @@ -0,0 +1 @@ +export { HtmlPreloadCssWebpackPlugin } from './html-preload-css-webpack-plugin.mjs'; diff --git a/packages/bundler-webpack/src/webpack-config/webapp.ssr.config.mts b/packages/bundler-webpack/src/webpack-config/webapp.ssr.config.mts index fc406a4..b71e02d 100644 --- a/packages/bundler-webpack/src/webpack-config/webapp.ssr.config.mts +++ b/packages/bundler-webpack/src/webpack-config/webapp.ssr.config.mts @@ -6,6 +6,7 @@ import path from 'path'; import { devWebpackConfigFragment } from './config-fragments/dev.fragment.mjs'; import { prodWebpackConfigFragment } from './config-fragments/prod.fragment.mjs'; import { ssrWebappWebpackConfigFragment } from './config-fragments/ssr-webapp.fragment.mjs'; +import { HtmlPreloadCssWebpackPlugin } from './plugins/index.mjs'; import ssrServerEnvBasedConfig from './server.ssr.config.mjs'; const ssrWebappGeneralConfig = merge(ssrWebappWebpackConfigFragment, { @@ -14,6 +15,7 @@ const ssrWebappGeneralConfig = merge(ssrWebappWebpackConfigFragment, { template: path.join(runtimePathById.src, 'index.template.html'), filename: 'server.html', }), + new HtmlPreloadCssWebpackPlugin(), ], });