refactor: webpack config (#11421)

This commit is contained in:
forehalo
2025-04-03 11:55:56 +00:00
parent 565d7b2b1e
commit c8d22d97d5
51 changed files with 766 additions and 547 deletions

View File

@@ -8,19 +8,14 @@ import { once } from 'lodash-es';
import type { Compiler, WebpackPluginInstance } from 'webpack';
import webpack from 'webpack';
import type { BuildFlags } from './types.js';
export const getPublicPath = (
flags: BuildFlags,
BUILD_CONFIG: BUILD_CONFIG_TYPE
) => {
export const getPublicPath = (BUILD_CONFIG: BUILD_CONFIG_TYPE) => {
const { BUILD_TYPE } = process.env;
if (typeof process.env.PUBLIC_PATH === 'string') {
return process.env.PUBLIC_PATH;
}
if (
flags.mode === 'development' ||
BUILD_CONFIG.debug ||
BUILD_CONFIG.distribution === 'desktop' ||
BUILD_CONFIG.distribution === 'ios' ||
BUILD_CONFIG.distribution === 'android'
@@ -58,11 +53,15 @@ const gitShortHash = once(() => {
const currentDir = Path.dir(import.meta.url);
function getHTMLPluginOptions(
flags: BuildFlags,
BUILD_CONFIG: BUILD_CONFIG_TYPE
) {
const publicPath = getPublicPath(flags, BUILD_CONFIG);
export interface CreateHTMLPluginConfig {
filename?: string;
additionalEntryForSelfhost?: boolean;
injectGlobalErrorHandler?: boolean;
emitAssetsManifest?: boolean;
}
function getHTMLPluginOptions(BUILD_CONFIG: BUILD_CONFIG_TYPE) {
const publicPath = getPublicPath(BUILD_CONFIG);
const cdnOrigin = publicPath.startsWith('/')
? undefined
: new URL(publicPath).origin;
@@ -79,144 +78,159 @@ function getHTMLPluginOptions(
return {
template: currentDir.join('template.html').toString(),
inject: 'body',
filename: 'index.html',
minify: false,
templateParameters: templateParams,
chunks: ['app'],
} satisfies HTMLPlugin.Options;
}
export function createShellHTMLPlugin(
flags: BuildFlags,
BUILD_CONFIG: BUILD_CONFIG_TYPE
) {
const htmlPluginOptions = getHTMLPluginOptions(flags, BUILD_CONFIG);
return new HTMLPlugin({
...htmlPluginOptions,
chunks: ['shell'],
filename: `shell.html`,
});
}
export function createBackgroundWorkerHTMLPlugin(
flags: BuildFlags,
BUILD_CONFIG: BUILD_CONFIG_TYPE
) {
const htmlPluginOptions = getHTMLPluginOptions(flags, BUILD_CONFIG);
return new HTMLPlugin({
...htmlPluginOptions,
chunks: ['backgroundWorker'],
filename: `background-worker.html`,
});
}
export function createPopupHTMLPlugin(
flags: BuildFlags,
BUILD_CONFIG: BUILD_CONFIG_TYPE
) {
const htmlPluginOptions = getHTMLPluginOptions(flags, BUILD_CONFIG);
return new HTMLPlugin({
...htmlPluginOptions,
chunks: ['popup'],
filename: `popup.html`,
});
}
export function createHTMLPlugins(
flags: BuildFlags,
BUILD_CONFIG: BUILD_CONFIG_TYPE
): WebpackPluginInstance[] {
const publicPath = getPublicPath(flags, BUILD_CONFIG);
const globalErrorHandler = [
'js/global-error-handler.js',
readFileSync(currentDir.join('./error-handler.js').toString(), 'utf-8'),
];
const htmlPluginOptions = getHTMLPluginOptions(flags, BUILD_CONFIG);
return [
{
apply(compiler: Compiler) {
compiler.hooks.compilation.tap(
'assets-manifest-plugin',
compilation => {
HTMLPlugin.getHooks(compilation).beforeAssetTagGeneration.tap(
'assets-manifest-plugin',
arg => {
if (
!BUILD_CONFIG.isElectron &&
!compilation.getAsset(globalErrorHandler[0])
) {
compilation.emitAsset(
globalErrorHandler[0],
new webpack.sources.RawSource(globalErrorHandler[1])
);
arg.assets.js.unshift(
arg.assets.publicPath + globalErrorHandler[0]
);
}
if (!compilation.getAsset('assets-manifest.json')) {
compilation.emitAsset(
globalErrorHandler[0],
new webpack.sources.RawSource(globalErrorHandler[1])
);
compilation.emitAsset(
`assets-manifest.json`,
new webpack.sources.RawSource(
JSON.stringify(
{
...arg.assets,
js: arg.assets.js.map(file =>
file.substring(arg.assets.publicPath.length)
),
css: arg.assets.css.map(file =>
file.substring(arg.assets.publicPath.length)
),
gitHash:
htmlPluginOptions.templateParameters.GIT_SHORT_SHA,
description:
htmlPluginOptions.templateParameters.DESCRIPTION,
},
null,
2
)
const AssetsManifestPlugin = {
apply(compiler: Compiler) {
compiler.hooks.compilation.tap('assets-manifest-plugin', compilation => {
HTMLPlugin.getHooks(compilation).beforeAssetTagGeneration.tap(
'assets-manifest-plugin',
arg => {
if (!compilation.getAsset('assets-manifest.json')) {
compilation.emitAsset(
`assets-manifest.json`,
new webpack.sources.RawSource(
JSON.stringify(
{
...arg.assets,
js: arg.assets.js.map(file =>
file.substring(arg.assets.publicPath.length)
),
{
immutable: false,
}
);
}
return arg;
css: arg.assets.css.map(file =>
file.substring(arg.assets.publicPath.length)
),
gitHash: gitShortHash(),
description: DESCRIPTION,
},
null,
2
)
),
{
immutable: false,
}
);
}
return arg;
}
);
});
},
};
const GlobalErrorHandlerPlugin = {
apply(compiler: Compiler) {
const globalErrorHandler = [
'js/global-error-handler.js',
readFileSync(currentDir.join('./error-handler.js').toString(), 'utf-8'),
];
compiler.hooks.compilation.tap(
'global-error-handler-plugin',
compilation => {
HTMLPlugin.getHooks(compilation).beforeAssetTagGeneration.tap(
'global-error-handler-plugin',
arg => {
if (!compilation.getAsset(globalErrorHandler[0])) {
compilation.emitAsset(
globalErrorHandler[0],
new webpack.sources.RawSource(globalErrorHandler[1])
);
arg.assets.js.unshift(
arg.assets.publicPath + globalErrorHandler[0]
);
}
return arg;
}
);
},
},
}
);
},
};
export function createHTMLPlugins(
BUILD_CONFIG: BUILD_CONFIG_TYPE,
config: CreateHTMLPluginConfig
): WebpackPluginInstance[] {
const publicPath = getPublicPath(BUILD_CONFIG);
const htmlPluginOptions = getHTMLPluginOptions(BUILD_CONFIG);
const plugins: WebpackPluginInstance[] = [];
plugins.push(
new HTMLPlugin({
...htmlPluginOptions,
chunks: ['index'],
filename: config.filename,
publicPath,
meta: {
'env:publicPath': publicPath,
},
}),
// selfhost html
new HTMLPlugin({
...htmlPluginOptions,
meta: {
'env:isSelfHosted': 'true',
'env:publicPath': '/',
},
filename: 'selfhost.html',
templateParameters: {
...htmlPluginOptions.templateParameters,
PRECONNECT: '',
},
}),
];
})
);
if (BUILD_CONFIG.isElectron) {
plugins.push(
new HTMLPlugin({
...htmlPluginOptions,
chunks: ['shell'],
filename: 'shell.html',
publicPath,
meta: {
'env:publicPath': publicPath,
},
}),
new HTMLPlugin({
...htmlPluginOptions,
filename: 'popup.html',
chunks: ['popup'],
publicPath,
meta: {
'env:publicPath': publicPath,
},
}),
new HTMLPlugin({
...htmlPluginOptions,
filename: 'background-worker.html',
chunks: ['backgroundWorker'],
publicPath,
meta: {
'env:publicPath': publicPath,
},
})
);
}
if (config.emitAssetsManifest) {
plugins.push(AssetsManifestPlugin);
}
if (config.injectGlobalErrorHandler) {
plugins.push(GlobalErrorHandlerPlugin);
}
if (config.additionalEntryForSelfhost) {
plugins.push(
new HTMLPlugin({
...htmlPluginOptions,
chunks: ['index'],
meta: {
'env:isSelfHosted': 'true',
'env:publicPath': '/',
},
filename: 'selfhost.html',
templateParameters: {
...htmlPluginOptions.templateParameters,
PRECONNECT: '',
},
})
);
}
return plugins;
}