umi在本地开发环境、编译部署时的功能很方便、已扩展。
但业务项目对性能有极高要求,希望页面尽可能轻量级,不必要的代码不引入,比如 @umijs。
支持在页面运行时不注入umi代码,干干净净,或者尽可能降到最低。
页面中只包含有业务项目开发者主动引入的代码。
可配置化开启此功能。
似乎需要选择性引入如下内置插件,但是我不确定哪些插件属于「不引入也不影响编译构建」。
https://github.com/umijs/umi/blob/v3.2.14/packages/umi/src/ServiceWithBuiltIn.ts#L12
https://github.com/umijs/umi/blob/v3.2.14/packages/preset-built-in/src/index.ts
尝试着修改 node_modules/umi/lib/ServiceWithBuiltIn.js ,不引入部分插件,npm run build 不通过。
目前 .umirc.js 大概如下:
import { defineConfig } from 'umi';
import px2viewport from 'postcss-px2viewport';
const path = require('path')
import pkInfo from './package.json';
const isProd = process.env.UMI_ENV === 'prod';
export default defineConfig({
mpa: {},
define: {
'pkgVersion': pkInfo.version,
},
define: {
'pkgVersion': pkInfo.version,
},
styles: !isProd?[
`body { background: #000; }`,
]:[
`body { background: transparent; }`
],
publicPath: isProd
? 'https://somedomain.com/project1/'
: '/',
chainWebpack: function (memo, { }) {
// 删除 umi 内置插件 ,不需要
memo.plugins.delete('locale');
memo.plugins.delete('antd');
memo.plugins.delete('layout');
memo.plugins.delete('routes');
memo.optimization.splitChunks({
chunks: 'all',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 3,
maxInitialRequests: 5,
automaticNameDelimiter: '~',
cacheGroups: {
vendors: {
name: `chunk-vendors`,
test: /[\\/]node_modules[\\/]/,
priority: -10,
chunks: 'all',
},
'async-commons': {
// 异步加载公共包、组件等
chunks: 'async',
minChunks: 2,
name: 'async-commons',
priority: 90,
},
commons: {
// 其他同步加载公共包
chunks: 'all',
minChunks: 2,
name: 'commons',
priority: 80,
},
},
});
memo.optimization.usedExports(true);
},
extraPostCSSPlugins: [px2viewport({ viewportWidth: 1080 })]
});
但Umi还是注入了很多不需要的代码:

build 时会走 tree shaking,代码会干掉的
build 时会走 tree shaking,代码会干掉的
截图中的就是通过 ANALYZE=1 npm run build 构建出来的,看起来还是有 @umijs 等包
我们这么来讨论这个问题,你的目的是希望 『对性能有极高要求,希望页面尽可能轻量级,不必要的代码不引入,比如 @umijs』?
第一个问题,对性能有极高要求,这个性能是指 页面渲染速度?静态资源加载速度?代码编译速度?你最好有个明确的目标甚至是指标。
第二个问题,希望页面尽可能轻量级,这个页面轻量级是希望书写页面时用更少的代码?页面运行时加载更少的资源?
第三个问题,不希望引入不必要的模块,例如:umijs。这个如上面 @ycjcl868 所说,treeshaking已经把没有用的都删掉了,所以如果你还能看到,那就说明它有被用到。
我们应该这么思考这个问题,umi作为一个一站式的框架提供了什么?
她提供了从开发 -> 编译 -> 运行 三方面的工具和便利。因为有运行时便利,所以就一定会有 umi 自己的代码会被加载到运行时里,这个无法避免。
例如: cra 就不会有运行时侵入,那是因为她提供的是 开发 -> 编译 两方面的工具和便利,并没有提供运行时api。
想通了这个,再回头分析分析,你的真实需求是什么
我明确一下表述,其实我的需求很简单。
问题1:
根本目标是页面打开更快,指标FP, FCP。
问题2:
自然是运行时体积更小。
问题3:
umi在运行环节提供能力,这个没毛病,甚至挺好的。这我肯定是理解的。我的问题是发现注入了不需要的代码。
之前我看到如下代码,认为umi总是会在运行时注入内置插件,所以有此疑问。
https://github.com/umijs/umi/blob/v3.2.14/packages/umi/src/ServiceWithBuiltIn.ts#L12
https://github.com/umijs/umi/blob/v3.2.14/packages/preset-built-in/src/index.ts
讨论到目前为止,关键点是基于“treeshaking会把没有用的代码删掉”,所以得出结论“如果你还能看到,那就说明它有被用到”。
其实业务项目中没有直接引入,我可以确认一下是否有间接引入,以及排查一下webpack为什么会引入某个模块。
COMPRESS=none yarn build 在 dist/umi.js 里找依赖链,到底是哪里引入的额外代码,如果有,可以通过开关插件,来避免额外代码的增加
再者看到魔改了 chainWebpack,这里面加戏太多了,建议根据依赖链路排查下,实在排查不了,可以提供复现 Demo
Most helpful comment
我们这么来讨论这个问题,你的目的是希望 『对性能有极高要求,希望页面尽可能轻量级,不必要的代码不引入,比如 @umijs』?
第一个问题,
对性能有极高要求,这个性能是指 页面渲染速度?静态资源加载速度?代码编译速度?你最好有个明确的目标甚至是指标。第二个问题,
希望页面尽可能轻量级,这个页面轻量级是希望书写页面时用更少的代码?页面运行时加载更少的资源?第三个问题,不希望引入不必要的模块,例如:
umijs。这个如上面 @ycjcl868 所说,treeshaking已经把没有用的都删掉了,所以如果你还能看到,那就说明它有被用到。我们应该这么思考这个问题,umi作为一个一站式的框架提供了什么?
她提供了从开发 -> 编译 -> 运行 三方面的工具和便利。因为有运行时便利,所以就一定会有 umi 自己的代码会被加载到运行时里,这个无法避免。
例如: cra 就不会有运行时侵入,那是因为她提供的是 开发 -> 编译 两方面的工具和便利,并没有提供运行时api。
想通了这个,再回头分析分析,你的真实需求是什么