utils.ts 6.6 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1
import fs from 'fs'
fxy060608's avatar
fxy060608 已提交
2
import os from 'os'
fxy060608's avatar
fxy060608 已提交
3
import path from 'path'
fxy060608's avatar
fxy060608 已提交
4
import colors from 'picocolors'
fxy060608's avatar
fxy060608 已提交
5
import { performance } from 'perf_hooks'
fxy060608's avatar
fxy060608 已提交
6
import { BuildOptions, InlineConfig, Logger } from 'vite'
fxy060608's avatar
fxy060608 已提交
7

fxy060608's avatar
fxy060608 已提交
8 9 10 11 12 13
import {
  M,
  isInHBuilderX,
  initModulePaths,
  parseScripts,
} from '@dcloudio/uni-cli-shared'
fxy060608's avatar
fxy060608 已提交
14

fxy060608's avatar
fxy060608 已提交
15
import { CliOptions } from '.'
fxy060608's avatar
fxy060608 已提交
16
import { initNVueEnv } from './nvue'
fxy060608's avatar
fxy060608 已提交
17 18 19 20 21 22 23

export const PLATFORMS = [
  'app',
  'h5',
  'mp-alipay',
  'mp-baidu',
  'mp-qq',
fxy060608's avatar
fxy060608 已提交
24
  'mp-lark',
fxy060608's avatar
fxy060608 已提交
25 26
  'mp-toutiao',
  'mp-weixin',
fxy060608's avatar
fxy060608 已提交
27
  'quickapp-webview',
fxy060608's avatar
fxy060608 已提交
28 29 30 31
  'quickapp-webview-huawei',
  'quickapp-webview-union',
]

fxy060608's avatar
fxy060608 已提交
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
function resolveConfigFile() {
  const viteConfigJs = path.resolve(process.env.UNI_INPUT_DIR, 'vite.config.js')
  const viteConfigTs = path.resolve(process.env.UNI_INPUT_DIR, 'vite.config.ts')

  if (fs.existsSync(viteConfigTs)) {
    return viteConfigTs
  }
  if (fs.existsSync(viteConfigJs)) {
    return viteConfigJs
  }
  return path.resolve(process.env.UNI_CLI_CONTEXT, 'vite.config.js')
}

export function addConfigFile(inlineConfig: InlineConfig) {
  if (isInHBuilderX()) {
    inlineConfig.configFile = resolveConfigFile()
  }
  return inlineConfig
}

fxy060608's avatar
fxy060608 已提交
52 53 54 55 56 57 58 59 60
let initliazed = false
export function initEnv(
  type: 'unknown' | 'dev' | 'build',
  options: CliOptions
) {
  if (initliazed) {
    return
  }
  initliazed = true
fxy060608's avatar
fxy060608 已提交
61 62 63 64
  if (options.platform === 'mp-360') {
    console.error(M['mp.360.unsupported'])
    process.exit(0)
  }
fxy060608's avatar
fxy060608 已提交
65 66 67
  if (options.plugin) {
    process.env.UNI_MP_PLUGIN = 'true'
  }
fxy060608's avatar
fxy060608 已提交
68
  // TODO 需要识别 mode
fxy060608's avatar
fxy060608 已提交
69 70 71 72 73 74 75 76 77
  if (type === 'dev') {
    process.env.NODE_ENV = 'development'
  } else if (type === 'build') {
    if ((options as BuildOptions).watch) {
      process.env.NODE_ENV = 'development'
    } else {
      process.env.NODE_ENV = 'production'
    }
  }
fxy060608's avatar
fxy060608 已提交
78 79 80
  if (!options.mode) {
    options.mode = process.env.NODE_ENV
  }
81 82 83
  // vite 会修改 NODE_ENV,存储在 UNI_NODE_ENV 中,稍后校正 NODE_ENV
  process.env.UNI_NODE_ENV = process.env.VITE_USER_NODE_ENV =
    process.env.NODE_ENV
fxy060608's avatar
fxy060608 已提交
84

fxy060608's avatar
fxy060608 已提交
85 86 87
  process.env.UNI_CLI_CONTEXT = isInHBuilderX()
    ? path.resolve(process.env.UNI_HBUILDERX_PLUGINS!, 'uniapp-cli-vite')
    : process.cwd()
fxy060608's avatar
fxy060608 已提交
88

fxy060608's avatar
fxy060608 已提交
89 90 91 92 93
  // TODO 待优化
  if (options.platform === 'app-android' || options.platform === 'app-ios') {
    process.env.UNI_APP_PLATFORM = options.platform
    options.platform = 'app'
  }
fxy060608's avatar
fxy060608 已提交
94 95 96
  if (options.platform === 'app-plus') {
    options.platform = 'app'
  }
fxy060608's avatar
fxy060608 已提交
97 98 99 100
  if (options.platform === 'app' && !process.env.UNI_APP_PLATFORM) {
    // 目前仅支持 app-android,先强制使用 app-android
    process.env.UNI_APP_PLATFORM = 'app-android'
  }
fxy060608's avatar
fxy060608 已提交
101 102 103 104 105 106 107
  if (
    options.platform === 'quickapp-webview-huawei' ||
    options.platform === 'quickapp-webview-union'
  ) {
    process.env.UNI_SUB_PLATFORM = options.platform
    options.platform = 'quickapp-webview'
  }
fxy060608's avatar
fxy060608 已提交
108 109
  process.env.VITE_ROOT_DIR =
    process.env.VITE_ROOT_DIR || process.env.UNI_INPUT_DIR || process.cwd()
fxy060608's avatar
fxy060608 已提交
110

fxy060608's avatar
fxy060608 已提交
111 112 113
  process.env.UNI_INPUT_DIR =
    process.env.UNI_INPUT_DIR || path.resolve(process.cwd(), 'src')

fxy060608's avatar
fxy060608 已提交
114 115 116 117
  initCustomScripts(options)

  process.env.UNI_PLATFORM = options.platform as UniApp.PLATFORM

fxy060608's avatar
fxy060608 已提交
118 119
  const hasOutputDir = !!process.env.UNI_OUTPUT_DIR
  if (hasOutputDir) {
fxy060608's avatar
fxy060608 已提交
120 121 122
    ;(options as BuildOptions).outDir = process.env.UNI_OUTPUT_DIR
  } else {
    if (!(options as BuildOptions).outDir) {
fxy060608's avatar
fxy060608 已提交
123 124
      ;(options as BuildOptions).outDir = path.resolve(
        process.cwd(),
fxy060608's avatar
fxy060608 已提交
125 126
        'dist',
        process.env.NODE_ENV === 'production' ? 'build' : 'dev',
fxy060608's avatar
fxy060608 已提交
127
        process.env.UNI_SUB_PLATFORM || process.env.UNI_PLATFORM
fxy060608's avatar
fxy060608 已提交
128 129 130 131
      )
    }
    process.env.UNI_OUTPUT_DIR = (options as BuildOptions).outDir!
  }
fxy060608's avatar
fxy060608 已提交
132 133 134 135
  // 兼容 HBuilderX 旧参数
  if (process.env.UNI_SUBPACKGE) {
    options.subpackage = process.env.UNI_SUBPACKGE
  }
fxy060608's avatar
fxy060608 已提交
136 137
  if (options.subpackage) {
    process.env.UNI_SUBPACKAGE = options.subpackage
fxy060608's avatar
fxy060608 已提交
138 139 140 141 142
    if (!hasOutputDir) {
      // 未指定,则自动补充
      process.env.UNI_OUTPUT_DIR = (options as BuildOptions).outDir =
        path.resolve(process.env.UNI_OUTPUT_DIR, options.subpackage)
    }
fxy060608's avatar
fxy060608 已提交
143 144
  }

fxy060608's avatar
fxy060608 已提交
145 146
  initAutomator(options)

fxy060608's avatar
fxy060608 已提交
147
  if (process.env.UNI_PLATFORM === 'app') {
fxy060608's avatar
fxy060608 已提交
148 149 150 151 152 153 154
    const pkg = require('../../package.json')
    console.log(
      M['app.compiler.version'].replace(
        '{version}',
        pkg['uni-app']['compilerVersion'] + '(vue3)'
      )
    )
fxy060608's avatar
fxy060608 已提交
155 156
    initNVueEnv()
  }
fxy060608's avatar
fxy060608 已提交
157 158 159 160 161 162 163 164 165

  if (process.env.NODE_ENV === 'development') {
    console.log(
      M['dev.performance'] +
        (process.env.UNI_PLATFORM.startsWith('mp-')
          ? M['dev.performance.mp']
          : '')
    )
  }
fxy060608's avatar
fxy060608 已提交
166

D
DCloud_LXH 已提交
167 168 169 170 171 172 173
  if (
    (options as BuildOptions).sourcemap &&
    process.env.NODE_ENV === 'production'
  ) {
    process.env.SOURCEMAP = 'true'
  }

fxy060608's avatar
fxy060608 已提交
174 175
  initModulePaths()

fxy060608's avatar
fxy060608 已提交
176
  console.log(M['compiling'])
fxy060608's avatar
fxy060608 已提交
177
}
fxy060608's avatar
fxy060608 已提交
178

fxy060608's avatar
fxy060608 已提交
179
function initAutomator({ autoHost, autoPort }: CliOptions) {
fxy060608's avatar
fxy060608 已提交
180 181
  // 发行分包,插件也不需要自动化测试
  if (!autoPort || process.env.UNI_SUBPACKAGE || process.env.UNI_MP_PLUGIN) {
fxy060608's avatar
fxy060608 已提交
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
    return
  }
  process.env.UNI_AUTOMATOR_WS_ENDPOINT =
    'ws://' + (autoHost || resolveHostname()) + ':' + autoPort
}

function resolveHostname() {
  const interfaces = os.networkInterfaces()
  const keys = Object.keys(interfaces)
  for (const key of keys) {
    const interfaceInfos = interfaces[key]
    if (!interfaceInfos) {
      continue
    }
    for (const info of interfaceInfos) {
197 198 199 200 201
      if (
        (info.family === 'IPv4' ||
          /* Node >= v18 */ (info as any).family === 4) &&
        !info.address.includes('127.0.0.1')
      ) {
fxy060608's avatar
fxy060608 已提交
202 203 204 205 206 207 208
        return info.address
      }
    }
  }
  return 'localhost'
}

fxy060608's avatar
fxy060608 已提交
209 210 211 212 213 214 215 216
export function cleanOptions(options: CliOptions) {
  const ret = { ...options }
  delete ret['--']

  delete ret.platform
  delete ret.p
  delete ret.ssr

217
  delete ret.base
fxy060608's avatar
fxy060608 已提交
218 219 220 221 222 223 224
  delete ret.debug
  delete ret.d
  delete ret.filter
  delete ret.f
  delete ret.logLevel
  delete ret.l
  delete ret.clearScreen
225 226
  delete ret.m
  delete ret.mode
fxy060608's avatar
fxy060608 已提交
227 228 229 230

  delete ret.autoHost
  delete ret.autoPort

fxy060608's avatar
fxy060608 已提交
231 232
  return ret
}
fxy060608's avatar
fxy060608 已提交
233

fxy060608's avatar
fxy060608 已提交
234 235 236 237
export function printStartupDuration(
  logger: Logger,
  whitespace: boolean = true
) {
fxy060608's avatar
fxy060608 已提交
238 239 240 241 242
  // @ts-ignore
  if (global.__vite_start_time) {
    // @ts-ignore
    const startupDuration = performance.now() - global.__vite_start_time
    logger.info(
fxy060608's avatar
fxy060608 已提交
243
      `${whitespace ? `\n  ` : ''}${colors.cyan(
fxy060608's avatar
fxy060608 已提交
244 245
        `ready in ${Math.ceil(startupDuration)}ms.`
      )}\n`
fxy060608's avatar
fxy060608 已提交
246 247 248
    )
  }
}
fxy060608's avatar
fxy060608 已提交
249 250 251 252 253 254 255 256 257 258 259 260 261 262

function initCustomScripts(options: CliOptions) {
  const custom = parseScripts(
    process.env.UNI_SCRIPT || options.platform!, // process.env.UNI_SCRIPT 是 HBuilderX 传递的
    path.join(process.env.VITE_ROOT_DIR!, 'package.json')
  )
  if (!custom) {
    return
  }
  options.platform = custom.platform
  process.env.UNI_CUSTOM_SCRIPT = custom.name
  process.env.UNI_CUSTOM_DEFINE = JSON.stringify(custom.define)
  process.env.UNI_CUSTOM_CONTEXT = JSON.stringify(custom.context)
}