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-env
对qa
命令行修改如下:"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
};