Cordova与Create-react-app

时间:2017-04-11 04:41:17

标签: javascript reactjs cordova create-react-app

我使用 create-react-app 创建了一个ReactJs应用程序,然后使用npm run build进行了生产构建。在使用Cordova创建的 www 文件夹中,我只需复制 create-react-app 构建文件夹中的所有文件即可。

我想知道如何挂钩Cordova的活动,例如:

function startApp() {
  // your app logic
}
if (window.cordova) {
  document.addEventListener('deviceready', startApp, false);
} else {
  startApp();
}

例如,我想在startApp()内调用缩小的JS文件。或者是否有任何其他工作流可用于使Cordova事件与react应用程序一起使用。

一个小例子会有所帮助。

是否可以使用构建文件并直接在Cordova内部使用React App?我不确定这是如何工作的,因为有Webpack设置将ES6代码转换为ES5和所有。

我是Cordova的新手,并且正在努力应对这种整合方面。

4 个答案:

答案 0 :(得分:28)

我已经找到了两个工作,并将发布在这里寻找相同的其他人。可能还有其他方法可以做到这一点,但这对我有用。

所以基本上我们将使用(比如说)创建一个Cordova应用程序: cordova创建testapp com.test.testapp testapp 这将给我一个文件夹结构:

testapp
        --hooks
        --platforms
        --plugins
        --www
        --config.xml

现在在testapp文件夹中我们运行:create-react-app teastappReact 这将在testapp文件夹中添加我的反应应用程序。 您的react应用程序将在/ src目录中有一个主index.js。

我index.js确保将你的主逻辑包装在一个函数中,然后像这样调用函数和Cordova对象:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';


const startApp = () => {
ReactDOM.render(
  <App />,
  document.getElementById('root')
);
}

if(!window.cordova) {
  startApp()
} else {
  document.addEventListener('deviceready', startApp, false)
}

现在应该这样做,您的应用程序将在应用程序中包含Cordova实例以及navigator.camera等设备对象。

同样在您的反应应用中,可以在公共文件夹中找到index.html,复制您在Codova www文件夹中找到的index.html中的html。现在我们可以删除www文件夹中的所有文件。稍后我们将手动或通过脚本将所有文件从react apps build文件夹复制到Cordova www文件夹。

所以我的index.html看起来如下所示,请注意作为脚本包含的cordova.js文件。

<!DOCTYPE html>
<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
-->
<html>

<head>
    <!--
        Customize this policy to fit your own app's needs. For more guidance, see:
            https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
        Some notes:
            * gap: is required only on iOS (when using UIWebView) and is needed for JS->native communication
            * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
            * Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
                * Enable inline JS: add 'unsafe-inline' to default-src
        -->
    <meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src * data: content:;">
    <meta name="format-detection" content="telephone=no">
    <meta name="msapplication-tap-highlight" content="no">
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

    <!-- Latest compiled and minified CSS -->
    <title>React App</title>
</head>

<body>
    <div id="root"></div>
   <script type="text/javascript" src="cordova.js"></script>
</body>

</html>

最后在您的反应应用程序的package.json中添加以下行: .... “主页”:“../www” .... 这将确保您的最终构建文件指向正确的路径。 我们还可以在package.json构建脚本中添加以下行。

  "scripts": {
    "start": "react-scripts start",
    ***"build": "react-scripts build && robocopy .\\build ..\\www /MIR",***
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "deploy": "npm run build&&gh-pages -d build"
  }

它可以是基于操作系统的robocopy或cp-r(Windows / Linux等)..

我们应该准备好使用我们的Cordova应用程序 cordova build android / ios。

答案 1 :(得分:19)

我解决了这个问题。以下是我为逐步寻找解决方案的步骤格式所做的事情:

  1. React app目录中复制/创建一个新create-react-app项目(使用Cordova创建)。
  2. 清除www app。
  3. Cordova文件夹的所有内容
  4. cd到React项目文件夹(您刚刚复制/创建的)&amp;打开package.json
  5. dependencies之前添加"homepage": "./",&amp;内部脚本将build更改为"build": "react-scripts build && robocopy .\\build ..\\www /MIR",
  6. 在同一个{npm run build&#39; s)目录中执行React&amp;返回父级(Cordova)文件夹,然后在所需平台中buildemulate您的项目。
  7. 奖金提示:如果您在项目中使用<Router>,请将其更改为<HashRouter>,否则您将看到一个空白的显示,因为没有任何内容会呈现给屏幕。

答案 2 :(得分:4)

我认为很难找到解决此问题的完整指南。我这样解决了它,从头开始完成,以便能够在Windows上的模拟Android设备上运行Create React App:

首先创建一个React应用或使用您现有的应用。

npx create-react-app my-app

https://github.com/facebook/create-react-app#creating-an-app

然后安装Cordova:

npm install -g cordova

https://cordova.apache.org/docs/en/latest/guide/cli/

在我的情况下,在my-app文件夹中创建一个新的cordova应用程序:

cordova create hello com.example.hello HelloWorld

将目录更改为hello或您所称的Cordova应用程序。

cordova platform add ios
cordova platform add android

运行cordova requirements来查看构建项目所需的内容。

enter image description here

由于我使用的是Windows,因此在此示例中,我只会为Android构建它。

cordova platform remove ios

并确认我只有cordova platform ls的Android

enter image description here

根据cordova requirements命令安装所需的内容。由于我进行了全新安装,因此我需要所有东西:Java开发工具包(JDK)8,Gradle和Android SDK。链接可以在这里找到:

https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html#requirements-and-support

或者:

https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html

https://gradle.org/install/

https://developer.android.com/studio/index.html

安装后打开Android Studio。我选择了标准安装,但失败并显示以下警告:

无法安装英特尔HAXM。有关详细信息,请检查 安装日志:“ C:\ Users \ Oscar \ AppData \ Local \ Temp \ haxm_log.txt” 英特尔®HAXM安装失败。要安装英特尔®HAXM,请按照 有关说明,请访问: https://software.intel.com/android/articles/installation-instructions-for-intel-hardware-accelerated-execution-manager-windows安装程序日志位于

C:\ Users \ Oscar \ AppData \ Local \ Temp \ haxm_log.txt安装程序日志内容: ===开始记录:2020-07-10 16:39:27 ===此计算机不支持英特尔虚拟化技术(VT-x),或者正在 Hyper-V专用。无法安装HAXM。请确保 Windows功能中禁用了Hyper-V,或参考Intel HAXM 文档以获取更多信息。

但是我仍然可以启动该应用程序,并添加在“配置”下找到的Android虚拟设备(AVD)。

enter image description here

我选择在Pixel XL系统映像中添加一个R

但是再次运行cordova requirements时,我可以看到我需要一个API级为28的Android目标。R为级30。

enter image description here

因此,我以API级别28 x86_64安装了Pie,并创建了一个新的虚拟设备。

enter image description here

我没有打开AVD Manager,而是打开SDK manager并下载了Android 9.0 Pie SDK。

enter image description here

现在一切看起来都很好:

enter image description here

然后运行cordova emulate android以测试默认的Cordova应用程序。

如果有效,则应如下所示:

enter image description here

将目录更改为my-app

编辑package.json并在依赖项之前添加"homepage": "./",

enter image description here

感谢@BlackBeard。来源:https://stackoverflow.com/a/46785362/3850405

运行npm run build

清除my-app\hello\www中的所有内容,然后将所有内容从my-app\build复制到my-app\hello\www

Voilà:

enter image description here

如果您不编辑my-app package.json并添加"homepage": "./",,它将看起来像这样:

enter image description here

经验教训:

1。

如果您在项目中使用<Router>,请将其更改为<HashRouter>,否则您将看到空白显示,因为屏幕上没有任何内容。适用于iOS和Android。

来源: https://stackoverflow.com/a/46785362/3850405

2。

您需要白名单才能允许使用URL。来自文档:

默认情况下,仅允许导航到file:// URL。允许 其他网址,则必须在config.xml中添加标签:

https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-whitelist/

像这样安装:

cordova plugin add cordova-plugin-whitelist

然后编辑位于应用程序根目录中的config.xml并添加以下任意一项:

<!-- Allow links to example.com -->
<allow-navigation href="http://example.com/*" />

<!-- Wildcards are allowed for the protocol, as a prefix
     to the host, or as a suffix to the path -->
<allow-navigation href="*://*.example.com/*" />

<!-- A wildcard can be used to whitelist the entire network,
     over HTTP and HTTPS.
     *NOT RECOMMENDED* -->
<allow-navigation href="*" />

来源:https://stackoverflow.com/a/30327204/3850405

3。

即使您使用的是白名单,您仍可能需要访问不支持https的http API。默认情况下,这是不允许的,并且可能引起一些真正的头痛。也可以通过编辑config.xml并在<platform name="android">下添加以下内容来解决此问题:

<edit-config xmlns:android="http://schemas.android.com/apk/res/android"  file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">     <application android:usesCleartextTraffic="true" /></edit-config>

鉴于您没有浏览到URL,任何API调用都必须指定实际的服务器。我通常使用Axios,因此我们只需要将服务器添加到默认URL。示例:

import axios, { AxiosPromise, AxiosRequestConfig, Method } from 'axios';

const getConfig = (url: string, method: Method, params?: any, data?: any) => {
     const config: AxiosRequestConfig = {
         url: 'http://192.168.1.249' + url,
         method: method,
         responseType: 'json',
         params: params,
         data: data,
         headers: { 'X-Requested-With': 'XMLHttpRequest' },
    }
    return config;
}

export const sendRequest = (url: string, method: Method, params?: any, data?: any): AxiosPromise<any> => {
    return axios(getConfig(url, method))
}

然后这样称呼:

const path = '/api/test/'

export const initialLoad = (number: number): AxiosPromise<InitialLoadDto> => {
    return sendRequest(path + 'InitialLoad/' + number, 'get');
}

答案 3 :(得分:-1)

try it,这是最好的组合。

转到git中的readme.md并以此开始