微前端: Systemjs

关于微应用的一个技术
更新于: 2023-03-24 08:01:43

项目结构

一个简单的 webpack + React + Systemjs 项目

.
├── .gitignore
├── .prettierrc
├── README.md
├── package.json
├── src
│   ├── App.js
│   ├── index.html
│   └── index.js
├── webpack.config.js
└── yarn.lock 

安装

# webpack
yarn add --dev \
    webpack \
    webpack-cli \
    webpack-dev-server \
    html-webpack-plugin \
    @babel/core @babel/cli @babel/preset-env \
    @babel/preset-react babel-loader

# app
yarn add react react-dom

关键配置

  • output.libraryTarget: 'system' 导出 system 模块,保证后面的 systemjs 可以无缝导入
  • inject: false 不要自动注入最终的 bundle.js 到页面,利用 systemjs 手动导入
  • externals: ['react', 'react-dom'] 公用模块从 importmap 里导入,这样可以不用打包到 bundle.js 里去
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    publicPath: '',
    path: __dirname + '/dist',
    filename: 'bundle.js',
    libraryTarget: 'system',
  },
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      filename: 'index.html', // output file
      inject: false,
    }),
  ],
  externals: ['react', 'react-dom'],
};

关键 HTML

  • systemjs-importmap 兼容的 system-importmap
  • 利用 System.import('/bundle.js'); 来注入
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- systemjs -->
    <script type="systemjs-importmap">
      {
        "imports": {
          "react": "https://unpkg.com/react@18.2.0/umd/react.production.min.js",
          "react-dom": "https://unpkg.com/react-dom@18.2.0/umd/react-dom.production.min.js"
        }
      }
    </script>
    <script src="https://unpkg.com/systemjs/dist/system.js"></script>
  </head>
  <body>
    <main id="root"></main>
    <script>
      System.import('/bundle.js');
    </script>
  </body>
</html>

参考