How to manage different config files for development and production with react-native - react-native

For testing my app locally I put dummy values in the code. Several times, I have forgotten to remove these values and pushed the changes, which is fine in development, but not in production. To avoid that this happens, I wanted to have a local config that overwrites the global config file. Something like :
const config = {
'auth.initial.email': '',
'auth.initial.password': '',
}
// Override defaults with local config
let extraConfig = null
try {
extraConfig = require('./config.local')
} catch(err) {}
Object.assign(config, extraConfig.default)
export default config
I believe this would work in node, but in react-native I get an error "Unable to resolve module". Is there a standard solution for this, or a simple way to catch and ignore import errors from JS in react-native?

You could use the __DEV__ variable from react-native.
This variable is set to true if you are in development mode.
It's set to false if your app is in production.

Related

PWA InjectManifest workbox console / debug output suddenly disabled (Vue.js / Quasar Framework)

I'm building a PWA with Vue.js / Quasar Framework and recently added the PWA capability. I changed the "workboxPluginMode" property to "InjectManifest" and at first Workbox gave me debug / console as expected.
Also, the "custom-service-worker.js" definetly gets picked up by the process because it displays an error when i remove this line:
precacheAndRoute(self.__WB_MANIFEST)
So the file is recognized and actively using the defined caching strategies (i think), but it won't provide me any debug info or console.log's on console anymore. I really don't know what i have changed to do that.
My "custom-service-worker.js" looks like this:
import { precacheAndRoute } from 'workbox-precaching'
import { registerRoute } from 'workbox-routing'
import { StaleWhileRevalidate } from 'workbox-strategies'
console.log('custom service worker active')
// Use with precache injection
precacheAndRoute(self.__WB_MANIFEST)
// Caching strategies
registerRoute(
({url}) => {
console.log(url)
// url.pathname.startsWith('/images')
},
new StaleWhileRevalidate()
);
self.addEventListener('fetch', function(event) {
console.log(event)
event.respondWith(fetch(event.request));
})
I have no clue why, but the console debug output of workbox was only displayed in my default browser (Vivaldi). I wanted to work on plain Chromium because I couldn't install my PWA with Vivaldi (no installation prompt popped up), but that also works now. Have literally no explanation for this, but this is PWA development I guess, it is what it is. Anyways, problem solved for me.

VueJS and ElectronJS | VueJS stops rendering completely when I import ipcRenderer in a component

So I am coding a VueJS and ElectronJS template which can be found here: https://github.com/dev-aethex/electronjstemplate
My code works something like this,
Inside of my Vue component I access a global pre constructed class called MainProcessInterface and when it's constructed it first checks if vue is compiled for running in a development server. If it's in a dev server it will connect to the dev socket which electrons main process will host if electron is in dev mode and not compiled. This method seems to be working great, I had to use a socket because vue dev server is being loaded into electron via loadURL and so vue has no clue what ipcRenderer is. Inside the main process interface, if vue is compiled it will instead use the ipcRenderer.send() method. This is were the problem was born.
As soon as Vue runs thought the TS code, it sees ipcRenderer.send and freaks out while printing an error to the electron window console saying fs.existsSync does not exist or is defined.
I can't find a way around this. I though maybe i'll split MainProcessInterface into 2 peices, one for ipc and the other for websockets. Although it isn't a very good way, so before implementing it, I would like to know if there is a better more proper way of doing such.
I had a similar issue with React. Are you importing the ipcRenderer object somewhere in your build process? You might want to make sure it references the correct variable. I tried to drop this in as a comment but it wouldn't fit:
//index.html (index.ejs) for me... This is in the main HTML entry point
var IPC = null;
try {
IPC = require('electron').ipcRenderer;
console.log('IPC IS: ' + IPC)
} catch (err) {
console.log('CRICITCAL ERROR: IPC NOT ENABLED')
console.log(err)
IPC = null;
}
Then I initialize off that context in React with a startup here:
setTimeout(()=>{
console.log('----------------HACK FIRED POST REHYDRATE')
window.REDUX_STORE.dispatch(
(dispatch, getState) => {
const _state = getState()
if(window.IPC) {
if(_state.osc && _state.osc.on) {
dispatch( reconnectToEos() )
} else {
dispatch( updateStatus('[OSC Startup: DISCONNECTED]', ))
}
console.log('\t------------ELECTRON')
} else {
//Shut off OSC
dispatch( updateOscKey('on', false) )
dispatch( updateStatus('[WebApp, OSC disabled]', ))
console.log('\t------------WEB')
}
}
)
}, 1000)
Basically I'm using a global variable (window.IPC) to initialize my app so I don't import a bad variable in my build process. I have a fair number of Electron APIs where this alleviates the issues with building via Webpack.
I hope this helps!

Vue local config file per App installation

I am new the Vue.js and I am trying first steps with an app. So for understanding the basics, I want a local config file per App installation to customise some needed variables in the code.
So in my main.js I tried the following:
import Vue from 'vue'
import App from './App.vue'
let config;
try {
config = require('../config.json');
} catch (e) {
config = require('../public/config.json');
}
Vue.config.productionTip = false;
Vue.prototype.$localConfig = config;
new Vue({
render: h => h(App)
}).$mount('#app');
This is working, until I build the production version with the dist folder. If I open the config.json in the root of the dist and change a property value, I see always the first defined values from the development env. So is webpack making there some caching? Is this at all the right way of handling such a local config file per App installation?
Maybe someone could give me some tips on this.
Doing config = require('../config.json'); is the same as import config from "../config.json" in a way that it takes the content of your json file at build time, transform it into JS object and make's it part of your app bundle.
You can do what you propose in a comment (include the file in a script tag in your index.html) but that means your app is doing additional request to the server to load the config and by doing so increasing "time to render" (time user have to wait until the page is fully rendered)
Most common way to handle app configuration in Vue/Webpack world is by using Environment Variables - those also "work" at build time tho so you need to build your app separately for each environment
let config
const configPromise =
process.env.NODE_ENV === 'development'
? import('../config.json')
: import('../public/config.json')
configPromise.then(res => {
config = res.default
})

How to refer other html file to load in production mode of application that are developed using electron?

I have problem in building electron application, which is made using electron.js and vue.js.
The development is almost done, so I need to build it and make production.
Basically, my project has license system, so when the program starts, users should activate it by entering license key. I wrote this part inside activate.html. So, inside public folder, there are two html files, one is default index.html, and the other is activate.html
Inside activate.html, when activation is success, startMain() javascript function is called. Inside this function, the program is navigated to main program, especially to index.html. This html file is Vue application, and then main program is started.
All this process is working fine in the development mode. But when it
comes to production, this is not working anymore. I probably know why this
happens, this is just because index.html is not available in
production mode when all these are built up.
Alternatively, I tried to load localhost:8080 inside
startMain(). But also this works fine in development mode, but unluckily, we don't have localhost server on production mode, so this
doesn't solve the problem.
This is startMain() inside activate.html
function startMain() {
window.__static = "index.html";
// Alternatively, we can use location.href on development mode.
// window.location.href = "http://localhost:8080/";
}
This is background.js ( electron main engine)
function createWindow() {
// Create the browser window.
win = new BrowserWindow({
width: 1400,
height: 900,
titleBarStyle: "hiddenInset"
});
win.setMenuBarVisibility(false);
if (isDevelopment) {
// Load the url of the dev server if in development mode
// win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
win.loadURL(`file://${process.cwd()}/public/activate.html`);
// if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol("app");
// Load the index.html when not in development
win.loadFile("activate.html");
}
win.on("closed", () => {
win = null;
});
}
What I want is to make it run correctly in production mode.
Specifically, when the user finishes activation flow ( activate.html),
it should start main program ( index.html )
Please help me with this issue. I welcome any comments.
I built this application using vue-cli-plugin-electron-builder package
In Vue usually you use vue-router to switch between views. You set the BrowserWindow.location the first time, in background.js, but after that you are in the Vue app and you make router calls like this:
router.replace({ name: "index" }).catch(() => { });
It's hard to guess what to do in your case, without seeing the rest of your activate.html. You need to define router in your App and probably want to convert your activate.html into an activate.vue component and make it the proper first page of your App.
I think the cli-plugin boilerplate will call main.js where you will define your app and bootstraps it. You add router there:
import router from "./router";
window.$app = new Vue({
router,
In your bootstrap function you can also call something like router.replace({ name: "activate"}) to start your app with your activate vue component.

React native require relative path file

I am trying React Native iOS and I was trying to setup project environments. I create a file called config.js so later I can just
import config from 'env'
to load the variables based on different environments. The following is the config.js file
let configFile = 'dev.js'
if (NODE_ENV === 'production') {
configFile = 'prod.js'
}
export default require('./env/' + configFile)
Somehow this won't work. the error message is:
Requiring unknown module "./env/dev.js". If you are sure the module is there, try restarting the packager or running "npm install"
When I changed my code to the following it would not give me errors. But it is not what I wanted to do.
export default require('./env/dev.js')
So does anyone know why is that?
Firstly, require calls are not dynamic. They are statically analyzed and bundled. So you would want something like this
let prodConfig = require('./env/prod.js');
let devConfig = require('./env/dev.js');
let config;
if (process.env.NODE_ENV === 'production') {
config = prodConfig;
}else {
config = devConfig;
}
export default config;