Closed meta-explore closed 1 year ago
这部分是强约定,目前做不到。
可以尝试把产物 umi.js
重命名成 app.js
,然后把 html 里的 umi.js
引用名改成 app.js
,由此引发的 edge case 自行承担。
那就放弃使用umi
可以写一个插件,用 chainWebpack 改掉 filename,加上 onBuildHtmlComplete 构建完成后去修改生成的 html 里的 umi.js
有类似需要,尝试通过chainWebpack修改,部署后页面报错(umi3可以)
chainWebpack(config, { type, ...props }) {
const isDev = process.env.NODE_ENV === 'development';
if (!isDev) {
config.output
.filename(`app.[contenthash:8].js`)
.chunkFilename(`app.[contenthash:8].async.js`);
}
},
目前只能打包完手动修改文件名umi.js => app.js,然后html同步修改
目前umi源码里,getAssetsMap是硬编码取entrypoints['umi'],所以暂无配置可实现,转换思路,可通过新增一个entry入口,最终替换html中umi产物,以你需要的app为例,还需同时满足处理js、css、.map文件:
// 已丢弃文件
const discardedFileMap: Record<string, boolean> = {};
export default (api: IApi) => {
// ... 略,核心逻辑如下
// 新增 app entry
api.modifyEntry((memo) => {
memo.app = memo.umi;
return memo;
});
let buildStats: any;
api.onDevCompileDone(({ stats }) => {
buildStats = stats;
});
api.onBuildComplete(({ err, stats }) => {
if (!err) {
buildStats = stats;
}
});
// 替换 umi 产物
api.modifyHTML({
fn: ($) => {
// @ts-ignore
const scripts = Array.from($('script').map((i, el) => el));
// @ts-ignore
const links = Array.from($('link').map((i, el) => el));
const {
umi: { assets: umiAssets, auxiliaryAssets: umiAuxiliaryAssets },
app: { assets: appAssets },
} = buildStats.toJson().entrypoints;
const outputPath = join(api.cwd, api.config.outputPath || 'dist');
function deleteFile(name: string) {
if (api.name === AppCommand.build && !discardedFileMap[name]) {
try {
unlinkSync(join(outputPath, name));
discardedFileMap[name] = true;
if (umiAuxiliaryAssets.find((item: any) => item.name === `${name}.map`)) {
unlinkSync(join(outputPath, `${name}.map`));
discardedFileMap[`${name}.map`] = true;
}
} catch (error: any) {
console.warn(error.message);
}
}
}
for (let i = 0; i < umiAssets.length; i++) {
const { name: originName } = umiAssets[i];
const { name: targetName } = appAssets[i];
if (!originName.startsWith('umi.') || !targetName.startsWith('app.')) continue;
if (originName.endsWith('.js')) {
const item = scripts.find((el: any) => $(el).attr('src')?.endsWith(originName));
if (item) {
const oldSrc = $(item).attr('src')!;
$(item).attr('src', oldSrc.replace(originName, targetName));
deleteFile(originName);
}
}
if (originName.endsWith('.css')) {
const item = links.find((el: any) => $(el).attr('href')?.endsWith(originName));
if (item) {
const oldHref = $(item).attr('href')!;
$(item).attr('href', oldHref.replace(originName, targetName));
deleteFile(originName);
}
}
}
return $;
},
stage: Number.MAX_SAFE_INTEGER,
});
}
实现并不复杂,定制框架已生产验证,受限于产物输出时umi中硬编码限制 @meta-explore @Jeepeng
function deleteFile(name: string) {
if (api.name === AppCommand.build && !discardedFileMap[name]) {
try {
unlinkSync(join(outputPath, name));
discardedFileMap[name] = true;
if (umiAuxiliaryAssets.find((item: any) => item.name === `${name}.map`)) {
unlinkSync(join(outputPath, `${name}.map`));
discardedFileMap[`${name}.map`] = true;
}
} catch (error: any) {
console.warn(error.message);
}
}
}
这个方法中的 AppCommand
定义的是什么呢?是 “build”吗?
不推荐自己修改产物的配置,这存在很大的风险,容易造成线上事故,不推荐的行为,先关了。
Background
业务强制性需求,必须是app.js
所以,如何重命名umi4打包后的文件名,把umi.js改成app.js ?