-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.ts
More file actions
156 lines (140 loc) · 5.44 KB
/
build.ts
File metadata and controls
156 lines (140 loc) · 5.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { transform } from '@swc/core'
import { existsSync } from 'fs'
import { type OutputChunk, type RolldownPlugin, rolldown } from 'rolldown'
import rdtPkg from './node_modules/react-devtools-core/package.json' with { type: 'json' }
const bundle = await rolldown({
input: 'index.js',
platform: 'neutral',
tsconfig: './tsconfig.json',
treeshake: true,
transform: {
define: {
__RDT_VERSION: JSON.stringify(rdtPkg.version),
},
},
plugins: [
swcPlugin(),
hermesCPlugin({
flags: ['-O', '-fno-static-require', '-Wno-direct-eval', '-Wno-undefined-variable'],
}),
],
})
await bundle.write({
file: 'dist/index.js',
format: 'iife',
intro: `
function __fmt(arg) {
if (typeof arg === 'string') return arg
var proto = Object.getPrototypeOf(arg) ?? Object.prototype
return proto.toString.call(arg)
}
var __mklog = (lvl) => (...args) => {
if (args.length === 1) nativeLoggingHook(__fmt(args[0]), lvl)
else nativeLoggingHook(args.map(__fmt).join(' '), lvl)
}
var window = self = globalThis, console = { log: __mklog(0), info: __mklog(1), warn: __mklog(1), error: __mklog(2) }
console.log("React DevTools bundle loading...")
`,
postFooter: '//# sourceURL=ReactDevTools',
keepNames: true,
})
function swcPlugin() {
return {
name: 'swc',
transform: {
filter: {
id: /\.[cm]?[jt]sx?$/,
},
handler(code) {
return transform(code, {
jsc: {
transform: {
react: {
runtime: 'automatic',
},
},
parser: {
syntax: 'typescript',
tsx: true,
},
},
env: {
// https://github.com/discord/hermes/blob/main/doc/Features.md
targets: 'fully supports es6',
include: [
'transform-async-generator-functions',
'transform-block-scoping',
'transform-classes',
'transform-duplicate-named-capturing-groups-regex',
'transform-named-capturing-groups-regex',
],
exclude: [
// Async functions are supported, only async arrow functions aren't
// Source: https://github.com/facebook/hermes/issues/1395
'transform-async-to-generator',
'transform-exponentiation-operator',
'transform-logical-assignment-operators',
'transform-nullish-coalescing-operator',
'transform-numeric-separator',
'transform-object-rest-spread',
'transform-optional-catch-binding',
'transform-optional-chaining',
'transform-parameters',
'transform-template-literals',
],
},
})
},
},
} satisfies RolldownPlugin
}
async function hermesCPlugin({
after,
before,
flags,
}: {
flags?: string[]
before?: (v: string) => void
after?: (v: string) => void
} = {}) {
const paths = {
win32: 'win64-bin/hermesc.exe',
darwin: 'osx-bin/hermesc',
linux: 'linux64-bin/hermesc',
}
if (!(process.platform in paths)) throw new Error(`Unsupported platform: ${process.platform}`)
const sdksDir = './node_modules/react-native/sdks'
const binPath = `${sdksDir}/hermesc/${paths[process.platform as keyof typeof paths]}`
if (!existsSync(binPath))
throw new Error(`Hermes compiler not found at ${binPath}. Please ensure you have react-native installed.`)
const ver = await Bun.file(`${sdksDir}/.hermesversion`).text()
return {
name: 'hermesc',
generateBundle(_, bundle) {
if (before) before(ver)
const file = bundle['index.js'] as OutputChunk
if (!file || !file.code) throw new Error('No code to compile')
const cmdlist = [binPath, '-emit-binary', ...(flags ?? [])]
const cmd = Bun.spawnSync<'pipe', 'pipe'>(cmdlist, {
// @ts-expect-error: Types are incorrect, but this works
stdin: new Blob([file.code]),
stdout: 'pipe',
})
if (cmd.exitCode) {
if (cmd.stderr.length) throw new Error(`Got error from hermesc: ${cmd.stderr.toString()}`)
throw new Error(`hermesc exited with code: ${cmd.exitCode}`)
}
const buf = cmd.stdout
if (!buf.length)
throw new Error(
`No output from hermesc. Probably a compilation error.\nTry running the command manually: ${cmdlist.join(' ')}`,
)
this.emitFile({
type: 'asset',
fileName: `${file.fileName.split('.')[0]!}.bundle`,
source: buf,
})
if (after) after(ver)
},
} satisfies RolldownPlugin
}