chore: replace side-effect requires with imports mapping to requires
So the code editor can report errors for bad imports. import statements are mapped to require statements via a bundler plugin.
This commit is contained in:
parent
f8567c6e68
commit
622df65cbf
8 changed files with 106 additions and 14 deletions
|
|
@ -30,7 +30,8 @@ const unsubRN = waitForModules(
|
|||
ReactNativeModuleId = id
|
||||
ReactNative = exports
|
||||
|
||||
require('./native/patches')
|
||||
// @as-require
|
||||
import('./native/patches')
|
||||
},
|
||||
{
|
||||
cached: true,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { parse } from 'path'
|
|||
import { rolldown } from 'rolldown'
|
||||
import { importGlobPlugin } from 'rolldown/experimental'
|
||||
import pkg from '../package.json'
|
||||
import asRequire from './plugins/as-require'
|
||||
import hermesSwcPlugin from './plugins/hermes-swc'
|
||||
import hermesCPlugin from './plugins/hermesc'
|
||||
import shimAliases from './plugins/shim-aliases'
|
||||
|
|
@ -86,6 +87,7 @@ export default async function build(dev = Dev, log = true) {
|
|||
__BUILD_FLAG_LOG_PROMISE_REJECTIONS__: String(dev),
|
||||
},
|
||||
plugins: [
|
||||
asRequire(),
|
||||
shimAliases(ShimsDir),
|
||||
importGlobPlugin(),
|
||||
hermesSwcPlugin(),
|
||||
|
|
|
|||
76
scripts/plugins/as-require.ts
Normal file
76
scripts/plugins/as-require.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import type { RolldownPlugin } from 'rolldown'
|
||||
|
||||
/**
|
||||
* Transforms `// @as-require` comments above supported import statements into `require` calls.
|
||||
*
|
||||
* Supported statements:
|
||||
* - Static side-effect imports: `import 'module'`
|
||||
* - Dynamic side-effect imports: `import('module')` and `await import('module')`
|
||||
* - Dynamic imports with .then(): `import('module').then(mod => ...)`
|
||||
*/
|
||||
export default function asRequire() {
|
||||
return {
|
||||
name: 'as-require',
|
||||
transform(code, id) {
|
||||
if (!code.includes('// @as-require')) return null
|
||||
|
||||
const asRequireRegex =
|
||||
/(?:\s*\/\/\s*@as-require\s*[\r\n]+)([^\r\n]*)/g
|
||||
|
||||
let hasChanged = false
|
||||
const newCode = code.replace(asRequireRegex, (match, statement) => {
|
||||
const trimmedStatement = statement.trim()
|
||||
|
||||
// import('./mod').then(mod => mod.do()) -> ((mod => mod.do()))(require('./mod'))
|
||||
const importThenRegex =
|
||||
/^import\((['"])(.+?)\1\)\s*\.then\(([\s\S]+)\);?$/
|
||||
const thenMatch = trimmedStatement.match(importThenRegex)
|
||||
if (thenMatch) {
|
||||
hasChanged = true
|
||||
const modulePath = `${thenMatch[1]}${thenMatch[2]}${thenMatch[1]}`
|
||||
const callback = thenMatch[3].trim()
|
||||
return `\n((${callback}))(require(${modulePath}));`
|
||||
}
|
||||
|
||||
// import './mod' -> require('./mod')
|
||||
const staticSideEffectRegex = /^import\s+(['"])(.+?)\1;?$/
|
||||
const staticMatch = trimmedStatement.match(
|
||||
staticSideEffectRegex,
|
||||
)
|
||||
if (staticMatch) {
|
||||
hasChanged = true
|
||||
const modulePath = `${staticMatch[1]}${staticMatch[2]}${staticMatch[1]}`
|
||||
return `\nrequire(${modulePath});`
|
||||
}
|
||||
|
||||
// import('./mod') -> require('./mod')
|
||||
// await import('./mod') -> require('./mod')
|
||||
const dynamicSideEffectRegex =
|
||||
/^(?:await\s+)?import\((['"])(.+?)\1\);?$/
|
||||
const dynamicMatch = trimmedStatement.match(
|
||||
dynamicSideEffectRegex,
|
||||
)
|
||||
if (dynamicMatch) {
|
||||
hasChanged = true
|
||||
const modulePath = `${dynamicMatch[1]}${dynamicMatch[2]}${dynamicMatch[1]}`
|
||||
return `\nrequire(${modulePath});`
|
||||
}
|
||||
|
||||
this.warn(
|
||||
`[${this.pluginName}] Warning: Could not transform statement in ${id}:\n${statement}\n` +
|
||||
`The line after the comment must be a side-effect import or a dynamic import with .then().`,
|
||||
)
|
||||
|
||||
return match
|
||||
})
|
||||
|
||||
if (hasChanged)
|
||||
return {
|
||||
code: newCode,
|
||||
map: null, // Sourcemaps are broken by this transform
|
||||
}
|
||||
|
||||
return null
|
||||
},
|
||||
} satisfies RolldownPlugin
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ Object.defineProperty(globalThis, '__c', {
|
|||
delete globalThis.__c
|
||||
globalThis.__c = clear
|
||||
|
||||
require('./preinit')
|
||||
// @as-require
|
||||
import('./preinit')
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -9,12 +9,15 @@ const unsub = onRunApplication(() => {
|
|||
unsub()
|
||||
|
||||
try {
|
||||
require('./start')
|
||||
// @as-require
|
||||
import('./start')
|
||||
} catch (e) {
|
||||
onError(e)
|
||||
}
|
||||
})
|
||||
|
||||
// Run all init plugins
|
||||
require('~/plugins/init')
|
||||
require('@revenge-mod/plugins/init')
|
||||
// @as-require
|
||||
import '~/plugins/init'
|
||||
// @as-require
|
||||
import '@revenge-mod/plugins/init'
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ registerPlugin<{ storage: Storage }>(
|
|||
api = api_
|
||||
|
||||
onSettingsModulesLoaded(() => {
|
||||
require('./utils').register()
|
||||
// @as-require
|
||||
import('./utils').then(it => it.register())
|
||||
})
|
||||
|
||||
if (api_.plugin.flags & PluginFlags.EnabledLate)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ const pluginSettings = registerPlugin(
|
|||
{
|
||||
start() {
|
||||
onSettingsModulesLoaded(() => {
|
||||
require('./register')
|
||||
// @as-require
|
||||
import('./register')
|
||||
})
|
||||
|
||||
waitForModuleWithImportedPath(
|
||||
|
|
|
|||
|
|
@ -13,30 +13,37 @@ const IndexModuleId = 0
|
|||
onModuleFirstRequired(IndexModuleId, function onIndexRequired() {
|
||||
try {
|
||||
if (__BUILD_FLAG_LOG_PROMISE_REJECTIONS__)
|
||||
require('./patches/log-promise-rejections')
|
||||
// @as-require
|
||||
import('./patches/log-promise-rejections')
|
||||
|
||||
if (__DEV__)
|
||||
nativeLoggingHook(`\u001b[31m--- PREINIT STAGE ---\u001b[0m`, 1)
|
||||
|
||||
// Initialize preinit libraries
|
||||
require('@revenge-mod/react/preinit')
|
||||
require('@revenge-mod/assets/preinit')
|
||||
require('@revenge-mod/discord/preinit')
|
||||
// @as-require
|
||||
import('@revenge-mod/react/preinit')
|
||||
// @as-require
|
||||
import('@revenge-mod/assets/preinit')
|
||||
// @as-require
|
||||
import('@revenge-mod/discord/preinit')
|
||||
|
||||
onModuleInitialized(IndexModuleId, function onIndexInitialized() {
|
||||
if (__DEV__)
|
||||
nativeLoggingHook(`\u001b[31m--- INIT STAGE ---\u001b[0m`, 1)
|
||||
|
||||
try {
|
||||
require('./init')
|
||||
// @as-require
|
||||
import('./init')
|
||||
} catch (e) {
|
||||
onError(e)
|
||||
}
|
||||
})
|
||||
|
||||
// Run all preinit plugins
|
||||
require('~/plugins/preinit')
|
||||
require('@revenge-mod/plugins/preinit')
|
||||
// @as-require
|
||||
import('~/plugins/preinit')
|
||||
// @as-require
|
||||
import('@revenge-mod/plugins/preinit')
|
||||
} catch (e) {
|
||||
onError(e)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue