Skip to content
微信公众号

前端应用解决方案

目前国内大厂开源的umi.js和modern.js都是前端应用解决方案,但它们有不同的特点和用途。

Umi.js: Umi.js 是一个可插拔的企业级前端应用框架,基于 React 和约定式路由。它提供了一整套开箱即用的功能和约定,包括路由配置、构建工具、插件系统等,使得开发者可以快速搭建和开发复杂的前端应用。Umi.js 支持单页应用(SPA)和多页应用(MPA),并且具有良好的扩展性和灵活性。

Modern.js: Modern.js 是一个现代化的全栈 JavaScript 框架,旨在提供一种简单、高效的方式来构建现代 Web 应用。它采用了一系列最新的技术和工具,如 Vite、React、Vue、TypeScript 等,以及一些内置的功能模块,如路由、状态管理、国际化等,帮助开发者快速构建现代化的前端应用。Modern.js 还支持服务端渲染(SSR)和静态站点生成(SSG),使得应用更具性能和可扩展性。

总结来说,Umi.js 更加注重企业级应用的开发和管理,提供了完善的工具和约定;而 Modern.js 则更加注重现代化的开发体验和技术栈的选择,以简洁高效为目标。选择使用哪个框架取决于项目需求、团队技术栈和个人偏好。

tapable

Tapable是一个用于创建插件系统的库,它是Webpack的核心依赖之一。Tapable提供了一组钩子(hooks),用于在Webpack构建过程中的不同阶段执行自定义逻辑。

Tapable的核心概念是钩子(hooks)。钩子是一个具有特定功能的函数,可以被Webpack的插件使用。Webpack在构建过程中会触发不同的钩子,插件可以注册到这些钩子上,并在相应的时机执行自己的逻辑。

Tapable提供了多种类型的钩子,包括同步钩子(SyncHook)、异步串行钩子(AsyncSeriesHook)、异步并行钩子(AsyncParallelHook)等。不同类型的钩子在触发时机和执行方式上有所区别,可以满足不同场景下的需求。

通过使用Tapable,开发者可以编写自己的Webpack插件,扩展Webpack的功能。插件可以在Webpack构建过程中的不同阶段执行自定义逻辑,例如在解析模块、优化代码、生成资源等环节进行额外的处理。

以下是一个简单的示例,展示了如何使用Tapable创建一个简单的Webpack插件:

js
const { SyncHook } = require('tapable');

class MyPlugin {
  apply(compiler) {
    // 创建一个同步钩子实例
    const hook = new SyncHook(['stats']);

    // 注册到compiler的emit钩子上
    compiler.hooks.emit.tap('MyPlugin', (compilation) => {
      // 执行自定义逻辑
      console.log('Hello from MyPlugin!');
      hook.call(compilation);
    });

    // 注册到自定义钩子上的插件
    hook.tap('MyPlugin', (stats) => {
      console.log('Stats:', stats);
    });
  }
}

module.exports = MyPlugin;

在上面的示例中,我们创建了一个名为MyPlugin的插件,它注册了一个同步钩子hook。在Webpack的emit阶段,插件会执行自定义逻辑,并通过调用钩子的call方法触发注册在钩子上的插件。

这只是一个简单的示例,Tapable提供了更多强大的功能和灵活的扩展方式,可以满足各种复杂的插件开发需求。通过使用Tapable,开发者可以更好地理解和控制Webpack的构建过程,实现更高级的定制化功能。

umi 的插件机制是使用了 tapable 库,我们可以简略的看一下插件流程。

js
// 通过插件加载,把 hooks 整理起来
const hooks = {
  onStart: [
    {
      plugin: "version",
      fn: () => {
        console.log("开始:执行了 version 插件");
      },
    },
    {
      plugin: "other",
      fn: () => {
        console.log("开始:执行了 other 插件");
      },
    },
  ],
  onEnd: [
    {
      plugin: "version",
      fn: () => {
        console.log("结束:执行了 version 插件");
      },
    },
    {
      plugin: "other",
      fn: () => {
        console.log("结束:执行了 other 插件");
      },
    },
  ],
};
// 执行插件中的 onStart 钩子
applyPlugins({ key:'onStart' })

// 做点别的什么事情
console.log('konos@1.0.0');

// 执行插件中的 onEnd 钩子
applyPlugins({ key: 'onEnd' })


//实现 applyPlugins

import { AsyncSeriesWaterfallHook } from "tapable";

// hooks 详见上方代码
const hooks = {...}

const applyPlugins = (opts: { key: string; })=>{
    const hooks = hooks[opts.key] || [];
    const tEvent = new AsyncSeriesWaterfallHook(["_"]);
    for (const hook of hooks) {
      tEvent.tapPromise(
        {
          name: hook.plugin,
        },
        async () => {
          await hook.fn();
        }
      );
    }
    return tEvent.promise(1) as Promise<T>;
}

整个过程,其实就是声明一个 AsyncSeriesWaterfallHook 钩子,然后按照插件注册顺序(for(const hook of hooks)),调用各个插件中声明的函数。

参考文章

中后台解决方案

目前国内开源的中后台解决方案主要有以下几个:

开源后台管理系统模板

本站总访问量次,本站总访客数人次
Released under the MIT License.