Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/bare-expo/android/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ gen-external-apklibs
# Java class files

# Generated files
app/src/main/java/local/

# Gradle files
.gradle
Expand Down
27 changes: 27 additions & 0 deletions apps/bare-expo/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ android {
androidResources {
ignoreAssetsPattern '!.svn:!.git:!.ds_store:!*.scc:!CVS:!thumbs.db:!picasa.ini:!*~'
}
if (project.properties["expo.inlineModules.enabled"] == "true") {
sourceSets {
main {
java {
srcDirs += [file('build/inline/modules/').absolutePath]
}
}
}
}
}

// Apply static values from `gradle.properties` to the `android.packagingOptions`
Expand Down Expand Up @@ -205,3 +214,21 @@ class ExecuteSetupAndroidProject implements Plugin<Project> {
}

apply plugin: ExecuteSetupAndroidProject

gradle.projectsEvaluated {
if (project.properties["expo.inlineModules.enabled"] == "true") {
providers.exec {
workingDir(projectRoot)
commandLine(
"node",
"--no-warnings",
"--eval",
"require(require.resolve('expo-modules-autolinking', { paths: [require.resolve('expo/package.json')] }))(process.argv.slice(1))",
"mirror-kotlin-inline-modules",
file('src/main/java/local/modules/').absolutePath,
file('build/inline/modules/').absolutePath,
project.properties["expo.inlineModules.watchedDirectories"]
)
}.standardOutput.asText.get()
}
}
6 changes: 6 additions & 0 deletions apps/bare-expo/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,9 @@ expo.useLegacyPackaging=false
EXPO_ALLOW_GLIDE_LOGS=true

android.enableMinifyInReleaseBuilds=true

# Enable support for local modules in Expo CLI and Expo Modules Autolinking.
expo.inlineModules.enabled=true

# List of directories watched for local modules.
expo.inlineModules.watchedDirectories=["../native-component-list/src/screens/inlineModules/inlineModulesExamples"]
10 changes: 9 additions & 1 deletion apps/bare-expo/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@
],
"./plugins/withAndroidNetworkSecurityConfig",
"./plugins/withBenchmarkModules"
]
],
"experiments": {
"inlineModules": true
},
"inlineModules": {
"watchedDirectories": [
"../native-component-list/src/screens/inlineModules/inlineModulesExamples"
]
}
}
}
20 changes: 19 additions & 1 deletion apps/bare-expo/ios/BareExpo.xcodeproj/project.pbxproj

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/bare-expo/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3700,7 +3700,7 @@ SPEC CHECKSUMS:
React: ade831e2e38887292c2c7d40f2f4098826a9dda4
React-callinvoker: 0496e88932950260bbced6f84c633c40ec865f7f
React-Core: c039131635f507742ca871a0f130aabdb7a2c57b
React-Core-prebuilt: 265a5ea421d251f0caf7b834230aa1044b1395db
React-Core-prebuilt: bfd90883151c7ca03c3f14e7a8bbc211a5a1b8c8
React-CoreModules: 89efc8cd313843796b11ef62caf9f73169d79a94
React-cxxreact: 532f14ce8e3490a6053f96a2fe964f29b0b530de
React-debug: c1ec6ee07de860f9113e88d96fb3dad6a69d4afd
Expand Down
2 changes: 2 additions & 0 deletions apps/bare-expo/ios/Podfile.properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
"expo.jsEngine": "hermes",
"newArchEnabled": "true",
"EX_DEV_CLIENT_NETWORK_INSPECTOR": "true",
"expo.inlineModules.enabled": "true",
"expo.inlineModules.watchedDirectories": "[\"../native-component-list/src/screens/inlineModules/inlineModulesExamples\"]",
"ios.buildReactNativeFromSource": "false"
}
51 changes: 51 additions & 0 deletions apps/bare-expo/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-env node */
// Learn more https://docs.expo.dev/guides/customizing-metro/
const { getDefaultConfig } = require('expo/metro-config');
const fs = require('node:fs');
const path = require('node:path');

/** @type {import('expo/metro-config').MetroConfig} */
Expand All @@ -24,6 +25,28 @@ config.watchFolders = [
path.join(monorepoRoot, 'apps/test-suite'), // Workaround for Yarn v1 workspace issue where workspace dependencies aren't properly linked, should be at `<root>/node_modules/apps/test-suite`
];

function findUpTSConfig(cwd) {
const tsconfigPath = path.resolve(cwd, './tsconfig.json');
if (fs.existsSync(tsconfigPath)) {
return path.dirname(tsconfigPath);
}

const parent = path.dirname(cwd);
if (parent === cwd) return null;

return findUpTSConfig(parent);
}

function findUpTSProjectRootOrThrow(dir) {
const tsProjectRoot = findUpTSConfig(dir);
if (!tsProjectRoot) {
throw new Error(
'Inline modules watched dir needs to be inside a TS project with tsconfig.json'
);
}
return tsProjectRoot;
}

// When testing on MacOS we need to swap out `react-native` for `react-native-macos`
config.resolver.resolveRequest = (context, moduleName, platform) => {
if (
Expand All @@ -33,6 +56,34 @@ config.resolver.resolveRequest = (context, moduleName, platform) => {
const newModuleName = moduleName.replace('react-native', 'react-native-macos');
return context.resolveRequest(context, newModuleName, platform);
}

const inlineModulesModulesPath = path.resolve(__dirname, './.expo/inlineModules/modules');

let inlineModuleFileExtension = null;
if (moduleName.endsWith('.module')) {
inlineModuleFileExtension = '.module.js';
} else if (moduleName.endsWith('.view')) {
inlineModuleFileExtension = '.view.js';
}
if (inlineModuleFileExtension) {
const tsProjectRoot = findUpTSProjectRootOrThrow(path.dirname(context.originModulePath));
const modulePathRelativeToTSRoot = path.relative(
tsProjectRoot,
fs.realpathSync(path.dirname(context.originModulePath))
);

const modulePath = path.resolve(
inlineModulesModulesPath,
modulePathRelativeToTSRoot,
moduleName.substring(0, moduleName.lastIndexOf('.')) + inlineModuleFileExtension
);

return {
filePath: modulePath,
type: 'sourceFile',
};
}

return context.resolveRequest(context, moduleName, platform);
};

Expand Down
6 changes: 6 additions & 0 deletions apps/native-component-list/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@
"eas": {
"projectId": "2c28de10-a2cd-11e6-b8ce-59d1587e6774"
}
},
"experiments": {
"inlineModules": true
},
"inlineModules": {
"watchedDirectories": ["src/screens/inlineModules/inlineModulesExamples/"]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ export const ScreensList: ScreenConfig[] = [
},
name: 'Battery',
},
{
getComponent() {
return optionalRequire(() => require('../screens/inlineModules/InlineModulesScreen'));
},
name: 'InlineModules',
},
{
getComponent() {
return optionalRequire(() => require('../screens/Blob/BlobScreen'));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Text } from 'react-native';

import SimpleModule from './inlineModulesExamples/SimpleModule.module';
import TestView from './inlineModulesExamples/TestView.view';

export default function InlineModulesScreen() {
return (
<>
<Text>{SimpleModule.test}</Text>
<TestView style={{ flex: 1 }} url="https://docs.expo.dev/modules/" />
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package inlineModulesExamples

import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition

public class SimpleModule : Module() {
override fun definition() = ModuleDefinition {
Constant("test") { ->
"Kotlin constant 1 new inlineModulesProvider"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import ExpoModulesCore
import WebKit

public class SimpleModule: Module {
public func definition() -> ModuleDefinition {
Constant("test") {
return "Swift constant 1283"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package inlineModulesExamples

import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
import java.net.URL

import android.content.Context
import android.webkit.WebView
import android.webkit.WebViewClient
import expo.modules.kotlin.AppContext
import expo.modules.kotlin.viewevent.EventDispatcher
import expo.modules.kotlin.views.ExpoView

class TestView : Module() {
override fun definition() = ModuleDefinition {
View(ExpoWebView::class) {
Events("onLoad")

Prop("url") { view: ExpoWebView, url: URL? ->
view.webView.loadUrl(url.toString())
}
}
}
}

class ExpoWebView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
private val onLoad by EventDispatcher()

internal val webView = WebView(context).also {
it.layoutParams = LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT
)

it.webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
onLoad(mapOf("url" to url))
}
}

addView(it)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import ExpoModulesCore
import WebKit

public class TestView: Module {
public func definition() -> ModuleDefinition {
View(ExpoWebView.self) {
Events("onLoad")

Prop("url") { (view, url: URL) in
if view.webView.url != url {
let urlRequest = URLRequest(url: url)
view.webView.load(urlRequest)
}
}
}
}
}

class ExpoWebView: ExpoView, WKNavigationDelegate {
let webView = WKWebView()
let onLoad = EventDispatcher()

required init(appContext: AppContext? = nil) {
super.init(appContext: appContext)
clipsToBounds = true
webView.navigationDelegate = self
addSubview(webView)
}

override func layoutSubviews() {
webView.frame = bounds
}

func webView(_ webView: WKWebView, _: WKNavigation) {
if let url = webView.url {
onLoad([
"url": url.absoluteString
])
}
}
}
10 changes: 8 additions & 2 deletions apps/native-component-list/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
"strictPropertyInitialization": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"noImplicitReturns": true
"noImplicitReturns": true,
"rootDirs": ["./", "../bare-expo/.expo/inlineModules/types"]
},
"include": ["App.tsx", "src/**/*", "ts-declarations/**/*"]
"include": [
"App.tsx",
"src/**/*",
"ts-declarations/**/*",
"../bare-expo/.expo/inlineModules/types/**/*"
]
}
Loading
Loading