Files
ArtPlayer/scripts/build.js
T
Harvey Zack c911928166 feat: add danmuku plugin documentation and i18n setup
- Created a new documentation file for the danmuku plugin with interactive code execution.
- Added comprehensive i18n setup instructions, including default language settings, language imports, and examples for adding and modifying languages.
- Introduced a test file to verify the integration of the danmuku plugin.
2025-08-17 12:09:50 +08:00

175 lines
4.5 KiB
JavaScript

import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { Parcel } from '@parcel/core'
import cpy from 'cpy'
import prompts from 'prompts'
import { getProjects } from './utils.js'
const projects = getProjects()
const compiledPath = path.resolve('docs/compiled')
function compressString(input) {
return input
.replace(/\s*(<[^>]+>)\s*/g, '$1')
.replace(/(\r\n|\n|\r)/g, ' ')
.replace(/\s+/g, ' ')
.trim()
}
async function build(name, targetName, clean = false) {
const projectPackageJson = path.join(projects[name], 'package.json')
const { version } = JSON.parse(fs.readFileSync(projectPackageJson, 'utf-8'))
process.chdir(projects[name])
const distDir = path.join(projects[name], 'dist')
// 👇 构建前清空 dist,只执行一次
if (clean && fs.existsSync(distDir)) {
fs.rmSync(distDir, { recursive: true, force: true })
console.log(`🗑️ Cleaned ${distDir}`)
}
const targets = {
main: {
context: 'browser',
distDir,
sourceMap: false,
outputFormat: 'global',
isLibrary: true,
engines: {
browsers: 'last 1 Chrome version',
},
},
legacy: {
context: 'browser',
distDir,
sourceMap: false,
outputFormat: 'global',
isLibrary: true,
engines: {
browsers: 'IE 11',
},
},
esm: {
context: 'browser',
distDir,
sourceMap: true,
outputFormat: 'esmodule',
isLibrary: true,
engines: {
browsers: 'last 1 Chrome version',
},
},
}
const names = {
main: `${name}.js`, // ✅ 保留 .js 后缀
legacy: `${name}.legacy.js`, // ✅ 保留 .js 后缀
esm: `${name}.mjs`, // ✅ ESM 用 .mjs
}
const entryFile = path.join(projects[name], 'src/index.js')
const bundler = new Parcel({
entries: entryFile,
defaultConfig: '@parcel/config-default',
mode: 'production',
targets: {
[targetName]: targets[targetName],
},
env: {
NODE_ENV: 'production',
},
})
const banner = `
/*!
* ${name}.js v${version}
* Github: https://github.com/zhw2590582/ArtPlayer
* (c) 2017-${new Date().getFullYear()} Harvey Zack
* Released under the MIT License.
*/
`
const { bundleGraph, buildTime } = await bundler.run()
const bundles = bundleGraph.getBundles()
const filePath = path.join(distDir, 'index.js')
const newFilePath = path.join(distDir, names[targetName])
const code = fs.readFileSync(filePath, 'utf-8')
fs.writeFileSync(filePath, banner + compressString(code))
fs.renameSync(filePath, newFilePath)
const size = fs.statSync(newFilePath).size / 1024
await cpy(newFilePath, compiledPath)
if (targetName === 'esm') {
const jsFile = newFilePath
const oldMapName = 'index.js.map'
const newMapName = `${names.esm}.map`
const oldMapPath = path.join(distDir, oldMapName)
const newMapPath = path.join(distDir, newMapName)
if (fs.existsSync(oldMapPath)) {
fs.renameSync(oldMapPath, newMapPath)
}
let jsContent = fs.readFileSync(jsFile, 'utf8')
jsContent = jsContent.replace(
/\/\/# sourceMappingURL=.*\.js\.map/,
`\n//# sourceMappingURL=${path.basename(newMapName)}`,
)
fs.writeFileSync(jsFile, jsContent)
await cpy(newMapPath, compiledPath)
await cpy(jsFile, compiledPath)
}
console.log(
`✨ Built@${targetName} ${name}@${version}`,
`Bundles@${bundles.length}`,
`Time@${buildTime}ms`,
`Size@${size.toFixed(2)}kb`,
)
}
async function runBuild() {
if (process.argv.pop() === 'all') {
const bundles = Object.keys(projects).map(name => async () => {
await build(name, 'main', true) // 👈 第一次清理
await build(name, 'legacy')
await build(name, 'esm')
})
await runPromisesInSeries(bundles)
console.log('✅ Finished building all packages!')
}
else {
const response = await prompts({
type: 'select',
name: 'value',
message: 'Which project do you want to build?',
choices: Object.keys(projects).map(name => ({
title: name,
value: name,
})),
initial: 0,
})
if (response.value) {
await build(response.value, 'main', true) // 👈 只清一次
await build(response.value, 'legacy')
await build(response.value, 'esm')
}
}
}
function runPromisesInSeries(ps) {
return ps.reduce((p, next) => p.then(next), Promise.resolve())
}
runBuild().catch((error) => {
console.error('❌ Build script encountered an error:', error)
})