re-start icon indicating copy to clipboard operation
re-start copied to clipboard

Electron issues

Open thorakmedichi opened this issue 5 years ago • 15 comments

Step 2: Describe your environment

  • template name : re-start
  • template version : Unsure... what existed a Feb 2019
  • react-native version: 55.4 (as per what the template had)
  • OS :Linux
  • Platform causing error: Electron

Step 3: Describe the problem (try to include screenshots):

Running yarn electron-builder produces my AppImage but the screen is blank Running yarn electron-pack (yarn build -c.extraMetadata.main=build/electron.js) errors out with a ton of errors. Top of the list is

Application entry file "build/electron.js" in the "/home/thorakmedichi/Development/Projects/stormfree/day-tracer/dist/linux-unpacked/resources/app.asar" does not exist. Seems like a wrong configuration.
    at error (/home/thorakmedichi/Development/Projects/stormfree/day-tracer/node_modules/app-builder-lib/out/asar/asarFileChecker.js:44:14)

Am I missing something not outlined in your documentation?

Expected Results:

An electron app that works, dev or production.

package.json

{
  "name": "testing",
  "version": "0.1.12",
  "author": "thorakmedichi",
  "main": "./index.electron.js",
  "homepage": "./",
  "scripts": {
    "android": "./node_modules/.bin/react-native run-android",
    "ios": "./node_modules/.bin/react-native run-ios",
    "web": "node scripts/start.js",
    "build": "node scripts/build.js",
    "lint": "eslint . --ext .js",
    "electron-dev": "concurrently \"BROWSER=none yarn react-scripts start\" \"wait-on http://localhost:3000 && electron .\"",
    "electron-pack": "build -c.extraMetadata.main=build/electron.js",
    "electron-build": "electron-builder",
    "preelectron-pack": "yarn build",
   },
  "build": {
    "appId": "com.example.electron-cra",
    "files": [
      "build/**/*",
      "node_modules/**/*",
      "public/*",
      "./index.electron.js"
    ],
    "directories": {
      "buildResources": "assets"
    }
  },

  ....etc

thorakmedichi avatar Mar 27 '19 22:03 thorakmedichi

Resolved pack errors by changing

"electron-pack": "build -c.extraMetadata.main=build/electron.js",

to

"electron-pack": "build -c.extraMetadata.main=./index.electron.js",

Screen still blank.

Upon opening the build folder and running the index.html file locally it also is a blank screen. No errors showing in the dev console.

thorakmedichi avatar Mar 28 '19 00:03 thorakmedichi

So my white screen appears to have been an issue with react-router

It would appear that BrowserHistory wont work with electron so I had to change to HashHistory

thorakmedichi avatar Mar 28 '19 01:03 thorakmedichi

Can you provide a pull-request with your changes to have a record of them?

piranna avatar Mar 28 '19 08:03 piranna

Can you provide a pull-request with your changes to have a record of them?

To be honest I don't know how this repo is put together to even decide where / how to make the PR for you. I just did a react-native init <Your Project Name> --template re-start and fixed from there.

I had to fix jest issues, webpack issues, package.json issues, index.electron.js issues etc AFTER that init.

I am happy to outline what we did though for the electron side if you want to add the PR yourself.

In short the yarn electron that your readme.md shows only loaded a loader, then we had to drag the index.electron.js file into the app loader... and then it only worked for local testing. Zero use in the real world where you need to build to give to other people without dev environments.

In package.json we added these scripts:

"build": "node scripts/build.js",
"electron-build:linux": "yarn build && electron-builder -l",
"electron-build:windows": "yarn build && electron-builder -w",
"electron-build:mac": "yarn build && electron-builder -m",

Then we added the "build" to package.json

"build": {
    "appId": "com.example.electron-cra",
    "files": [
      "dist/**/*",
      "build/**/*",
      "node_modules/**/*",
      "src/assets/**/*",
      "public/*",
      "./index.electron.js"
    ],
    "directories": {
      "buildResources": "./src/common/assets"
    },
    "win": {
      "icon": "./src/common/assets/app-icons/png/512x512.png"
    },
    "linux": {
      "icon": "./src/common/assets/app-icons/png/512x512.png"
    },
    "mac": {
      "icon": "./src/common/assets/app-icons/png/osx-icon-512x512.png"
    }
  },

Then we changed index.electron.js line 24 which was:

mainWindow.loadURL('http://localhost:3000');

To be

mainWindow.loadURL(`file://${path.join(__dirname, './build/index.html')}`);

Basically the following package.json command did nothing but cause issues so we just abandoned it all together

"electron-pack": "build -c.extraMetadata.main=./index.electron.js",

There was some issue in doing the electron build where it didn't like the assets folder outside of the /src dir so we moved them into /src/common/assets to share between all platforms.

We did a lot more than that but that is the core of the electron fixes we needed to do. I just cant remember every thing that was done as a whole for us to make re-start work for our specific use case

thorakmedichi avatar Apr 11 '19 00:04 thorakmedichi

For our router issues - well we use react-navigation for RN as it has better animations and router handling than react-native-router. Basically our entire team thought react-native-router was kinda crap compared to alternatives.

For web we used react-router because its solid for web. To accomplish this we had to build some common interfaces and take advantage of the .web.js notation.

The trick was that RNW didn't like react-router's BrowserHistory for Electron builds so we had to use HashHistory instead.

So we basically had navigator.web.js

import { history } from './history';

/**
 * Used with navigator.js to make a universal command to navigate from components
 * This makes our main code platform agnostic
 *
 * @param {string} routeName The screen to navigate to
 * @param {object} params Any extra data you want to pass to the route
 */
const navigate = (routeName, params = {}) => {
    history.push({
        pathname: routeName,
        state: params
    });
};

const currentRoute = () => history.location.pathname.replace(/\//, '');

const closeDrawer = () => null;

export default {
    navigate,
    currentRoute,
    closeDrawer
};

and navigator.js

import { NavigationActions, DrawerActions } from 'react-navigation';

let navigator;

/**
 * Creates a ref callback to the App.js AppStack
 * @param {string} navigatorRef
 */
const setTopLevelNavigator = (navigatorRef) => {
    navigator = navigatorRef;
}

/**
 * Gets the current screen from react-navigation
 * @param {object} navigationState
 * @returns {*}
 */
const getActiveRouteName = (navigationState) => {
    if (isEmpty(navigationState)) {
        return null;
    }
    const route = navigationState.routes[navigationState.index];
    // dive into nested navigators
    if (route.routes) {
        return getActiveRouteName(route);
    }
    return route.routeName;
};

/**
 * Used with navigator.web.js to make a universal command to navigate from components
 * This makes our main code platform agnostic
 *
 * @param {string} routeName The screen to navigate to
 * @param {object} params Any extra data you want to pass to the route
 */
const navigate = (routeName, params) => {
    navigator.dispatch(
        NavigationActions.navigate({
            routeName,
            params,
        })
    );
}

const currentRoute = () => {
    if (navigator) {
        return getActiveRouteName(navigator.state.nav);
    }

    return null;
}

const closeDrawer = () =>  navigator.dispatch(DrawerActions.closeDrawer());

export default {
    navigate,
    currentRoute,
    setTopLevelNavigator,
    closeDrawer
};

history.js

/**
 * Creates a global history object for navigating web routes
 */
// BrowserHistory does not work with Electron so we have to use HashHistory
import createHashHistory from 'history/createHashHistory';

export const history = createHashHistory();

and our router.web.js file had

import { history } from './history';

<Router history={history}>
//.....
</Router>

Then anywhere in our app we could just do things like NavigationService.navigate('MyScreen') and regardless of the platform it knew what navigation system to use.

thorakmedichi avatar Apr 11 '19 00:04 thorakmedichi

For our jest testing we found that the tests would lock up on us all the time so we changed package.json to be

"test": "npm run test:native && npm run test:web",
"test:web": "node scripts/test.js --config \"./config/web.jest.config.js\" --detectOpenHandles --maxWorkers=10",
"test:native": "node scripts/test.js --config \"./config/native.jest.config.js\" --ci --coverage --detectOpenHandles --maxWorkers=10",

Note the --detectOpenHandles --maxWorkers=10

thorakmedichi avatar Apr 11 '19 01:04 thorakmedichi

Also we use react-native-elements (as I think a lot of people do) so we had to add the following to the webpack.config.xxxxx.js to the include below line 285

// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript and some ESnext features.
`${paths.appNodeModules}/react-native-elements`,
`${paths.appNodeModules}/react-native-vector-icons`,
`${paths.appNodeModules}/react-native-ratings`,
`${paths.appNodeModules}/react-native-status-bar-height`,

We also had to add the following to src/index.js

import iconFont from 'react-native-vector-icons/Fonts/MaterialIcons.ttf';

const iconFontStyles = `
    @font-face {
        src: url(${iconFont}) format('truetype');
        font-family: MaterialIcons;
    }
`;

// Create stylesheet
const style = document.createElement('style');
style.type = 'text/css';

if (style.styleSheet) {
    style.styleSheet.cssText = iconFontStyles;
} else {
    style.appendChild(document.createTextNode(iconFontStyles));
}

// Inject stylesheet
document.head.appendChild(style);

There was more... but that does the broad sweep of changes to basically get us running.

thorakmedichi avatar Apr 11 '19 01:04 thorakmedichi

Oh and one more... we found we had to change babel.config.js to

module.exports = function (api) {
    api.cache(true);
    return {
        presets: [['module:metro-react-native-babel-preset'], ['react-app']],
        ignore: ['node_modules/art/core/color.js'],
        plugins: [
            ['module-resolver', {
                'alias': {
                    '^react-native$': 'react-native-web'
                }
            }]
        ],
    };
};

thorakmedichi avatar Apr 11 '19 01:04 thorakmedichi

The re-start template is obsolete, the new build process is to install the re-base template and all the customized ones on top of it, and after that exec the finish-install script.

piranna avatar Apr 11 '19 06:04 piranna

@amoghbanta can you provide me permissions on npm to fix that? I've already done a script to publish all new templates at once.

piranna avatar Apr 11 '19 07:04 piranna

@piranna, done! You have the access now. 😄

amoghbanta avatar Apr 11 '19 08:04 amoghbanta

Is it still give me login errors...

403 Forbidden - PUT https://registry.npmjs.org/react-native-template-re-base - You do not have permission to publish "react-native-template-re-base". Are you logged in as the correct user?

I'm logged in npm as piranna.

piranna avatar Apr 11 '19 08:04 piranna

The re-start template is obsolete, the new build process is to install the re-base template and all the customized ones on top of it, and after that exec the finish-install script.

okay good to know. We started this project about 1.5 months - 2 months ago and the readme.md that I see here now today is not what it was when we first found your library.

Cheers

thorakmedichi avatar Apr 11 '19 15:04 thorakmedichi

Is it still give me login errors...

403 Forbidden - PUT https://registry.npmjs.org/react-native-template-re-base - You do not have permission to publish "react-native-template-re-base". Are you logged in as the correct user?

I'm logged in npm as piranna.

Hey, @piranna, I just checked, you have admin rights on react-everywhere npm packages. If you could please check once again at your site, that'd be great.

amoghbanta avatar Apr 15 '19 13:04 amoghbanta

NOW it worked :tada: All published as 0.4.1 version, thanks! :-D

piranna avatar Apr 15 '19 14:04 piranna