mirror of
https://github.com/alex8088/electron-vite.git
synced 2025-11-10 06:24:33 +08:00
perf(isolateEntries): transform log
This commit is contained in:
parent
cfd9812a91
commit
4edffe3b9a
@ -1,10 +1,19 @@
|
|||||||
import { type InlineConfig, type Plugin, type Logger, build as viteBuild, mergeConfig } from 'vite'
|
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-function-type */
|
||||||
|
import path from 'node:path'
|
||||||
|
import { type InlineConfig, type Plugin, type Logger, type LogLevel, build as viteBuild, mergeConfig } from 'vite'
|
||||||
import type { InputOptions, RollupOutput } from 'rollup'
|
import type { InputOptions, RollupOutput } from 'rollup'
|
||||||
import colors from 'picocolors'
|
import colors from 'picocolors'
|
||||||
import buildReporterPlugin from './buildReporter'
|
import buildReporterPlugin from './buildReporter'
|
||||||
|
|
||||||
const VIRTUAL_ENTRY_ID = '\0virtual:isolate-entries'
|
const VIRTUAL_ENTRY_ID = '\0virtual:isolate-entries'
|
||||||
|
|
||||||
|
const LogLevels: Record<LogLevel, number> = {
|
||||||
|
silent: 0,
|
||||||
|
error: 1,
|
||||||
|
warn: 2,
|
||||||
|
info: 3
|
||||||
|
}
|
||||||
|
|
||||||
export default function isolateEntriesPlugin(userConfig: InlineConfig): Plugin {
|
export default function isolateEntriesPlugin(userConfig: InlineConfig): Plugin {
|
||||||
let logger: Logger
|
let logger: Logger
|
||||||
|
|
||||||
@ -16,9 +25,11 @@ export default function isolateEntriesPlugin(userConfig: InlineConfig): Plugin {
|
|||||||
return {
|
return {
|
||||||
name: 'vite:isolate-entries',
|
name: 'vite:isolate-entries',
|
||||||
apply: 'build',
|
apply: 'build',
|
||||||
|
|
||||||
configResolved(config): void {
|
configResolved(config): void {
|
||||||
logger = config.logger
|
logger = config.logger
|
||||||
},
|
},
|
||||||
|
|
||||||
options(opts): InputOptions | void {
|
options(opts): InputOptions | void {
|
||||||
const { input } = opts
|
const { input } = opts
|
||||||
if (input && typeof input === 'object') {
|
if (input && typeof input === 'object') {
|
||||||
@ -29,24 +40,32 @@ export default function isolateEntriesPlugin(userConfig: InlineConfig): Plugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
buildStart(): void {
|
buildStart(): void {
|
||||||
transformedCount = 0
|
transformedCount = 0
|
||||||
assetCache.clear()
|
assetCache.clear()
|
||||||
},
|
},
|
||||||
|
|
||||||
resolveId(id): string | null {
|
resolveId(id): string | null {
|
||||||
if (id === VIRTUAL_ENTRY_ID) {
|
if (id === VIRTUAL_ENTRY_ID) {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
},
|
},
|
||||||
|
|
||||||
async load(id): Promise<string | void> {
|
async load(id): Promise<string | void> {
|
||||||
if (id === VIRTUAL_ENTRY_ID) {
|
if (id === VIRTUAL_ENTRY_ID) {
|
||||||
const _entries = Array.isArray(entries)
|
const _entries = Array.isArray(entries)
|
||||||
? entries
|
? entries
|
||||||
: Object.entries(entries).map(([key, value]) => ({ [key]: value }))
|
: Object.entries(entries).map(([key, value]) => ({ [key]: value }))
|
||||||
|
|
||||||
const watchFiles = new Set<string>()
|
const watchFiles = new Set<string>()
|
||||||
|
const shouldLog = LogLevels[userConfig.logLevel || 'info'] >= LogLevels.info
|
||||||
|
const shouldWatch = this.meta.watchMode
|
||||||
|
|
||||||
for (const entry of _entries) {
|
for (const entry of _entries) {
|
||||||
const re = await bundleEntryFile(entry, userConfig, this.meta.watchMode)
|
const re = await bundleEntryFile(entry, userConfig, shouldWatch, shouldLog, transformedCount)
|
||||||
|
|
||||||
const outputChunks = re.bundles.output
|
const outputChunks = re.bundles.output
|
||||||
for (const chunk of outputChunks) {
|
for (const chunk of outputChunks) {
|
||||||
if (assetCache.has(chunk.fileName)) {
|
if (assetCache.has(chunk.fileName)) {
|
||||||
@ -59,23 +78,29 @@ export default function isolateEntriesPlugin(userConfig: InlineConfig): Plugin {
|
|||||||
})
|
})
|
||||||
assetCache.add(chunk.fileName)
|
assetCache.add(chunk.fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const id of re.watchFiles) {
|
for (const id of re.watchFiles) {
|
||||||
watchFiles.add(id)
|
watchFiles.add(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
transformedCount += re.transformedCount
|
transformedCount += re.transformedCount
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const id of watchFiles) {
|
for (const id of watchFiles) {
|
||||||
this.addWatchFile(id)
|
this.addWatchFile(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
// This is the virtual entry file
|
// This is the virtual entry file
|
||||||
console.log(1)`
|
console.log(1)`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
renderStart(): void {
|
renderStart(): void {
|
||||||
clearLine()
|
clearLine(-1)
|
||||||
logger.info(`${colors.green(`✓`)} ${transformedCount} modules transformed.`)
|
logger.info(`${colors.green(`✓`)} ${transformedCount} modules transformed.`)
|
||||||
},
|
},
|
||||||
|
|
||||||
generateBundle(_, bundle): void {
|
generateBundle(_, bundle): void {
|
||||||
for (const chunkName in bundle) {
|
for (const chunkName in bundle) {
|
||||||
if (chunkName.includes('virtual_isolate-entries')) {
|
if (chunkName.includes('virtual_isolate-entries')) {
|
||||||
@ -89,25 +114,18 @@ export default function isolateEntriesPlugin(userConfig: InlineConfig): Plugin {
|
|||||||
async function bundleEntryFile(
|
async function bundleEntryFile(
|
||||||
input: string | Record<string, string>,
|
input: string | Record<string, string>,
|
||||||
config: InlineConfig,
|
config: InlineConfig,
|
||||||
watch: boolean
|
watch: boolean,
|
||||||
|
shouldLog: boolean,
|
||||||
|
preTransformedCount: number
|
||||||
): Promise<{ bundles: RollupOutput; watchFiles: string[]; transformedCount: number }> {
|
): Promise<{ bundles: RollupOutput; watchFiles: string[]; transformedCount: number }> {
|
||||||
let transformedCount = 0
|
const transformReporter = transformReporterPlugin(preTransformedCount, shouldLog)
|
||||||
|
const buildReporter = watch ? buildReporterPlugin() : undefined
|
||||||
const reporter = watch ? buildReporterPlugin() : undefined
|
|
||||||
const viteConfig = mergeConfig(config, {
|
const viteConfig = mergeConfig(config, {
|
||||||
build: {
|
build: {
|
||||||
write: false,
|
write: false,
|
||||||
watch: false
|
watch: false
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [transformReporter, buildReporter],
|
||||||
{
|
|
||||||
name: 'vite:transform-counter',
|
|
||||||
transform(): void {
|
|
||||||
transformedCount++
|
|
||||||
}
|
|
||||||
} as Plugin,
|
|
||||||
reporter
|
|
||||||
],
|
|
||||||
logLevel: 'warn',
|
logLevel: 'warn',
|
||||||
configFile: false
|
configFile: false
|
||||||
}) as InlineConfig
|
}) as InlineConfig
|
||||||
@ -119,13 +137,63 @@ async function bundleEntryFile(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
bundles: bundles as RollupOutput,
|
bundles: bundles as RollupOutput,
|
||||||
watchFiles: reporter?.api?.getWatchFiles() || [],
|
watchFiles: buildReporter?.api?.getWatchFiles() || [],
|
||||||
transformedCount
|
transformedCount: transformReporter?.api?.getTransformedCount() || 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearLine(): void {
|
function transformReporterPlugin(
|
||||||
process.stdout.moveCursor(0, -1)
|
preTransformedCount = 0,
|
||||||
|
shouldLog = true
|
||||||
|
): Plugin<{ getTransformedCount: () => number }> {
|
||||||
|
let transformedCount = 0
|
||||||
|
let root
|
||||||
|
const log = throttle(id => {
|
||||||
|
writeLine(`transforming (${preTransformedCount + transformedCount}) ${colors.dim(path.relative(root, id))}`)
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
name: 'vite:transform-reporter',
|
||||||
|
configResolved(config) {
|
||||||
|
root = config.root
|
||||||
|
},
|
||||||
|
transform(_, id) {
|
||||||
|
transformedCount++
|
||||||
|
if (!shouldLog) return
|
||||||
|
if (id.includes('?')) return
|
||||||
|
log(id)
|
||||||
|
},
|
||||||
|
api: {
|
||||||
|
getTransformedCount() {
|
||||||
|
return transformedCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeLine(output: string): void {
|
||||||
|
clearLine()
|
||||||
|
if (output.length < process.stdout.columns) {
|
||||||
|
process.stdout.write(output)
|
||||||
|
} else {
|
||||||
|
process.stdout.write(output.substring(0, process.stdout.columns - 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearLine(move: number = 0): void {
|
||||||
|
if (move < 0) {
|
||||||
|
process.stdout.moveCursor(0, move)
|
||||||
|
}
|
||||||
process.stdout.clearLine(0)
|
process.stdout.clearLine(0)
|
||||||
process.stdout.cursorTo(0)
|
process.stdout.cursorTo(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function throttle(fn: Function) {
|
||||||
|
let timerHandle: NodeJS.Timeout | null = null
|
||||||
|
return (...args: any[]) => {
|
||||||
|
if (timerHandle) return
|
||||||
|
fn(...args)
|
||||||
|
timerHandle = setTimeout(() => {
|
||||||
|
timerHandle = null
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user