微前端

随着项目工程越来越大,打包慢、加载慢等问题也随之而来,想着有什么方案可以解决呢?偶然之间看到微前端的概念,那什么是微前端呢?

  微前端主要是借鉴后端微服务的概念。简单地说,就是将一个巨无霸(Monolith)的前端工程拆分成一个一个的小工程。别小看这些小工程,它们也是“麻雀虽小,五脏俱全”,完全具备独立的开发、运行能力。整个系统就将由这些小工程协同合作,实现所有页面的展示与交互。

 

 

 

 上面是一些网上摘抄的概念,那怎么落地呢?

找了半天,终于找到了,它就是阿里的qiankun框架基于single-spa构建,下面是具体的构建流程:

  1、新建一个项目;

  2、cd  /projectname -> npm init 工程

·   3、cnpm install qiankun -S 或 yarn add qiankun

   4、项目结构

  

 

 5、index.js

import { registerMicroApps, setDefaultMountApp, start, runAfterFirstMounted } from 'qiankun';

import render from './VueRender';

render({ loading: true });

const loader = loading => render({ loading });

registerMicroApps(
  [
    {
      name: 'bigScreen',
      entry: '//localhost:7101',
      container: '#subapp-viewport',
      loader,
      activeRule: '/bigScreen',
    },
    {
      name: 'terryMusic',
      entry: '//localhost:8080',
      container: '#subapp-viewport',
      loader,
      activeRule: '/terryMusic',
    },
  ],
  {
    beforeLoad: [
      app => {
        console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
      },
    ],
    beforeMount: [
      app => {
        console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
      },
    ],
    afterUnmount: [
      app => {
        console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
      },
    ],
  },
);


/**
 * Step3 设置默认进入的子应用
 */
setDefaultMountApp('/bigScreen');

/**
 * Step4 启动应用
 */
start();

runAfterFirstMounted(() => {
  console.log('[MainApp] first app mounted');
});

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Terry - MicroFront</title>
</head>

<body>
  <div class="mainapp">
    <!-- 标题栏 -->
    <header class="mainapp-header">
      <h1>Terry微前端应用落地</h1>
    </header>
    <div class="mainapp-main">
      <!-- 侧边栏 -->
      <ul class="mainapp-sidemenu">
        <li onclick="push('/bigScreen')">big-screen</li>
        <li onclick="push('/terryMusic')">terry-music</li>
      </ul>
      <!-- 子应用  -->
      <main id="subapp-container"></main>
    </div>
  </div>

  <script>
    function push(subapp) { history.pushState(null, subapp, subapp) }
  </script>
</body>

</html>

package.json

{
  "name": "terry-micro-front",
  "version": "1.0.0",
  "description": "微前端",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server"
  },
  "author": "terry",
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.7.2",
    "@babel/plugin-transform-react-jsx": "^7.7.0",
    "@babel/preset-env": "^7.7.1",
    "babel-loader": "^8.0.6",
    "cross-env": "^7.0.2",
    "css-loader": "^3.2.0",
    "html-webpack-plugin": "^3.2.0",
    "less-loader": "^6.2.0",
    "qiankun": "^2.3.1",
    "style-loader": "^1.0.0",
    "vue": "^2.6.12",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.9.0"
  }
}

VueRender:用于加载vue项目

import Vue from 'vue/dist/vue.esm';

function vueRender({ loading }) {
  return new Vue({
    template: `
      <div id="subapp-container">
        <h4 v-if="loading" class="subapp-loading">Loading...</h4>
        <div id="subapp-viewport"></div>
      </div>
    `,
    el: '#subapp-container',
    data() {
      return {
        loading,
      };
    },
  });
}

let app = null;

export default function render({ loading }) {
  if (!app) {
    app = vueRender({ loading });
  } else {
    app.loading = loading;
  }
}

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './index.js',
  devtool: 'source-map',
  devServer: {
    port: '7099',
    clientLogLevel: 'warning',
    disableHostCheck: true,
    compress: true,
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
    historyApiFallback: true,
    overlay: { warnings: false, errors: true },
  },
  output: {
    publicPath: '/',
  },
  mode: 'development',
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
            plugins: ['@babel/plugin-transform-react-jsx'],
          },
        },
      },
      {
        test: /\.(le|c)ss$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: './index.html',
      minify: {
        removeComments: true,
        collapseWhitespace: true,
      },
    }),
  ],
};

子应用配置:Vue项目为例:

 

 成品:

 

 

 

 以上就是整个项目搭建过程以及代码,有兴趣的可以一起学习哦! 贴上github地址:https://github.com/ytg123/Terry-Micro-Front/tree/master

posted @ 2020-11-16 11:24  广广-t  阅读(276)  评论(0)    收藏  举报