feat(bytecodePlugin): protect strings #91
This commit is contained in:
parent
bc6448df9b
commit
32d78f2f42
|
@ -2,9 +2,10 @@ import path from 'node:path'
|
||||||
import fs from 'node:fs'
|
import fs from 'node:fs'
|
||||||
import { spawn } from 'node:child_process'
|
import { spawn } from 'node:child_process'
|
||||||
import colors from 'picocolors'
|
import colors from 'picocolors'
|
||||||
import { type Plugin, type ResolvedConfig, normalizePath } 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 { getElectronPath } from '../electron'
|
import { getElectronPath } from '../electron'
|
||||||
|
|
||||||
// Inspired by https://github.com/bytenode/bytenode
|
// Inspired by https://github.com/bytenode/bytenode
|
||||||
|
@ -140,6 +141,7 @@ export interface BytecodeOptions {
|
||||||
chunkAlias?: string | string[]
|
chunkAlias?: string | string[]
|
||||||
transformArrowFunctions?: boolean
|
transformArrowFunctions?: boolean
|
||||||
removeBundleJS?: boolean
|
removeBundleJS?: boolean
|
||||||
|
protectedStrings?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,9 +152,11 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const { chunkAlias = [], transformArrowFunctions = true, removeBundleJS = true } = options
|
const { chunkAlias = [], transformArrowFunctions = true, removeBundleJS = true, protectedStrings = [] } = options
|
||||||
const _chunkAlias = Array.isArray(chunkAlias) ? chunkAlias : [chunkAlias]
|
const _chunkAlias = Array.isArray(chunkAlias) ? chunkAlias : [chunkAlias]
|
||||||
|
|
||||||
|
const filter = createFilter(/\.(m?[jt]s|[jt]sx)$/)
|
||||||
|
|
||||||
const bytecodeChunks: string[] = []
|
const bytecodeChunks: string[] = []
|
||||||
const nonEntryChunks: string[] = []
|
const nonEntryChunks: string[] = []
|
||||||
|
|
||||||
|
@ -185,6 +189,32 @@ export function bytecodePlugin(options: BytecodeOptions = {}): Plugin | null {
|
||||||
config.logger.warn(colors.yellow('bytecodePlugin is not support renderers'))
|
config.logger.warn(colors.yellow('bytecodePlugin is not support renderers'))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
transform(code, id): void | { code: string; map: SourceMapInput } {
|
||||||
|
if (protectedStrings.length === 0 || !filter(id)) return
|
||||||
|
|
||||||
|
let match: RegExpExecArray | null
|
||||||
|
let s: MagicString | undefined
|
||||||
|
|
||||||
|
protectedStrings.forEach(str => {
|
||||||
|
const re = new RegExp(`\\u0027${str}\\u0027|\\u0022${str}\\u0022|\\u0060${str}\\u0060`, 'g')
|
||||||
|
const charCodes = Array.from(str).map(s => s.charCodeAt(0))
|
||||||
|
const replacement = `String.fromCharCode(${charCodes.toString()})`
|
||||||
|
while ((match = re.exec(code))) {
|
||||||
|
s ||= new MagicString(code)
|
||||||
|
const [full] = match
|
||||||
|
s.overwrite(match.index, match.index + full.length, replacement, {
|
||||||
|
contentOnly: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
return {
|
||||||
|
code: s.toString(),
|
||||||
|
map: config.build.sourcemap ? s.generateMap({ hires: true }) : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
renderChunk(code, chunk): { code: string } | null {
|
renderChunk(code, chunk): { code: string } | null {
|
||||||
if (useInRenderer) {
|
if (useInRenderer) {
|
||||||
return null
|
return null
|
||||||
|
|
Loading…
Reference in a new issue