fix(bytecodePlugin): sub-chunks are not compliled in vite 4

This commit is contained in:
alex8088 2023-03-26 23:08:52 +08:00
parent f33c86383e
commit 6c6db628f6

View file

@ -6,7 +6,7 @@ import colors from 'picocolors'
import { type Plugin, type ResolvedConfig, normalizePath, createFilter } from 'vite' import { type Plugin, type ResolvedConfig, normalizePath, createFilter } from 'vite'
import * as babel from '@babel/core' import * as babel from '@babel/core'
import MagicString from 'magic-string' import MagicString from 'magic-string'
import type { SourceMapInput } from 'rollup' import type { SourceMapInput, OutputChunk } from 'rollup'
import { getElectronPath } from '../electron' import { getElectronPath } from '../electron'
import { toRelativePath } from '../utils' import { toRelativePath } from '../utils'
@ -168,9 +168,6 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
.replace(/-/g, '\\u002d') .replace(/-/g, '\\u002d')
} }
const bytecodeChunks: string[] = []
const nonEntryChunks: string[] = []
const transformAllChunks = _chunkAlias.length === 0 const transformAllChunks = _chunkAlias.length === 0
const isBytecodeChunk = (chunkName: string): boolean => { const isBytecodeChunk = (chunkName: string): boolean => {
return transformAllChunks || _chunkAlias.some(alias => alias === chunkName) return transformAllChunks || _chunkAlias.some(alias => alias === chunkName)
@ -188,6 +185,7 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
let config: ResolvedConfig let config: ResolvedConfig
let useInRenderer = false let useInRenderer = false
let bytecodeRequired = false
let bytecodeFiles: { name: string; size: number }[] = [] let bytecodeFiles: { name: string; size: number }[] = []
return { return {
@ -233,10 +231,7 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
return null return null
} }
if (chunk.type === 'chunk' && isBytecodeChunk(chunk.name)) { if (chunk.type === 'chunk' && isBytecodeChunk(chunk.name)) {
bytecodeChunks.push(chunk.fileName) bytecodeRequired = true
if (!chunk.isEntry) {
nonEntryChunks.push(chunk.fileName)
}
if (transformArrowFunctions) { if (transformArrowFunctions) {
return { return {
code: _transform(code) code: _transform(code)
@ -246,7 +241,7 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
return null return null
}, },
generateBundle(): void { generateBundle(): void {
if (!useInRenderer && bytecodeChunks.length) { if (!useInRenderer && bytecodeRequired) {
this.emitFile({ this.emitFile({
type: 'asset', type: 'asset',
source: bytecodeModuleLoaderCode.join('\n') + '\n', source: bytecodeModuleLoaderCode.join('\n') + '\n',
@ -256,21 +251,33 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
} }
}, },
async writeBundle(options, output): Promise<void> { async writeBundle(options, output): Promise<void> {
if (useInRenderer || bytecodeChunks.length === 0) { if (useInRenderer || !bytecodeRequired) {
return return
} }
const bundles = Object.keys(output)
const outDir = options.dir! const outDir = options.dir!
bytecodeFiles = [] bytecodeFiles = []
const pattern = nonEntryChunks.length ? nonEntryChunks.map(chunk => `(${chunk})`).join('|') : null
const bundles = Object.keys(output)
const chunks = Object.values(output).filter(
chunk => chunk.type === 'chunk' && isBytecodeChunk(chunk.name) && chunk.fileName !== bytecodeModuleLoader
) as OutputChunk[]
const bytecodeChunks = chunks.map(chunk => chunk.fileName)
const nonEntryChunks = chunks.filter(chunk => !chunk.isEntry).map(chunk => path.basename(chunk.fileName))
const pattern = nonEntryChunks.map(chunk => `(${chunk})`).join('|')
const bytecodeRE = pattern ? new RegExp(`require\\(\\S*(?=(${pattern})\\S*\\))`, 'g') : null const bytecodeRE = pattern ? new RegExp(`require\\(\\S*(?=(${pattern})\\S*\\))`, 'g') : null
const keepBundle = (chunkFileName: string): void => { const keepBundle = (chunkFileName: string): void => {
const newFileName = path.resolve(path.dirname(chunkFileName), `_${path.basename(chunkFileName)}`) const newFileName = path.resolve(path.dirname(chunkFileName), `_${path.basename(chunkFileName)}`)
fs.renameSync(chunkFileName, newFileName) fs.renameSync(chunkFileName, newFileName)
} }
const getBytecodeLoaderBlock = (chunkFileName: string): string => { const getBytecodeLoaderBlock = (chunkFileName: string): string => {
return `require("${toRelativePath(bytecodeModuleLoader, chunkFileName)}");` return `require("${toRelativePath(bytecodeModuleLoader, chunkFileName)}");`
} }
await Promise.all( await Promise.all(
bundles.map(async name => { bundles.map(async name => {
const chunk = output[name] const chunk = output[name]
@ -291,8 +298,7 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
const chunkFileName = path.resolve(outDir, name) const chunkFileName = path.resolve(outDir, name)
if (bytecodeChunks.includes(name)) { if (bytecodeChunks.includes(name)) {
const bytecodeBuffer = await compileToBytecode(_code) const bytecodeBuffer = await compileToBytecode(_code)
const bytecodeFileName = path.resolve(outDir, name + 'c') fs.writeFileSync(path.resolve(outDir, name + 'c'), bytecodeBuffer)
fs.writeFileSync(bytecodeFileName, bytecodeBuffer)
if (chunk.isEntry) { if (chunk.isEntry) {
if (!removeBundleJS) { if (!removeBundleJS) {
keepBundle(chunkFileName) keepBundle(chunkFileName)