| | |
| | | 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' |
| | |
| | | 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) |
| | | }) |
| | | } |