使用 React 本机静态服务器和 webview 从 node_modules 服务 html 文件
serve html file from node_modules using react native static server and webview
是否可以从 node_modules
文件夹中提供 html 文件?我知道如何从资产文件夹提供服务,例如:
<WebView
...
source={{uri:'file:///android_asset/project_a/index.html'}}/>
或 iOS
的相应路径,但如何访问 node_modules
文件夹并从那里提供文件?我已经尝试使用 require()
and/or 使用我想要提供的模块的路径但没有运气。
我的想法是,我想避免在项目之间复制粘贴构建文件(即,从项目 A 的构建文件夹到项目 B 的 assets/www),相反,我想发布项目 A作为 npm 包和 npm 安装并从项目 B 提供服务。这也改进了项目的版本管理。
我最终向 packages.json
添加了一个脚本,该脚本在启动应用程序之前将感兴趣的文件复制到 assets/www
文件夹中。类似于:
"scripts": {
"copy:build": "node -e \"fs.copyFileSync('./node_modules/dir-of-module','./assets/www/build')\"",
"start-android": "npm run copyAssets && react-native run-android",
...
}
如果有更好的选择,请告诉我!
对于 Android,您可以 运行 自定义 Gradle 任务,该任务能够在构建时处理复制您的资产。
在模块的根目录中创建一个 Gradle 文件,如下所示:
(我假设你的模块名称是 react-native-my-awesome-module
并且你的 HTML 文件在模块根目录下的 www 文件夹下。)
awesome.gradle:
/**
* Register HTML asset source folder
*/
android.sourceSets.main.assets.srcDirs += file("$buildDir/intermediates/ReactNativeMyAwesomeModule")
/**
* Task to copy HTML files
*/
afterEvaluate {
def targetDir = "../../node_modules/react-native-my-awesome-module/www";
def fileNames = [ "*.html" ];
def htmlCopyTask = tasks.create(
name: "copyReactNativeMyAwesomeModuleAssets",
type: Copy) {
description = "copy react native my awesome module assets."
into "$buildDir/intermediates/ReactNativeMyAwesomeModule/www"
fileNames.each { fileName ->
from(targetDir) {
include(fileName)
}
}
}
android.applicationVariants.all { def variant ->
def targetName = variant.name.capitalize()
def generateAssetsTask = tasks.findByName("generate${targetName}Assets")
generateAssetsTask.dependsOn(htmlCopyTask)
}
}
安装模块后,将以下行放入项目的 android/app/build.gradle
文件中:
apply from: file("../../node_modules/react-native-my-awesome-module/awesome.gradle");
当您构建应用程序时,将从您的模块复制 www 文件夹下的资产。您可以在您的应用中访问您的资源,如下所示:
<WebView
source={{uri: 'file:///android_asset/www/index.html'}}
/>
是否可以从 node_modules
文件夹中提供 html 文件?我知道如何从资产文件夹提供服务,例如:
<WebView
...
source={{uri:'file:///android_asset/project_a/index.html'}}/>
或 iOS
的相应路径,但如何访问 node_modules
文件夹并从那里提供文件?我已经尝试使用 require()
and/or 使用我想要提供的模块的路径但没有运气。
我的想法是,我想避免在项目之间复制粘贴构建文件(即,从项目 A 的构建文件夹到项目 B 的 assets/www),相反,我想发布项目 A作为 npm 包和 npm 安装并从项目 B 提供服务。这也改进了项目的版本管理。
我最终向 packages.json
添加了一个脚本,该脚本在启动应用程序之前将感兴趣的文件复制到 assets/www
文件夹中。类似于:
"scripts": {
"copy:build": "node -e \"fs.copyFileSync('./node_modules/dir-of-module','./assets/www/build')\"",
"start-android": "npm run copyAssets && react-native run-android",
...
}
如果有更好的选择,请告诉我!
对于 Android,您可以 运行 自定义 Gradle 任务,该任务能够在构建时处理复制您的资产。
在模块的根目录中创建一个 Gradle 文件,如下所示:
(我假设你的模块名称是 react-native-my-awesome-module
并且你的 HTML 文件在模块根目录下的 www 文件夹下。)
awesome.gradle:
/**
* Register HTML asset source folder
*/
android.sourceSets.main.assets.srcDirs += file("$buildDir/intermediates/ReactNativeMyAwesomeModule")
/**
* Task to copy HTML files
*/
afterEvaluate {
def targetDir = "../../node_modules/react-native-my-awesome-module/www";
def fileNames = [ "*.html" ];
def htmlCopyTask = tasks.create(
name: "copyReactNativeMyAwesomeModuleAssets",
type: Copy) {
description = "copy react native my awesome module assets."
into "$buildDir/intermediates/ReactNativeMyAwesomeModule/www"
fileNames.each { fileName ->
from(targetDir) {
include(fileName)
}
}
}
android.applicationVariants.all { def variant ->
def targetName = variant.name.capitalize()
def generateAssetsTask = tasks.findByName("generate${targetName}Assets")
generateAssetsTask.dependsOn(htmlCopyTask)
}
}
安装模块后,将以下行放入项目的 android/app/build.gradle
文件中:
apply from: file("../../node_modules/react-native-my-awesome-module/awesome.gradle");
当您构建应用程序时,将从您的模块复制 www 文件夹下的资产。您可以在您的应用中访问您的资源,如下所示:
<WebView
source={{uri: 'file:///android_asset/www/index.html'}}
/>