12 - 构建与部署
构建配置
config/index.js 概述
config/index.js 是 Taro 构建的主配置入口,导出一个函数,根据 NODE_ENV 合并 dev 或 prod 配置:
js
const config = {
// ... 大量配置
}
module.exports = function (merge) {
if (!IS_PROD) {
return merge({}, config, require('./dev'))
}
return merge({}, config, require('./prod'))
}关键构建变量
js
const DIST_PATH = `dist/${process.env.TARO_ENV}` // 输出目录按平台区分
const IS_PROD = process.env.NODE_ENV === 'production'
const BUILD_TARGET = process.env.TARGET // 'app' 时为 APP 构建
const BUILD_APP_SERVER = process.env.SERVER // 'server' 时为 APP 服务端模式defineConstants — 环境变量注入
工作原理
defineConstants 通过 getDefineConstants() 函数将环境变量注入到客户端代码中,每个变量被映射为 process.env.KEY → 'value':
js
// config/utils.js
function getDefineConstants(consts) {
return Object.keys(consts).reduce((val, k) => {
val[`process.env.${k}`] = `'${consts[k]}'`
return val
}, {})
}自动收集 APP_ 变量
getEnvs() 函数自动收集所有以 APP_ 开头的环境变量:
js
function getEnvs() {
return Object.keys(process.env).reduce((ret, key) => {
if (key.indexOf('APP_') >= 0) {
ret[key] = process.env[key]
}
return ret
}, {})
}显式注入的常量
js
const CONST_ENVS = {
APP_NAME: pkg.app_name, // "ecshopx"
APP_AUTH_PAGE: process.env.TARO_ENV == 'h5'
? '/subpage/pages/auth/login'
: '/subpages/member/index',
APP_BUILD_TARGET: BUILD_TARGET,
APP_LIVE: process.env.APP_LIVE,
...APP_ENVS, // 所有 APP_ 开头的环境变量
APP_DEFAULT_MEMBER_GRADE_ID: process.env.APP_DEFAULT_MEMBER_GRADE_ID || ''
}getCacheIdentifier — 缓存标识
js
function getCacheIdentifier(consts = {}) {
const env = process.env.NODE_ENV || 'development'
const envHash = digest(JSON.stringify(consts))
return `cache-loader:${pkg.version} ${env} ${envHash}`
}用于 babel-loader / cache-loader 的缓存标识,环境变量变化时自动失效。
环境管理
dotenv-flow 加载
项目使用 .env + .env.local 双层环境变量:
| 文件 | 用途 | 是否提交 Git |
|---|---|---|
.env | 默认环境变量模板 | 是 |
.env.local | 本地覆盖 | 否 |
.env 文件
bash
APP_BASE_URL= # 后端 API 地址
APP_WEBSOCKET= # WebSocket 地址
APP_COMPANY_ID= # 企业/租户 ID
APP_PLATFORM= # 产品版本
APP_ID= # 微信小程序 AppID
APP_MAP_KEY= # 地图 Key
# ...
APP_DEFAULT_LANGUAGE=zhcn多客户发布 — scripts/run.sh
交互式构建脚本,支持多客户配置:
bash
# 交互式选择客户
bash scripts/run.sh
# 直接指定参数
bash scripts/run.sh <appid> <baseUrl> <appName> <websocket> <company_id> ...流程:
- 读取
companys.conf配置文件,解析[section]区块名作为客户列表 select交互菜单选择客户- 提取客户配置(appid、baseUrl、company_id 等)
- 生成
.env.local - 选择编译方式(weapp / h5)并执行
H5 vs Mini 构建差异
Mini(小程序)配置
js
mini: {
webpackChain(chain) {},
compile: {
include: [REACT_I18NEXT_PATH, I18NEXT_PATH] // 显式包含 i18next 包
},
miniCssExtractPluginOption: { ignoreOrder: true },
optimizeMainPackage: { enable: true }, // 主包优化
imageUrlLoaderOption: { limit: 0 }, // 图片不转 base64
postcss: {
autoprefixer: { enable: true },
pxtransform: { enable: true, config: {} }, // px → rpx
url: { enable: true, config: { limit: 10240 } }, // 10KB 以下转 base64
cssModules: { enable: false }
}
}H5 配置
js
h5: {
publicPath: IS_APP ? (IS_APP_SERVER ? '/' : './') : '/',
router: {
mode: IS_APP ? (IS_APP_SERVER ? 'browser' : 'hash') : 'browser'
},
webpackChain(chain) {},
devServer: { /* HTTPS 配置已注释 */ },
postcss: {
autoprefixer: { enable: true },
cssModules: { enable: false }
},
esnextModules: ['taro-ui'] // taro-ui 使用 ES 模块
}H5 路由模式矩阵
| 构建类型 | publicPath | router.mode | 说明 |
|---|---|---|---|
| 非 App | / | browser | 标准 H5 部署 |
| App 前端 | ./ | hash | H5+ 前端模式 |
| App 服务端 | / | browser | H5+ 服务端模式 |
Sass 配置
js
sass: {
resource: process.env.TARO_ENV === 'weapp'
? ['src/style/imports.scss', 'src/style/weapp-mixins.scss']
: ['src/style/imports.scss', 'src/style/h5-mixins.scss'],
projectDirectory: path.resolve(__dirname, '..')
}- 微信小程序使用
weapp-mixins.scss - 其他平台使用
h5-mixins.scss - 共享
imports.scss
Alias 配置
js
alias: {
'taro-ui$': 'taro-ui/lib/index', // 精确匹配
'@': path.join(__dirname, '../src') // @ → src/
}Copy Patterns
基础模式(所有平台)
js
{ from: 'src/assets', to: `${DIST_PATH}/assets` }H5 额外
js
{ from: 'src/files', to: `${DIST_PATH}` }微信 i18n 资源转换
js
// resources.js: .json 引用替换为 .js
{
from: 'src/subpages/i18n/resources.js',
to: `subpages/i18n/resources.js`,
transform: i18nResourceTransform
}
// 每个语言 JSON → CommonJS module
{
from: `src/subpages/i18n/locales/${lang}.json`,
to: `subpages/i18n/locales/${lang}.js`,
transform: i18nLocaleTransform // → module.exports = { ... }
}编译器配置
js
compiler: {
type: 'webpack5',
prebundle: { enable: false, force: true }
}
framework: 'react'
designWidth: 750
sourceRoot: 'src'- 使用 webpack5 编译器
- prebundle(预编译)已关闭
dev vs prod 配置
config/dev.js
js
module.exports = {
env: { NODE_ENV: '"development"' },
defineConstants: {},
weapp: {},
h5: {}
}开发环境配置极简,仅设置 NODE_ENV。
config/prod.js
生产环境配置全部被注释,包含:
- CDN 上传到 AWS S3 的配置(
APP_CDN == 'aws'时) - 非 CDN 模式的文件 hash 命名
- webpackChain 中设置 publicPath
注释中涉及的变量: APP_CDN、APP_PUBLIC_PATH、APP_CDN_PATH、APP_CDN_KEY、APP_CDN_SCERET、APP_CDN_REGION、APP_CDN_BUCKET
Docker 构建
Dockerfile — 多阶段构建
Stage 1 — Builder:
dockerfile
FROM reg.ishopex.cn/base-images/node-python3:16.16.0-alpine3.16
ARG CMD
ARG APP_BASE_URL
# ... 16 个 ARG
ENV CMD=$CMD
ENV APP_BASE_URL=$APP_BASE_URL
# ...
WORKDIR /app
COPY package*.json .env ./
RUN npm ci
COPY . .
RUN ${CMD}
RUN ls -l /app/dist/h5Stage 2 — Runtime:
dockerfile
FROM steebchen/nginx-spa:stable
COPY --from=builder /app/dist/h5 .
EXPOSE 80
CMD ["nginx"]Docker 构建示例
bash
docker build \
--build-arg CMD="npm run build:h5" \
--build-arg APP_BASE_URL="https://api.example.com" \
--build-arg APP_COMPANY_ID="38" \
--build-arg APP_PLATFORM="standard" \
--build-arg APP_ID="wx1234567890" \
-t ecshopx-vshop:h5 .分包优化
optimizeMainPackage
js
mini: {
optimizeMainPackage: { enable: true }
}Taro 内置的主包体积优化功能,自动分析依赖关系,将仅被分包使用的模块移到分包。
图片不转 base64
js
mini: {
imageUrlLoaderOption: { limit: 0 } // 图片不转 base64,减少主包体积
}分包 API 隔离
分包专用 API 模块不从主包导出,避免主包膨胀:
js
// src/api/index.js — 分包专用模块注释说明
// 分包内请直接 import from '@/api/community'
// 分包用: community, dianwu, game, boost, mdugc, delivery, merchantmodify-taro.js 插件
config/modify-taro.js 是 Taro 插件,修改构建产物中的 taro.js,用于 BA 首页 workaround:
js
export default (ctx) => {
ctx.modifyBuildAssets((build) => {
const taroJs = build.assets['taro.js']
// 追加 _wrapNativeSuper(Array)
// 修复全局 this 引用
})
}注意:此插件在
config/index.js的plugins数组中被注释掉,当前未启用。
构建产物目录
| 平台 | 输出目录 |
|---|---|
| 微信小程序 | dist/weapp/ |
| H5 | dist/h5/ |
完整构建命令
| 命令 | 说明 |
|---|---|
npm run build:weapp | 构建微信小程序 |
npm run build:weapp:live | 构建微信小程序(带直播) |
npm run build:h5 | 构建 H5 |
npm run dev:weapp | 微信小程序 watch 模式 |
npm run dev:h5 | H5 watch 模式 |
npm run dev:weapp:i18n | 微信小程序 i18n 调试模式 |
npm run dev:h5:i18n | H5 i18n 调试模式 |
本项目开发和发布只使用 weapp 与 h5 构建命令。
