refactor: build script, use react-jsx

This commit is contained in:
amsyarasyiq 2024-07-08 19:22:01 +08:00
parent 14e7c61f39
commit 4d144f60d9
10 changed files with 67 additions and 76 deletions

View file

@ -1,5 +1,4 @@
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
@ -9,6 +8,9 @@
"[typescriptreact]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[json]": {
"editor.formatOnSave": false
},
"javascript.format.semicolons": "insert",
"typescript.format.semicolons": "insert",
"typescript.preferences.quoteStyle": "double",

View file

@ -28,6 +28,7 @@
"@typescript-eslint/typescript-estree": "^7.1.1",
"chalk": "^5.3.0",
"esbuild": "^0.20.2",
"esbuild-plugin-globals": "^0.2.0",
"eslint": "^8.57.0",
"eslint-plugin-import-alias": "^1.2.0",
"eslint-plugin-react": "^7.34.0",
@ -46,10 +47,7 @@
},
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": [
"react",
"react-native"
]
"ignoreMissing": ["react", "react-native"]
}
}
}

8
pnpm-lock.yaml generated
View file

@ -61,6 +61,9 @@ devDependencies:
esbuild:
specifier: ^0.20.2
version: 0.20.2
esbuild-plugin-globals:
specifier: ^0.2.0
version: 0.2.0
eslint:
specifier: ^8.57.0
version: 8.57.0
@ -1172,6 +1175,11 @@ packages:
resolution: {integrity: sha512-ldETiVy9nu3uCHKsALW4pGitzASWivUq79DdMQqdLa2Nx0swhULpvXCqSoJrWYVI69bsgaNRqnFRwpHie8hY+A==}
dev: false
/esbuild-plugin-globals@0.2.0:
resolution: {integrity: sha512-y+6utQVWrETQWs0J8EGLV5gEOP59mmjX+fKWoQHn4TYwFMaj0FxQYflc566tHuokBCzl+uNW2iIlM1o1jfNy6w==}
engines: {node: '>=7'}
dev: true
/esbuild@0.20.2:
resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==}
engines: {node: '>=12'}

View file

@ -3,6 +3,7 @@
import swc from "@swc/core";
import crypto from "crypto";
import { build } from "esbuild";
import globalPlugin from "esbuild-plugin-globals";
import { readFile, writeFile } from "fs/promises";
import path from "path";
import { fileURLToPath } from "url";
@ -41,28 +42,15 @@ const config = {
__DEV__: JSON.stringify(releaseBranch !== "main")
},
legalComments: "none",
alias: {
"spitroast": "./node_modules/spitroast",
"react/jsx-runtime": "./shims/jsxRuntime"
},
plugins: [
{
name: "runtimeGlobalAlias",
setup: async build => {
const globalMap = {
"react": "globalThis.React",
"react-native": "globalThis.ReactNative"
};
Object.keys(globalMap).forEach(key => {
const filter = new RegExp(`^${key}$`);
build.onResolve({ filter }, args => ({
namespace: "glob-" + key, path: args.path
}));
build.onLoad({ filter, namespace: "glob-" + key }, () => ({
// @ts-ignore
contents: `Object.defineProperty(module, 'exports', { get: () => ${globalMap[key]} })`,
resolveDir: "src",
}));
});
}
},
globalPlugin({
"react": "React",
"react-native": "ReactNative"
}),
{
name: "swc",
setup(build) {
@ -79,7 +67,7 @@ const config = {
}
},
react: {
pragma: "__bunny_createElement"
runtime: "automatic"
}
},
},

1
shims/emptyModule.tsx Normal file
View file

@ -0,0 +1 @@
export {};

14
shims/jsxRuntime.tsx Normal file
View file

@ -0,0 +1,14 @@
import { getFactoryOfProxy } from "@lib/utils/lazy";
import { findByPropsProxy } from "@metro/utils";
const jsxRuntime = findByPropsProxy("jsx", "jsxs", "Fragment");
function unproxyFirstArg<T>(args: T[]) {
const factory = getFactoryOfProxy(args[0]);
if (factory) args[0] = factory();
return args;
}
export const Fragment = Symbol.for("react.fragment");
export const jsx = (...args: any[]) => jsxRuntime.jsx(...unproxyFirstArg(args));
export const jsxs = (...args: any[]) => jsxRuntime.jsxs(...unproxyFirstArg(args));

View file

@ -1,17 +1,9 @@
import { getFactoryOfProxy } from "@lib/utils/lazy";
import { version } from "bunny-build-info";
import { instead } from "spitroast";
const { instead } = require("spitroast");
// @ts-ignore - shut up fr
globalThis.window = globalThis;
// @ts-ignore && TODO: Move this to a more sensible place
globalThis.__bunny_createElement = function createElement(type, props, ...children) {
const factory = getFactoryOfProxy(type);
if (factory) type = factory();
return React.createElement(type, props, ...children);
};
async function initializeBunny() {
try {
// Make 'freeze' and 'seal' do nothing
@ -42,7 +34,7 @@ if (typeof globalThis.__r !== "undefined") {
const batchedBridge = window.__fbBatchedBridge;
const callQueue = new Array<any>;
const unpatchHook = instead("callFunctionReturnFlushedQueue", batchedBridge, (args, orig) => {
const unpatchHook = instead("callFunctionReturnFlushedQueue", batchedBridge, (args: any, orig: any) => {
if (args[0] === "AppRegistry" || !batchedBridge.getCallableModule(args[0])) {
callQueue.push(args);
return batchedBridge.flushedQueue();

View file

@ -1,14 +1,16 @@
import { getFindContext } from "@metro/proxy";
import {
after as _after,
before as _before,
instead as _instead
} from "spitroast";
const {
after: _after,
before: _before,
instead: _instead
} = require("spitroast") as
// Temporary
typeof import("../../../node_modules/spitroast");
type ParametersAfterOneArgs<F> = F extends (x: any, y: any, ...args: infer P) => unknown ? P : never;
type ProxyPatchParameters<T, P> = [func: string, parent: [P, (t: P) => any], ...args: ParametersAfterOneArgs<T>];
type ParametersAfterTwoArgs<F> = F extends (x: any, y: any, ...args: infer P) => unknown ? P : never;
type ProxyPatchParameters<T, P> = [func: string, parent: [P, (t: P) => any], ...args: ParametersAfterTwoArgs<T>];
function shim<T extends (func: string, parent: any, ...args: ParametersAfterOneArgs<T>) => any>(fn: T) {
function shim<T extends (func: string, parent: any, ...args: ParametersAfterTwoArgs<T>) => any>(fn: T) {
function shimmed(this: any, ...args: Parameters<T>) {
const proxyInfo = getFindContext(args[1]);
if (proxyInfo && !proxyInfo.cache && proxyInfo.indexed) {

View file

@ -1,6 +1,7 @@
import { ExportsFlags, getMetroCache, indexBlacklistFlag, indexExportsFlags, ModulesMapInternal } from "@metro/caches";
import { Metro } from "@metro/types";
import { before, instead } from "spitroast";
const { before, instead } = require("spitroast");
export const metroModules: Metro.ModuleList = window.modules;
const metroRequire: Metro.Require = window.__r;
@ -87,7 +88,7 @@ function onModuleRequire(moduleExports: any, id: Metro.ModuleID) {
// There are modules registering the same native component
if (moduleExports?.default?.name === "requireNativeComponent") {
instead("default", moduleExports, (args, origFunc) => {
instead("default", moduleExports, (args: any, origFunc: any) => {
try {
return origFunc(...args);
} catch {
@ -112,7 +113,7 @@ function onModuleRequire(moduleExports: any, id: Metro.ModuleID) {
}
if (!patchedImportTracker && moduleExports.fileFinishedImporting) {
before("fileFinishedImporting", moduleExports, ([filePath]) => {
before("fileFinishedImporting", moduleExports, ([filePath]: [string]) => {
if (_importingModuleId === -1 || !filePath) return;
metroModules[_importingModuleId]!.__filePath = filePath;
});
@ -137,7 +138,7 @@ function onModuleRequire(moduleExports: any, id: Metro.ModuleID) {
// Hindi timestamps moment
if (moduleExports.isMoment) {
instead("defineLocale", moduleExports, (args, orig) => {
instead("defineLocale", moduleExports, (args: [string], orig: (lcl: string) => string) => {
const origLocale = moduleExports.locale();
orig(...args);
moduleExports.locale(origLocale);

View file

@ -5,33 +5,18 @@
"compilerOptions": {
"strict": true,
"paths": {
"@core/*": [
"./src/core/*"
],
"@lib": [
"./src/lib"
],
"@lib/*": [
"./src/lib/*"
],
"@metro": [
"./src/metro"
],
"@metro/*": [
"./src/metro/*"
],
"@ui": [
"./src/lib/ui"
],
"@ui/*": [
"./src/lib/ui/*"
],
"@types": [
"./src/lib/utils/types.ts"
],
"@assets/*": [
"./src/assets/*"
]
// Just to discourage from consuming the module directly
"spitroast": ["./shims/emptyModule"],
"@core/*": ["./src/core/*"],
"@lib": ["./src/lib"],
"@lib/*": ["./src/lib/*"],
"@metro": ["./src/metro"],
"@metro/*": ["./src/metro/*"],
"@ui": ["./src/lib/ui"],
"@ui/*": ["./src/lib/ui/*"],
"@types": ["./src/lib/utils/types.ts"],
"@assets/*": ["./src/assets/*"]
},
"module": "esnext",
"moduleResolution": "bundler",