天地玄黄,宇宙洪荒

    前端开发,重要的就是 2 个(类)文件:

    • index.html

    • 静态资源:js & css

    一个一站式的前端开发框架,要做的就是定义、构建、使用以上文件,其中

    • 「定义」是静态的,是描述式的

    • 「构建」和「使用」是运行时的

    • 由于 webpack 的普遍使用,「定义」的一大部分工作就是围绕 webpack 进行;「构建」和本地开发服务器的运行,也都是依赖 webpack

    具体到 umi 框架,使用精巧的插件体系,把上述操作更加语义化以及细化

    • 从纵向看,就是使用插件对 index.html 文件和 webpack files 进行配置

      • webpack files 是一大堆文件:webpack config / webpackrc / entry.js / router.js / etc
    • 从横向看,就是执行命令,并且通过 apply 插件得到定制过的相关文件、配置作为 webpack 的输入

    umi 插件体系的一些初步理解 - 图1再搜索 umi 源码,可以看到更精细的插件 hook 点

    • html 相关

      • modifyHTML
    • webpack 相关

      • modifyWebpackConfig

      • modifyAFWebpackOpts

      • modifyEntryFile

      • router 相关

        • modifyRouterFile

        • modifyRouteComponent

        • modifyRoutes

    以上这几个 hook 都是比较「纯粹」的,看名字就知道了:「modify」

    还有一些 hook 点就不那么 pure 了,比如:generateFiles
    作用是生成 DvaContainer.js 文件,直接就写到 writeSync 了
    (为啥不搞成 pure hook 呢?可以的)

    还有一些 hook 点是和运行时的生命周期挂钩的,看命名也就知道了

    • beforeServerWithApp

    • onStart

    • beforeDevAsync

    • beforeGenerateHTML

    • buildSuccess(为啥不叫 onBuildSuccess ???)

    • etc

    关于 umi 命令生命周期如图所示:
    传送门🚁:https://github.com/umijs/umi/issues/87
    umi 插件体系的一些初步理解 - 图2
    然后,插件就可以选取自己需要的 hook 点进行配置,以 umi-plugin-dva 插件为例:

    1. chenni:umi-plugin-dva/ (master✗) $ grep -rn 'api.register' * [12:28:58]
    2. lib/index.js:210: api.register('generateFiles', () => {
    3. lib/index.js:226: api.register('modifyRouterFile', ({
    4. lib/index.js:241: api.register('modifyRouteComponent', ({
    5. lib/index.js:273: api.register('modifyEntryFile', ({
    6. lib/index.js:285: api.register('modifyAFWebpackOpts', ({
    7. lib/index.js:298: api.register('modifyPageWatchers', ({
    8. src/index.js:178: api.register('generateFiles', () => {
    9. src/index.js:201: api.register('modifyRouterFile', ({ memo }) => {
    10. src/index.js:222: api.register('modifyRouteComponent', ({ memo, args }) => {
    11. src/index.js:255: api.register('modifyEntryFile', ({ memo }) => {
    12. src/index.js:269: api.register('modifyAFWebpackOpts', ({ memo }) => {
    13. src/index.js:285: api.register('modifyPageWatchers', ({ memo }) => {

    所以,最后再总结一下:

    • umi 使用插件体系进行框架的配置和使用

    • 从纵向看,是静态的,通过插件配置各种 hook 点,定义 index 文件、webpack 配置、生命周期 hook

      • 纯配置类 hook,modifyXXX

      • 生命周期类 hook,on/before/afterXXX

      • 其他不纯洁的 hook😅

    • 从横向看,是运行时的,加载需要的插件,在生命周期的各个点读取和执行 hook

    ref:

    未完待续(代码走读:插件的加载和执行)