91 lines
3.0 KiB
TypeScript
91 lines
3.0 KiB
TypeScript
import type { Plugin, NormalizedOutputOptions, OutputBundle } from 'rollup'
|
|
import path from 'node:path'
|
|
import fs from 'node:fs'
|
|
import { rollup } from 'rollup'
|
|
import chalk from 'chalk'
|
|
import commonjs from '@rollup/plugin-commonjs'
|
|
import { external } from '../../../shared/config'
|
|
|
|
const bundlesToMerge = new Set<string>()
|
|
const commonChunk = new Set<string>()
|
|
let buildFormat
|
|
let isDelete
|
|
|
|
export default function ({ deleteInlinedFiles = true }): Plugin {
|
|
return {
|
|
name: 'opentiny-vue:inline-chunks',
|
|
generateBundle: async ({ format, dir }: NormalizedOutputOptions, bundle: OutputBundle) => {
|
|
buildFormat = format
|
|
isDelete = deleteInlinedFiles
|
|
const jsAssets = Object.keys(bundle).filter((i) => /\.[mc]?js$/.test(i))
|
|
for (const jsName of jsAssets) {
|
|
const jsChunk = bundle[jsName]
|
|
|
|
if (jsChunk.type === 'asset') continue
|
|
if (!jsChunk.code) continue
|
|
|
|
if (format === 'es') {
|
|
const reg = /^import(\s*.+\s*from)?\s+"[./]+(.+-[a-f0-9]{8}.+)".*$/gim
|
|
const matchArr = jsChunk.code.match(reg)
|
|
if (matchArr) {
|
|
const filePath = path.join(dir, jsName)
|
|
bundlesToMerge.add(filePath)
|
|
matchArr.forEach((matchImport) => {
|
|
const sourceName = matchImport.match(/"(.+)"/)[1]
|
|
commonChunk.add(path.join(filePath, '../', sourceName))
|
|
})
|
|
}
|
|
}
|
|
|
|
if (format === 'cjs') {
|
|
const reg = /require\("[./]+(.+-[a-f0-9]{8}.+)".*$/gim
|
|
const matchArr = jsChunk.code.match(reg)
|
|
if (matchArr) {
|
|
const filePath = path.join(dir, jsName)
|
|
bundlesToMerge.add(filePath)
|
|
matchArr.forEach((matchRequire) => {
|
|
const sourceName = matchRequire.match(/"(.+)"/)[1]
|
|
commonChunk.add(path.join(filePath, '../', sourceName))
|
|
})
|
|
}
|
|
}
|
|
}
|
|
},
|
|
closeBundle: async () =>
|
|
new Promise((resolve) => {
|
|
// eslint-disable-next-line no-console
|
|
console.log(`\n${chalk.green('开始内联公共依赖')}`)
|
|
let i = 0
|
|
if (bundlesToMerge.size > 0) {
|
|
bundlesToMerge.forEach(async (filePath) => {
|
|
if (commonChunk.has(filePath)) {
|
|
++i
|
|
} else {
|
|
const bundle = await rollup({
|
|
input: filePath,
|
|
external: (source) => external(source),
|
|
plugins: buildFormat === 'cjs' ? [commonjs()] : []
|
|
})
|
|
await bundle.write({ dir: path.join(filePath, '../'), format: buildFormat })
|
|
await bundle.close()
|
|
++i
|
|
}
|
|
if (i === bundlesToMerge.size) {
|
|
resolve()
|
|
}
|
|
})
|
|
} else {
|
|
resolve()
|
|
}
|
|
}).then(async () => {
|
|
if (isDelete) {
|
|
commonChunk.forEach((filePath) => {
|
|
fs.unlinkSync(filePath)
|
|
// eslint-disable-next-line no-console
|
|
console.log(`\n${chalk.red(filePath)} 已经被内联并删除`)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|