Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add html plugin for mako #12629

Merged
merged 1 commit into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion packages/preset-umi/src/features/mako/mako.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import path from 'path';
import { IApi } from '../../types';
import {
EntryAssets,
extractEntryAssets,
} from '../../utils/extractEntryAssets';
import { isWindows } from '../../utils/platform';

export default (api: IApi) => {
Expand Down Expand Up @@ -45,17 +49,52 @@ export default (api: IApi) => {
enableBy: api.EnableBy.config,
});

// html 处理逻辑
const assets: EntryAssets = {
// Will contain all js and mjs files
js: [],
// Will contain all css files
css: [],
};

api.modifyConfig((memo) => {
// @TODO remove this when mako support windows
if (isWindows) {
memo.mako = false;
process.env.OKAM = '';
}
const makoPlugins = memo.mako?.plugins || [];
if (!api.config.mpa) {
makoPlugins.push({
name: 'UmiHtmlGenerationMako',
generateEnd: ({ stats }: any) => {
const entryPointFiles = new Set<string>();

for (const chunk of stats.entrypoints['umi'].chunks) {
const files = stats.chunks.find((c: any) => c.id === chunk).files;
for (const file of files) {
entryPointFiles.add(file);
}
}

let entryAssets = extractEntryAssets(Array.from(entryPointFiles));
Object.entries(entryAssets).forEach(([ext, files]) => {
if (!Array.isArray(assets[ext])) {
assets[ext] = [];
}
assets[ext].push(...files);
});
},
});
}
return {
...memo,
mfsu: false,
hmrGuardian: false,
makoPlugins: memo.mako?.plugins || [],
mako: {
...memo.mako,
plugins: makoPlugins,
},
};
});

Expand All @@ -78,4 +117,21 @@ export default (api: IApi) => {
console.error(e);
}
});

api.addHTMLStyles(() => {
const { publicPath } = api.config;
const displayPublicPath = publicPath === 'auto' ? '/' : publicPath;
return assets.css.map((css) => {
return `${displayPublicPath}${css}`;
});
});

api.addHTMLHeadScripts(() => {
const { publicPath } = api.config;
const displayPublicPath = publicPath === 'auto' ? '/' : publicPath;

return assets.js.map((js) => {
return `${displayPublicPath}${js}`;
});
});
};
49 changes: 10 additions & 39 deletions packages/preset-umi/src/features/webpack/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import type {
Compiler,
} from '@umijs/bundler-webpack/compiled/webpack';
import { IApi } from '../../types';
import {
EntryAssets,
extractEntryAssets,
} from '../../utils/extractEntryAssets';

export default (api: IApi) => {
api.describe({
Expand All @@ -11,7 +15,7 @@ export default (api: IApi) => {
});

// html 处理逻辑
const assets: { js: string[]; css: string[]; [key: string]: string[] } = {
const assets: EntryAssets = {
// Will contain all js and mjs files
js: [],
// Will contain all css files
Expand All @@ -26,45 +30,12 @@ export default (api: IApi) => {
const entryPointFiles = compilation.entrypoints
.get('umi')!
.getFiles();

// Extract paths to .js, .mjs and .css files from the current compilation
const entryPointPublicPathMap: Record<string, boolean> = {};
const extensionRegexp = /\.(css|js|mjs)(\?|$)/;

const UMI_ASSETS_REG = {
js: /^umi(\..+)?\.js$/,
css: /^umi(\..+)?\.css$/,
};

entryPointFiles.forEach((entryPointPublicPath) => {
const extMatch = extensionRegexp.exec(entryPointPublicPath);
// Skip if the public path is not a .css, .mjs or .js file
if (!extMatch) {
return;
}

if (entryPointPublicPath.includes('.hot-update')) {
return;
let entryAssets = extractEntryAssets(entryPointFiles);
Object.entries(entryAssets).forEach(([ext, files]) => {
if (!Array.isArray(assets[ext])) {
assets[ext] = [];
}

// Skip if this file is already known
// (e.g. because of common chunk optimizations)
if (entryPointPublicPathMap[entryPointPublicPath]) {
return;
}

// umi html 默认会注入 不做处理
if (
UMI_ASSETS_REG.js.test(entryPointPublicPath) ||
UMI_ASSETS_REG.css.test(entryPointPublicPath)
) {
return;
}

entryPointPublicPathMap[entryPointPublicPath] = true;
// ext will contain .js or .css, because .mjs recognizes as .js
const ext = extMatch[1] === 'mjs' ? 'js' : extMatch[1];
assets[ext].push(entryPointPublicPath);
assets[ext].push(...files);
});
},
);
Expand Down
60 changes: 60 additions & 0 deletions packages/preset-umi/src/utils/extractEntryAssets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
export type EntryAssets = {
js: string[];
css: string[];
[key: string]: string[];
};

export function extractEntryAssets(entryPointFiles: string[]): EntryAssets {
const assets: {
js: string[];
css: string[];
[key: string]: string[];
} = {
// Will contain all js and mjs files
js: [],
// Will contain all css files
css: [],
};

// Extract paths to .js, .mjs and .css files from the current compilation
const entryPointPublicPathMap: Record<string, boolean> = {};
const extensionRegexp = /\.(css|js|mjs)(\?|$)/;

const UMI_ASSETS_REG = {
js: /^umi(\..+)?\.js$/,
css: /^umi(\..+)?\.css$/,
};

entryPointFiles.forEach((entryPointPublicPath) => {
const extMatch = extensionRegexp.exec(entryPointPublicPath);
// Skip if the public path is not a .css, .mjs or .js file
if (!extMatch) {
return;
}

if (entryPointPublicPath.includes('.hot-update')) {
return;
}

// Skip if this file is already known
// (e.g. because of common chunk optimizations)
if (entryPointPublicPathMap[entryPointPublicPath]) {
return;
}

// umi html 默认会注入 不做处理
if (
UMI_ASSETS_REG.js.test(entryPointPublicPath) ||
UMI_ASSETS_REG.css.test(entryPointPublicPath)
) {
return;
}

entryPointPublicPathMap[entryPointPublicPath] = true;
// ext will contain .js or .css, because .mjs recognizes as .js
const ext = extMatch[1] === 'mjs' ? 'js' : extMatch[1];
assets[ext].push(entryPointPublicPath);
});

return assets;
}
Loading