资讯专栏INFORMATION COLUMN

微前端 —— menu&&project1(React)

Euphoria / 1480人阅读

摘要:前言微前端理论篇微前端项目上一篇中,我们完成了项目的搭建,算是完成了整个微前端架构的一半工程了。项目项目是作为页面的菜单显示的,主要用于路由的控制。源码地址源码地址项目源码地址微前端理论篇微前端项目微前端项目

前言

        微前端 —— 理论篇
        微前端 —— portal项目
        上一篇中,我们完成了portal项目的搭建,算是完成了整个微前端架构的一半工程了。现在开始新建我们的业务小应用。

Menu项目

        menu项目是作为页面的菜单显示的,主要用于路由的控制。
        项目的结构如下:

        接下来就开始实现它吧。

新建项目文件夹menu,在根目录执行npm init -y

安装相关依赖,由于react相关的几个依赖已经在portal项目中抽离出来,因此我们这不需要安装了。

         package.js文件内容如下:

    {
      "name": "menu",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "start": "webpack-dev-server --config ./webpack.dev.js --port 8235",
        "build": "webpack --config ./webpack.config.js -p"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
        "antd": "^3.20.7",
        "babel-plugin-import": "^1.12.0",
        "copy-webpack-plugin": "^5.0.4",
        "react-router": "4.3.1",
        "react-router-dom": "4.3.1",
        "single-spa-react": "2.8.1",
        "@reach/router": "1.2.1"
      },
      "devDependencies": {
        "@babel/core": "7.0.0",
        "@babel/plugin-proposal-class-properties": "7.0.0",
        "@babel/plugin-proposal-decorators": "7.1.0",
        "@babel/plugin-proposal-object-rest-spread": "7.0.0",
        "@babel/plugin-syntax-dynamic-import": "^7.0.0",
        "@babel/preset-env": "7.0.0",
        "@babel/preset-react": "7.0.0",
        "autoprefixer": "9.1.5",
        "babel-core": "6.26.3",
        "babel-loader": "8.0.0",
        "clean-webpack-plugin": "0.1.19",
        "css-loader": "1.0.0",
        "postcss-loader": "3.0.0",
        "style-loader": "0.23.0",
        "webpack": "4.17.1",
        "webpack-cli": "3.1.0",
        "webpack-dev-server": "^3.1.14"
      }
    }

        新建src文件夹,在src文件夹下创建components文件夹,在components文件夹中新建文件Menu.js,内容如下:

    import React from "react"
    import {Menu, Icon} from "antd"
    import { Link } from "@reach/router"
    const MenuItem = Menu.Item
    
    export default class Menu_ extends React.Component {
        render () {
            return (
                

menu!

主页 页面1 页面2 页面3 页面4
) } } const menuStyle = { display: "inline-block", position: "fixed", width: "300px", height: "100%" }

        现在我们已经实现了菜单的页面代码。在src目录下新建文件root.component.js,引入导出Menu组件

    import React from "react"
    import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom"
    import Menu from "./components/Menu"
    
    export default class Root extends React.Component {
    
      state = {
        hasError: false
      }
    
      componentDidCatch (error, info) {
        this.setState({hasError: true})
      }
    
      render () {
        return (
          
        )
      }
    }

        在src目录下新建文件set-public-path.js

    // For lazy loading within an application to work you need to set webpack"s public path
    // basically webpack"s internal module system always looks for code-splits (modules) at the root
    export default function setPublicPath() {
      return Promise.all([getUrl()]).then(values => {
        const [url] = values
        const webpackPublicPath = url.slice(0, url.lastIndexOf("/") + 1)
    
        __webpack_public_path__ = webpackPublicPath
        return true
      })
    }
    
    function getUrl () {
      return window.System.resolve("@portal/menu")
    }

        在src目录下新建文件menu.js,用于组件的注册

    import React from "react"
    import ReactDOM from "react-dom"
    import singleSpaReact from "single-spa-react"
    import { property } from "lodash"
    import setPublicPath from "./set-public-path.js"
    
    const reactLifecycles = singleSpaReact({
      React,
      ReactDOM,
      loadRootComponent: () => import(/* webpackChunkName: "people-app" */"./root.component.js").then(property("default")),
      domElementGetter,
    })
    
    export const bootstrap = [
      () => {
        return setPublicPath()
      },
      reactLifecycles.bootstrap,
    ]
    
    export const mount = [
      reactLifecycles.mount,
    ]
    
    export const unmount = [
      reactLifecycles.unmount,
    ]
    
    export const unload = [
      reactLifecycles.unload,
    ]
    
    function domElementGetter() {
      let el = document.getElementById("menu");
      if (!el) {
        el = document.createElement("div");
        el.id = "menu";
        document.body.appendChild(el);
      }
    
      return el;
    }

        最后编写webpack配置文件,在项目根目录下创建文件webpack.config.jswebpack.dev.js


        webpack.config.js

    /* eslint-env node */
    const webpack = require("webpack")
    const path = require("path");
    const CleanWebpackPlugin = require("clean-webpack-plugin");
    const CopyWebpackPlugin = require("copy-webpack-plugin");
    
    module.exports = {
      entry: path.resolve(__dirname, "src/menu.js"),
      output: {
        filename: "menu.js",
        library: "menu",
        libraryTarget: "amd",
        path: path.resolve(__dirname, "build/menu"),
      },
      mode: "production",
      module: {
        rules: [
          {parser: {System: false}},
          {
            test: /.js?$/,
            exclude: [path.resolve(__dirname, "node_modules")],
            loader: "babel-loader",
          },
          {
            test: /.css$/,
            exclude: [path.resolve(__dirname, "node_modules")],
            use: [
              "style-loader",
              {
                loader: "css-loader",
                options: {
                  modules: true,
                  localIdentName: "[path][name]__[local]",
                },
              },
              {
                loader: "postcss-loader",
                options: {
                  plugins() {
                    return [
                      require("autoprefixer")
                    ];
                  },
                },
              },
            ],
          },
          {
            test: /.css$/,
            include: [path.resolve(__dirname, "node_modules")],
            exclude: [/.krem.css$/],
            use: ["style-loader", "css-loader"],
          },
        ],
      },
      resolve: {
        modules: [
          __dirname,
          "node_modules",
        ],
      },
      plugins: [
        new CleanWebpackPlugin(["build/menu"]),
        new CopyWebpackPlugin([
          {from: path.resolve(__dirname, "src/Menu.js")}
        ]),
      ],
      devtool: "source-map",
      externals: [
        /^@portal/*/,
        /^lodash$/,
        /^single-spa$/,
        /^rxjs/?.*$/,
        /^react$/,
        /^react/lib.*/,
        /^react-dom$/,
        /.*react-dom.*/,
      ],
    };

        公共依赖就别多带带打包了
        webpack.dev.js

    /* eslint-env node */
    const config = require("./webpack.config.js");
    const webpack = require("webpack");
    
    config.plugins.push(new webpack.NamedModulesPlugin());
    config.plugins.push(new webpack.HotModuleReplacementPlugin());
    config.devServer = {
      headers: {
        "Access-Control-Allow-Origin": "*",
      },
    }
    
    config.mode = "development"
    
    module.exports = config;

        menu项目的源码大概就这些

3.project1
        project1项目也是通过react框架实现的,主要是实现了不同路由匹配不同页面,最后运行打包的时候,暴露出一个js文件,共portal项目调用。详细的就不阐述了,跟menu项目大同小异,也就只是页面代码不一样。



        menu源码地址
        project1源码地址
        项目源码地址

        微前端 —— 理论篇
        微前端 —— portal项目
        微前端 —— project2项目(VUE)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106340.html

相关文章

  • 前端 —— 理论篇

    摘要:现在开始从头搭建我们的微前端架构。项目源码微前端项目微前端微前端项目 1. 微前端         基于spa类的单页应用,随着企业工程项目的体积越来越大,开发的功能越来越多,页面也越来越多,项目随之也变得越来越臃肿,维护起来十分困难,往往改一个logo,或者改一个小样式,都要将项目全部重新打包一遍,维护困难,部署也困难。         因此前端在借鉴后端的微服务架构模式后,衍生了...

    wangbinke 评论0 收藏0
  • 前端 —— project2项目(VUE)

    摘要:前言微前端理论篇微前端项目微前端前一篇文章讲解了项目在微前端架构中的应用,本篇为最后一篇,项目在此架构中的应用。项目我们就不自己搭建了,直接使用脚手架生成。 前言         微前端 —— 理论篇        微前端 —— portal项目        微前端 —— menu&&project1(React)        前一篇文章讲解了react项目在single-spa微...

    kumfo 评论0 收藏0
  • 前端 —— portal项目

    摘要:前言微前端理论篇上一篇介绍了微前端的理念,本片将开始介绍项目。先实现公共依赖的引入吧。在上一步我们没有引入的依赖包,是因为的依赖包是作为公共依赖导入的。里面全是我的公共依赖文件在下新建文件夹,新建文件,作为我们整个项目的页面文件。 前言 微前端 —— 理论篇 上一篇介绍了微前端的理念,本片将开始介绍portal项目。 portal项目介绍         portal项目包括两个...

    shiguibiao 评论0 收藏0
  • React中的权限组件设计问题小结

      背景 在项目中要求在后台系统控制管理权限。在之前做过的后台管理系统权限控制是用Vue,这样的话就可以用路由钩子里做权限比对和拦截处理。但这次我们说的是在一个后台系统需要加入权限管理控制,技术栈是React。现在我们就看看实现过程吧。  原代码基于 react 16.x、dva 2.4.1 实现,所以本文是参考了ant-design-pro v1内部对权限管理的实现  所谓的权限控制是什么?...

    3403771864 评论0 收藏0
  • 前端qiankun安装使用

    一、前言大型中后台项目一般包括10个以上的子项目,如果维护在一个单页面应用中,项目就会越来越大,而且不利于版本的迭代,微前端就很好的解决了这些问题。这篇文章主要来体验下蚂蚁的微前端:qiankun,虽然比较成熟了,但在体验过程中还是有一些问题,记录总结下,项目代码实践项目以react单页面应用为主应用,然后构建了三个微应用:react、vue3、node静态页面二、前期准备微前端要求多个前端服务,...

    社区管理员 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<