umijs / umi

A framework in react community ✨
https://umijs.org
MIT License
15.37k stars 2.65k forks source link

[Feature Request] 如何重命名umi4打包后的文件名,把umi.js改成app.js ? #10455

Closed meta-explore closed 1 year ago

meta-explore commented 1 year ago

Background

业务强制性需求,必须是app.js

所以,如何重命名umi4打包后的文件名,把umi.js改成app.js ?

fz6m commented 1 year ago

这部分是强约定,目前做不到。

可以尝试把产物 umi.js 重命名成 app.js ,然后把 html 里的 umi.js 引用名改成 app.js ,由此引发的 edge case 自行承担。

meta-explore commented 1 year ago

那就放弃使用umi

cnyballk commented 1 year ago

可以写一个插件,用 chainWebpack 改掉 filename,加上 onBuildHtmlComplete 构建完成后去修改生成的 html 里的 umi.js

Jeepeng commented 1 year ago

有类似需要,尝试通过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同步修改

Hfimy commented 1 year ago

目前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

meta-explore commented 1 year ago
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”吗?

fz6m commented 1 year ago

不推荐自己修改产物的配置,这存在很大的风险,容易造成线上事故,不推荐的行为,先关了。