umi

"version": "3.4.19"

@umijs/preset-built-in 负责注册umi命令

比如:umi generate tmp

image.png

umi generate tmp 的tmp也是在文件generate.ts中

  api.registerGenerator({
    key: 'tmp',
    // @ts-ignore
    Generator: createTmpGenerator({ api }),
  });

使用lerna组合umi跟dumi项目,umi一直安装不成功

lerna.json

{
  "packages": ["packages/*"],
  "npmClient": "yarn",
  "useWorkspaces": true,
  "version": "independent"
}

package.json

{
  "workspaces": [
    "packages/*"
  ]
}

其实控制台做了提示


提示不成功

只是warning不醒目,改成error 提醒要好点,两个项目都加上version字段就顺利安装成功了

使用lerna run 控制台没有umi的脚本输出

加上--stream参数

  "scripts": {
    "start": "lerna run start --stream",
    "start:ui": "lerna --scope geek-ui run start --stream"
  }
有umi输出

umi3.0 dva onAction 在哪里设置

react 中使用svg

webpack 做配置:

[..]
{
    test: /\.svg$/,
    use: ['@svgr/webpack'],
},
[..]

使用:

import { ReactComponent as Logo } from './logo.svg';

Loader: Load SVG images

用vscode观察umi是怎样启动项目的

用umi生成的web项目,在scripts通常是这样

  "scripts": {
    "start": "umi dev",
    "build": "umi build",
    "postinstall": "umi generate tmp",
  },

怎样观测umi是怎样启动项目的,我想debug看看,做如下配置:
launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "inspect umi",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}",
      "program": "${workspaceFolder}/node_modules/umi/lib/cli.js", // umi 脚本所在位置
      // "outFiles": ["${workspaceFolder:cmp}/node_modules/umi/lib/**/*/js"],
      "args": ["dev"] // umi 命令需要的参数
    }
  ]
}

program 跟 args合起来就是umi dev 命令,这样就可以愉快的debug umirc.ts了

如何在VS Code中debug umi,观察编译过程
vscode 调试 umi

umi@3.5.3 项目瘦身

目的:虽然是B端的项目,但是用户首次打开页面觉得很慢,所以需要优化首页文件大小。脑海里的方向有两个:分包,按需加载。查阅umi文档,首先找到dynamicImport,开开心心的做了配置,首页加载的文件大小的确小了大概一半,但是样式出来问题,ant的样式把自定义的样式覆盖了,别人也需要到同样的问题开启dynamicImport后样式引入顺序问题 #5883,审查元素发现自定义的样式是内联的,ant的样式是link进去的,也就是说ant的样式的顺序在自定义样式的后面加载,覆盖了自定义样式,因此需要将ant的顺序在自定义文件之前加载。umijs文档有个chunks配置跟文件加载顺序有关。

import Config from 'webpack-chain'
const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin')

const webpackConfig: any = (_: Config) => {
  _.merge({
    optimization: {
      splitChunks: {
        cacheGroups: {
          antd: {
            name: 'antd',
            chunks: 'all',
            test: /[\\/]node_modules[\\/](antd|@ant-design)[\\/]/,
            priority: 10
          }
        }
      }
    }
  })
}
export default webpackConfig

chunks: ['antd', 'umi'],

这样样式就不会有问题了。但是通过umi-webpack-bundle-analyzer分析有些很大的包(比如echarts docx)被打包到umi.js中导致首页加载的还是比较慢,继续分包

  _.merge({
    optimization: {
      splitChunks: {
        cacheGroups: {
          // 组件库相关
          react: {
            name: 'react',
            chunks: 'all',
            test: /[\\/]node_modules[\\/](react|react-dom|react-router|react-router-dom)[\\/]/,
            priority: 12
          },
          // 图表库相关
          charts: {
            name: 'charts',
            chunks: 'async',
            test: /[\\/]node_modules[\\/](echarts|zrender)[\\/]/,
            priority: 11
          },
          docx: {
            name: 'docx',
            chunks: 'async',
            test: /[\\/]node_modules[\\/](docx)[\\/]/,
            priority: 11
          },
          antd: {
            name: 'antd',
            chunks: 'all',
            test: /[\\/]node_modules[\\/](antd|@ant-design)[\\/]/,
            priority: 10
          }
        }
      }
    }
  })

同时在chunks中做配置

chunks: ['react', 'charts','docx','antd', 'umi'],

包文件是拆分出来了,但是首页加载的时候charts docx等文件还是被加载了,docx echarts并没有在首页用到,why?搜索并没有查到,只好翻看umijs源码。
body插入script文件处:


Html.ts getContent

翻阅代码可以发现在.umrc中定义的chunks: ['react', 'charts','docx','antd', 'umi']在此会被插入到HTML中,插入的顺序是按照从左到右的顺序,左边的会先加载,我们可以把antd的代码写在前面,我们自己写的代码会被打包到umi.js umi.css 中,这样就保证我们自己的代码会把antd的样式覆盖了。将charts跟docx从chunks删掉,修改后的chunks: ['react', 'antd', 'umi'] 这样首页就不会加载charts跟docx。

umi@3.5.3 重写node.js module的_resolveFilename方法的目的是啥子?

requireHook.ts

// files 为webpack的代码
export const files = [
  'webpack/lib/Chunk',
  'webpack/lib/Compilation',
  'webpack/lib/dependencies/ConstDependency',
  'webpack/lib/javascript/JavascriptParserHelpers',
  'webpack/lib/LibraryTemplatePlugin',
  'webpack/lib/LoaderTargetPlugin',
  'webpack/lib/node/NodeTargetPlugin',
  'webpack/lib/node/NodeTemplatePlugin',
  'webpack/lib/ModuleFilenameHelpers',
  'webpack/lib/NormalModule',
  'webpack/lib/RequestShortener',
  'webpack/lib/RuntimeGlobals',
  'webpack/lib/RuntimeModule',
  'webpack/lib/optimize/LimitChunkCountPlugin',
  'webpack/lib/ParserHelpers',
  'webpack/lib/SingleEntryPlugin',
  'webpack/lib/Template',
  'webpack/lib/webworker/WebWorkerTemplatePlugin',
];

export function init() {
  // Allow run once
  if (inited) return;
  inited = true;

  const filesMap = files.map((file) => {
    const fileName = getFileName(file);
    return [file, `@umijs/deps/compiled/webpack/${fileName}`];
  });

  const hookPropertyMap = new Map(
    [
      ['webpack', '@umijs/deps/compiled/webpack'],
      ['webpack/package.json', '@umijs/deps/compiled/webpack/pkgInfo'],
      ...filesMap,
      // ['webpack-sources', '@umijs/deps/compiled/webpack/sources'],
    ].map(([request, replacement]) => [request, require.resolve(replacement)]),
  );

  const mod = require('module');
  const resolveFilename = mod._resolveFilename;
  mod._resolveFilename = function (
    request: string,
    parent: any,
    isMain: boolean,
    options: any,
  ) {
    const hookResolved = hookPropertyMap.get(request);
    if (hookResolved) request = hookResolved;
    return resolveFilename.call(mod, request, parent, isMain, options);
  };
}

Module._resolveFilename 是为了获取模块的绝对路径,重写是为了在使用比如const webpack =require("webpack")的时候不是去node_modules加载webpack,而是从@umijs/deps/compiled/webpack加载。我们在node_modules也可以搜索下webpack目录,发现压根找不到,而是被umi塞到了@umijs/deps/compiled/webpack下,为什么要这么做?,很大的可能性就是为了兼容4 5 两个版本。但是我们使用webpack方式不会变,所以就重写了node.js Module._resolveFilename函数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容