umi3+react+antd pro 多环境打包配置

umi3+react+antd pro 在打包时只区分了:本地 + 生产,umi3的package.json scripts 部分如下:

"scripts": {
    "analyze": "cross-env ANALYZE=1 umi build",
    "build": "umi build",
    "start": "umi dev",
    "qa": "umi build",
    "start:no-mock": "cross-env MOCK=none umi dev",
    "start:no-ui": "cross-env UMI_UI=none umi dev"
  },

这样在发布测试环境的时候只能执行 num run build 来执行打包命令。

问题:如果“测试环境”的静态资源跟“生产环境”资源地址,以及api请求不同的时候就没办法做处理了。

为了区分“测试”和“生产”上scripts中新增加了"qa": "umi build" 但是仍然没有区分出是生成还是测试来。借助cross-envqa命令行修改如下:"qa": "cross-env mode=development umi build", 在 config/confit.ts 下接收 mode(方法:const mode = process.env.mode;)
config/config.ts内容如下:

// https://umijs.org/config/
import { defineConfig } from 'umi';

import layout from './layout';
import routes from './routes';
import { assetDir, chainWebpack } from './webpack/chainWebpack';

const mode = process.env.mode; // 获取打包命令中的mode
let options = {
  assetDir: ''
};
if(mode === 'development') {
  options = {
    publicPath: '//a-dev.demo.cn/',
    devtool: "eval-source-map",
    define: {
      assetDir,
      "process.env": {
        NODE_ENV: JSON.stringify(mode)
      }
    }
  }
} else if (mode === 'production') {
  options = {
    assetDir,
    publicPath: '//a.demo.cn/'
  }
}

/** 项目工程配置入口 */
export default defineConfig({
  ...options,
  base: '/demo', // 路由前缀
  hash: true,
  outputPath: 'output',
  history: {
    type: 'browser'
  },
  targets: {
    ie: 11,
  },

  dynamicImport: {
    loading: '@/components/Loading/index',
  },

  chainWebpack,

  locale: {},
  // Theme for antd: https://ant.design/docs/react/customize-theme-cn
  theme: {
    'primary-color': layout.primaryColor,
  },
  antd: {},
  dva: {
    hmr: true,
  },

  layout,
  routes,
});

由于对打包目录结构做了调整,调整为:

├── index.html
└── static
    └── demo-web

故又添加了chainWebpack 支持,内容如下:

import packageJson from '../../package.json';
const CopyWebpackPlugin = require('copy-webpack-plugin');
const assetDir = `static/${packageJson.name}`;
const path = require('path');

function chainWebpack(config, {
    env,
    webpack,
    createCSSRule
}) {
    // 修改js,js chunk文件输出目录
    config.output
        .filename(`${assetDir}/js/[name].[hash:8].js`)
        .chunkFilename(`${assetDir}/js/[name].[contenthash:8].chunk.js`);

    // 修改css输出目录
    config.plugin('extract-css').tap(() => [{
        filename: `${assetDir}/css/[name].[hash:8].css`,
        chunkFilename: `${assetDir}/css/[name].[contenthash:8].chunk.css`,
        ignoreOrder: true
    }]);

    // 修改图片输出目录
    config.module
        .rule('images')
        .test(/\.(png|jpe?g|gif|webp|ico)(\?.*)?$/)
        .use('url-loader')
        .loader(require.resolve('url-loader'))
        .tap(options => {
            const obj = {
                ...options,
                name: `${assetDir}/img/[name].[hash:8].[ext]`,
                fallback: {
                    ...options.fallback,
                    options: {
                        name: `${assetDir}/img/[name].[hash:8].[ext]`,
                        esModule: false
                    }
                }
            };
            return obj;
        });

    // 修改svg输出目录
    config.module
        .rule('svg')
        .test(/\.(svg)(\?.*)?/)
        .use('file-loader')
        .tap(options => ({
            ...options,
            name: `${assetDir}/img/[name].[hash:8].[ext]`
        }));

    // 修改fonts输出目录
    config.module
        .rule('fonts')
        .test(/\.(eot|woff|woff2|ttf)(\?.*)?$/)
        .use('file-loader')
        .loader(require.resolve('file-loader'))
        .tap(options => ({
            ...options,
            name: `${assetDir}/fonts/[name].[hash:8].[ext]`,
            fallback: {
                ...options.fallback,
                options: {
                    name: `${assetDir}/fonts/[name].[hash:8].[ext]`,
                    esModule: false
                }
            }
        }));

    // 复制公共资源到打包目录,使用规则:path + /static/rating-ms-web/public/xxx.png
    config.plugin('copy-webpack-plugin')
        .use(CopyWebpackPlugin, [{
            patterns: [{
                from: path.resolve(__dirname, '../../public'),
                to: assetDir + '/public',
            }]
        }]);


    let mode = process.env.mode;
    if(mode === 'development') {
        config.plugin('define-plugin')
            .use(webpack.DefinePlugin, [{
                "process.env": {
                    NODE_ENV: JSON.stringify(mode)
                }
            }]);
    }

}

export {
    chainWebpack,
    assetDir
};
其中修改process.env.NODE_ENV比较费劲的地方在于:

config/config.ts 和 chainWebpack 需要都进行define设置,要不然不生效。

你可能感兴趣的:(umi,react.js,antd)