zs
2025-05-06 55bf797dcc730b37bc691ebab2b51ff9db8ed245
HIAWms/web/script/build.js
@@ -1,8 +1,10 @@
const { writeFileSync, rmSync } = require('fs')
const { spawn } = require('node:child_process')
const crossSpawn = require('cross-spawn')
const slash = require('slash')
const { writeFileSync, rmSync, ensureFileSync } = require('fs-extra')
const { globSync } = require('glob')
const path = require('path')
const os = require('os')
const baseBuildFile = './node_modules/.cache/widgets.json'
let isSingleBuild = false
const isWin = process.platform === 'win32'
const argvPath = './script/.argv'
@@ -20,15 +22,88 @@
  writeFileSync(argvPath, widgetName)
}
const run = spawn(process.platform === 'win32' ? 'npm.cmd' : 'npm', [
  'run',
  'build-lib',
])
buildWidgets()
run.stdout.on('data', (data) => console.info(data.toString('utf8')))
function buildWidgets() {
  const isWin = process.platform === 'win32'
  const argv = process.argv || []
run.stderr.on('data', (data) => console.info(data.toString('utf8')))
  const widgetName = argv[argv.length - 1]
run.on('close', (code) => {
  if (code == 0 && isSingleBuild) rmSync(argvPath)
})
  const widgetsPath = globSync(`./src/widgets/*/index.ts`)
  const widgetNames = widgetsPath.map((file) => {
    const parts = isWin
      ? path.resolve(file).split('\\')
      : path.resolve(file).split('/')
    return parts[parts.length - 2]
  }) // 打包一个组件
  if (widgetName && widgetNames.includes(widgetName)) {
    isSingleBuild = true
    writeFileSync(argvPath, widgetName)
    runBuild()
  } else {
    // 打包多组件,按CPU默认并行度打包
    const buildWidgets = divideArray(widgetNames)
    const slashPath = slash(path.resolve(process.cwd(), baseBuildFile))
    ensureFileSync(slashPath)
    writeFileSync(slashPath, JSON.stringify(buildWidgets, null, 2))
    buildSumCount = 0
    buildCount = 0
    for (let index = 0; index < Object.keys(buildWidgets).length; index++) {
      const widgets = buildWidgets[index]
      if (widgets.length) {
        buildSumCount++
        runBuild(index)
      }
    }
    console.log(buildWidgets)
  }
}
/**
 * 获取等分的组件数据
 * @param {*} widgets
 * @param {*} cpus
 * @returns
 */
function divideArray(widgets) {
  // 当打包时,操作电脑可能会卡
  const cpus = os.availableParallelism() > 1 ? os.availableParallelism() - 1 : 1
  let result = {}
  let dataPerKey = Math.floor(widgets.length / cpus)
  let remainingData = widgets.length
  for (let i = 0; i < cpus; i++) {
    let currentDataCount = Math.min(dataPerKey, remainingData)
    result[i] = widgets.splice(0, currentDataCount)
    remainingData -= currentDataCount
  }
  if (widgets.length) {
    widgets.forEach((widgetName, index) => {
      result[index].push(widgetName)
    })
  }
  return result
}
/**
 * 运行编译
 * @param {*} nodeIndex 设置打包组件起点
 */
function runBuild(nodeIndex) {
  const cmdParams = ['run', 'build-lib']
  const run = crossSpawn(
    process.platform === 'win32' ? 'npm.cmd' : 'npm',
    cmdParams,
    {
      stdio: 'inherit',
      shell: true,
      env: {
        // 编译组件索引映射
        ...process.env,
        NODE_INDEX: nodeIndex,
      },
    }
  )
  run.on('close', (code) => {
    if (code == 0 && isSingleBuild) rmSync(argvPath)
  })
}