Skip to content

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> ...

流程

  1. 读取 companys.conf 配置文件,解析 [section] 区块名作为客户列表
  2. select 交互菜单选择客户
  3. 提取客户配置(appid、baseUrl、company_id 等)
  4. 生成 .env.local
  5. 选择编译方式(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 路由模式矩阵

构建类型publicPathrouter.mode说明
非 App/browser标准 H5 部署
App 前端./hashH5+ 前端模式
App 服务端/browserH5+ 服务端模式

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_CDNAPP_PUBLIC_PATHAPP_CDN_PATHAPP_CDN_KEYAPP_CDN_SCERETAPP_CDN_REGIONAPP_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/h5

Stage 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, merchant

modify-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.jsplugins 数组中被注释掉,当前未启用。

构建产物目录

平台输出目录
微信小程序dist/weapp/
H5dist/h5/

完整构建命令

命令说明
npm run build:weapp构建微信小程序
npm run build:weapp:live构建微信小程序(带直播)
npm run build:h5构建 H5
npm run dev:weapp微信小程序 watch 模式
npm run dev:h5H5 watch 模式
npm run dev:weapp:i18n微信小程序 i18n 调试模式
npm run dev:h5:i18nH5 i18n 调试模式

本项目开发和发布只使用 weapp 与 h5 构建命令。