react多项目多模块运行/打包

react多项目多模块运行/打包

react17 为例,实现多项目的分模块打包。多项目之间共享组件和依赖,运行、打包互不干扰。

在这里插入图片描述

一、安装

npm install -g create-react-app
# OR
yarn global add create-react-app

二、创建项目:

create-react-app my-project
  • src目录新增pages文件夹,除index.js以外的文件都移到pages
  • src目录新增components文件夹,创建HelloWorld组件并引入到App.js
src
 - components
 - pages

三、目录改造

分模块打包:一个模块就是一个项目,各个模块独立配置

  • 在根目录新增template文件夹,存放模块模板文件
  • src目录新增models文件夹,存放模块文件

在模块、模板目录,创建两个项目(文件夹):beijingtianjin

template
 - beijing
 - tianjin
src
 - models
   - beijing
   - tianjin
  • src下的 pages 复制到项目文件夹
  • public下的 index.htmlstatic复制到模板文件夹

注意App.js中图片和组件的路径

四:配置改造

cross-env是跨平台环境变量的工具,react-app-rewired是重写配置的工具,新增这俩依赖:

yarn add cross-env react-app-rewired

每个项目都有开发/生产环境,需要新增4个脚本命令:

// package.json

  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "start:beijing": "cross-env MODEL_NAME=beijing react-app-rewired start",
    "build:beijing": "cross-env MODEL_NAME=beijing react-app-rewired build",
    "start:tianjin": "cross-env MODEL_NAME=tianjin react-app-rewired start",
    "build:tianjin": "cross-env MODEL_NAME=tianjin react-app-rewired build",
    "test": "react-app-rewired test"
  },

homepage对应index.html中的变量%PUBLIC_URL%,方便打包后预览

// package.json

  "homepage":"./",

基本配置:

// config-overrides.js

module.exports = function override(config, env) {

  // 输出目录
  config.output = {
    ...config.output,
    // publicPath: '',// package.json -> homepage = './'
    filename: `static/js/bundle.js`,
    chunkFilename: `static/js/[name].chunk.js`,
  };

  return config;
};

到这一步,最好运行一次默认打包配置,表示新增的目录和文件没有影响默认配置

本例引用了公共的静态资源和组件用于测试:
src/assets/logo.svgsrc/components/HelloWorld.js

如果可以正常打包,接下来就是配置多模块,能想到多模块打包,传统配置必定很熟了,不再赘述,请看注释…

完整配置:

const path = require('path');
const paths = require('react-scripts/config/paths');
const HtmlWebpackPlugin = require('html-webpack-plugin');

function resolve(dir) {
  return path.join(__dirname, dir)
}

module.exports = function (config, env) {

  let pathDir = path.join(__dirname, 'dist');
  paths.appBuild = path.join(__dirname, 'dist');

  if (process.env.MODEL_NAME) {
    let mName = process.env.MODEL_NAME;

    // 输出目录
    pathDir = resolve(`dist/${mName}`);
    paths.appBuild = resolve(`dist/${mName}`);

    // 模块入口
    // paths.appSrc = resolve(`src`);
    // paths.appIndexJs = resolve(`src/index`);
    paths.appIndexJs = resolve(`src/models/${mName}/index`);
    config.entry = paths.appIndexJs;

    // 模板入口
    paths.appPublic = resolve(`template/${mName}`);
    paths.appHtml = resolve(`template/${mName}/index.html`);

    config.plugins = [
      ...config.plugins,
      new HtmlWebpackPlugin({
        title: mName,
        inject: 'body',
        // chunks: ["bundle","main"],
        template: paths.appHtml,
        filename: 'index.html',
      })
    ];
  }

  // 关闭 source-map
  config.devtool = false;

  // 输出目录
  config.output = {
    ...config.output,
    path: pathDir,
    // publicPath: '', // package.json -> homepage = './'
    filename: 'static/js/bundle.js',
    chunkFilename: 'static/js/[name].chunk.js',
  };

  // 外部扩展
  config.externals = {
    'react': 'React',
    'react-dom': 'ReactDOM'
  };

  // 设置别名
  config.resolve = {
    ...config.resolve,
    alias: {
      ...config.alias,
      '@': path.resolve(__dirname, 'src'),
    },
  };

  return config;
};

这样做的好处:

  • 不用每次都这样create-react-app my-project
  • 共享组件、共享静态资源
  • 节省磁盘,package.jsonnode_modules也是共享的
  • 方便管理,也不用创建那么多git仓库了

我这的java项目集成的是FreeMarker,复制对应的项目模板index.html后缀改成.ftl

每次前端打包对应的环境配置之后,把dist目录的文件同步到java项目的static目录

这套配置目前管理着超过10个可视化大屏项目,比一个大屏创建一个React方便多了

猜你喜欢

转载自blog.csdn.net/gaofengzks/article/details/120505401