nuxt-community / electron-template

Electron starter with nuxt.js
MIT License
251 stars 31 forks source link

Support for browser ? #7

Closed Kylart closed 7 years ago

Kylart commented 7 years ago

I am referring to #3 and #4 . Now I have this

// nuxt.config.js
...
build: {
    extend (config, {isClient}) {
      // Extend only webpack config for client-bundle
      if (isClient)
      {
        config.target = 'electron-renderer'
      }
    },
    vendor: ['vuetify', 'axios']
  },
...

And if I go to the _NUXT_URL_ in my browser, I get the common error that require is not defined and so my app doesn't do that much. Well, I am not that much of a front-end developper but isn't there any way to get this work in the browser too ? Maybe browserify or something would do the job ? The idea would be to have the app working when embed in electron and in the browser.

OR

Would it be possible to access process from store/index.js as it is supposed to be available for both main and renderer process ? (see here)

process seems to be undefined when called in this file.

It might not be possible though.

This question is available on Nuxt.js community (#c5)
detrohutt commented 7 years ago

Hmm.. I am not sure that's a typical use-case for electron. I believe if you'd want it accessible from the web and as a desktop app, you'd make two different projects -- one electron app, and one generic node/express app or similar.

As far as accessing process from store/index.js goes, maybe try adding this underneath your if block:

else
{
  config.target = 'electron-main'
}

Also, you may already have this in your config file as part of the ... but make sure you've got a plugins section next to build for vuetify.. see more info here.

Kylart commented 7 years ago

I don't think it is a typical use-case indeed. Still, I'd like to do it as it seems a really cool feature to add.

If I do this

else
{
  config.target = 'electron-main'
}

I get a warning from webpack saying that the target should be node and I can't access process from store/index.js (actually my app even has real problem to even start). If I put node as the target, I don't have the warning anymore and I can access a process object but it seems it is not the same object as in my main.js (maybe normal?) since if I do this:

// main.js
...
process.blabla = "Hello"
...
// store/index.js
console.log(process.blabla)

I don't get anything. Actually it even says that process is undefined even though if I just console.log(process), I have something.

Maybe it would help if I stated the problem I want to solve a little bit more? It can be put simply like this. I want to set a global object in main.js and access it from store/index.js without having to access any node module like os, fs, path and so on. A bit like what I stated before with process.

I don't know if it is clear enough but if this was possible, I could probably get rid of the config.build.extend thing and so my app would be ok for both electron and a browser.

Kylart commented 7 years ago

Ok so months after I ran into a possible solution to this issue in case people would google and happen to find this.

Electron is smart. So it shares the process.env with the window. Which means that this is possible:

// main.js
const app = require('electron').app
app.on('ready', () => {
  ...
  newWin()
  process.env.myVariable = 'is cool'
  ...
})

Then in store (maybe even in nuxtServerInit?) you can access this variable via window.process.env.myVariable // -> 'is cool'

alidcast commented 6 years ago

@Kylart This is prob late but I figured out how to get electron template to work for both a desktop and web app.

// process.env didn't work, so we export the configuration as a function 
// so that we can pass the `isElectron` boolean at build time
const resolve = require('path').resolve
module.exports = (isElectron) => ({
  // you'll be able to access these variables via `context.env` 
  env: {
    isDesktop: isElectron,
    isWeb: !isElectron
  },
  build: {
    extend (config, { dev, isClient }) {
      if (isElectron && isClient) config.target = 'electron-renderer'

      if (dev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }
})

Then create separate main files that'll serve as entry points for the electron desktop app or nuxt web app and load nuxt's config approriately inside them. For example:

module.exports = require('pathTo/nuxt.config.js')(false)

And for nuxt, if you don't want to use it programmatically, you can start the app by specifiying the entry file:

scripts: {
"dev": "cross-env nuxt dev --c pathToNuxtWebFile/index.js"
}
Kylart commented 6 years ago

Hey @alidcastano ! It's always interesting to see solutions 😄

I kinda like what you did there! Though if I understand it right (I did not test it yet), it seems that it works this way: When starting the application, you get to choose whether you want to launch your app in the desktop or in the browser. I might have understood it the wrong way though.

What I actually meant was something that would answer this use case:

  1. I start my electron app (in the desktop)
  2. I click a button in it
  3. It opens the same app in the browser

So one instances: both desktop and browser are working. No need for a restart. I can agree this is definitely not a typical use-case for an electron app but I feel like it is really cool.

alidcast commented 6 years ago

Well you'd likely need to have the app running both in the browser and desktop - two separate instances - but you can keep the windows in sync via local storage. This plugin - vuex-shared-mutations https://github.com/xanf/vuex-shared-mutations - might be helpful

Kylart commented 6 years ago

It's true sync is a big problem, from what I have it feels like two instances with nothing but the structure in common. Just like if I had two different applications 😄

I'll actually give a try to this plugin for sure!