how can I use electron apis



  • After I use the wrap, i can work out an desktop app. But when I use import {remote} from “electron”, error pop up for not find electron module.


  • Admin

    You need a deep integration of Electron. But this will break websites/mobile app build though (as importing electron in a browser or mobile app will fail), so you’d need two repos: one for electron and one for websites/mobile apps.

    How to do deep integration:

    1. In root folder of your project, npm install electron
    2. In /build/webpack.base.conf.js add target: 'electron-main' target: 'electron-renderer' to exported object
    3. In electron wrapper folder (/electron) add target: 'electron-renderer' target: 'electron-main' to /electron/build/webpack.conf.js exported object

    Edited: targets must be actually swapped. renderer for root webpack and main for electron folder.



  • Hi @rstoenescu ,
    I am trying the Electron integration, but I have the same problem than @vampirefan (i.e., trying to require ‘electron’ from the app doesn’t work).
    The solution you provided doesn’t work for me, I now have a white screen both on the web app and in the Electron app (both running with quasar dev).

    Could you please take a look at that? At the moment, Electron is not usable with Quasar… thanks! 🙂



  • Just noticed there is an error in the console:

    [vue-router] Failed to resolve async component default: Error: ENOENT, renderer/js/1.60d2ce35b6fa95fc1fc2.js not found in /home/.../electron/node_modules/electron/dist/resources/electron.asar
    

  • Admin

    @Michele-Angioni Any repo I can take a look? You might have misinterpreted part of the instructions.



  • @rstoenescu unfortunately I cannot open source the repo immediately, but being a quite new project I could setup a completely new Repo on github with simple configuration.

    Quickest thing, I post here the files:

    # package.json
    {
      "scripts": {
        "clean": "node build/script.clean.js",
        "dev": "node build/script.dev.js",
        "build": "node build/script.build.js",
        "lint": "eslint --ext .js,.vue src"
      },
      "dependencies": {
        "babel-runtime": "^6.0.0",
        "fastclick": "^1.0.6",
        "material-design-icons": "^3.0.1",
        "moment": "^2.15.0",
        "node-sass": "^4.5.1",
        "noty": "^2.4.1",
        "quasar-framework": "^0.13.4",
        "roboto-fontface": "^0.7.0",
        "sass-loader": "^6.0.3",
        "sweetalert": "^1.1.3",
        "vue": "^2.2.2",
        "vue-router": "^2.0.0"
      },
      "devDependencies": {
        "autoprefixer": "^6.4.0",
        "babel-core": "^6.0.0",
        "babel-eslint": "^7.0.0",
        "babel-loader": "^6.0.0",
        "babel-plugin-transform-runtime": "^6.0.0",
        "babel-preset-es2015": "^6.0.0",
        "babel-preset-stage-2": "^6.0.0",
        "colors": "^1.1.2",
        "connect-history-api-fallback": "^1.1.0",
        "css-loader": "^0.26.0",
        "electron": "^1.5.0",
        "eslint": "^3.0.1",
        "eslint-config-standard": "^6.2.0",
        "eslint-friendly-formatter": "^2.0.5",
        "eslint-loader": "^1.3.0",
        "eslint-plugin-html": "^2.0.1",
        "eslint-plugin-promise": "^3.3.0",
        "eslint-plugin-standard": "^2.0.0",
        "eventsource-polyfill": "^0.9.6",
        "express": "^4.13.3",
        "extract-text-webpack-plugin": "^2.0.0-beta.4",
        "file-loader": "^0.10.0",
        "friendly-errors-webpack-plugin": "^1.1.3",
        "html-webpack-plugin": "^2.8.1",
        "http-proxy-middleware": "^0.17.0",
        "json-loader": "^0.5.4",
        "opn": "^4.0.2",
        "postcss-loader": "^1.0.0",
        "progress-bar-webpack-plugin": "^1.9.0",
        "shelljs": "^0.7.0",
        "stylus": "^0.54.5",
        "stylus-loader": "^2.1.1",
        "url-loader": "^0.5.7",
        "vue-loader": "11.1.4",
        "vue-style-loader": "^2.0.0",
        "vue-template-compiler": "^2.2.2",
        "webpack": "^2.2.1",
        "webpack-dev-middleware": "^1.8.4",
        "webpack-hot-middleware": "^2.17.0",
        "webpack-merge": "^4.0.0"
      }
    }
    
    
    # build/webpack.base.conf.js
    
    var
      path = require('path'),
      webpack = require('webpack'),
      config = require('../config'),
      cssUtils = require('./css-utils'),
      env = require('./env-utils'),
      merge = require('webpack-merge'),
      projectRoot = path.resolve(__dirname, '../'),
      ProgressBarPlugin = require('progress-bar-webpack-plugin'),
      useCssSourceMap =
        (env.dev && config.dev.cssSourceMap) ||
        (env.prod && config.build.productionSourceMap)
    
    function resolve (dir) {
      return path.join(__dirname, '..', dir)
    }
    
    module.exports = {
      target: 'electron-main', // Added to integrate deep with Electron
      entry: {
        app: './src/main.js'
      },
      output: {
        path: path.resolve(__dirname, '../dist'),
        publicPath: config[env.prod ? 'build' : 'dev'].publicPath,
        filename: 'js/[name].js',
        chunkFilename: 'js/[id].[chunkhash].js'
      },
      resolve: {
        extensions: ['.js', '.vue', '.json'],
        modules: [
          resolve('src'),
          resolve('node_modules')
        ],
        alias: config.aliases
      },
      module: {
        rules: [
          { // eslint
            enforce: 'pre',
            test: /\.(vue|js)$/,
            loader: 'eslint-loader',
            include: projectRoot,
            exclude: /node_modules/,
            options: {
              formatter: require('eslint-friendly-formatter')
            }
          },
          {
            test: /\.js$/,
            loader: 'babel-loader',
            include: projectRoot,
            exclude: /node_modules/
          },
          {
            test: /\.vue$/,
            loader: 'vue-loader',
            options: {
              postcss: cssUtils.postcss,
              loaders: merge({js: 'babel-loader'}, cssUtils.styleLoaders({
                sourceMap: useCssSourceMap,
                extract: env.prod
              }))
            }
          },
          {
            test: /\.json$/,
            loader: 'json-loader'
          },
          {
            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
            loader: 'url-loader',
            options: {
              limit: 10000,
              name: 'img/[name].[hash:7].[ext]'
            }
          },
          {
            test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
            loader: 'url-loader',
            options: {
              limit: 10000,
              name: 'fonts/[name].[hash:7].[ext]'
            }
          }
        ]
      },
      plugins: [
        /*
          Take note!
          Uncomment if you wish to load only one Moment locale:
    
          new webpack.ContextReplacementPlugin(/moment[\/\]locale$/, /en/),
        */
    
        new webpack.DefinePlugin({
          'process.env': config[env.prod ? 'build' : 'dev'].env,
          'DEV': env.dev,
          'PROD': env.prod,
          '__THEME': '"' + env.platform.theme + '"'
        }),
        new webpack.LoaderOptionsPlugin({
          minimize: env.prod,
          options: {
            context: path.resolve(__dirname, '../src'),
            postcss: cssUtils.postcss
          }
        }),
        new ProgressBarPlugin({
          format: config.progressFormat
        })
      ],
      performance: {
        hints: false
      }
    }
    
    # electron/build/webpack.conf.js
    
    var
      path = require('path'),
      webpack = require('webpack'),
      config = require('../config/webpack'),
      merge = require('webpack-merge'),
      ProgressBarPlugin = require('progress-bar-webpack-plugin')
    
    function resolve (dir) {
      return path.join(__dirname, '..', dir)
    }
    
    var folders = {
      src: resolve('src'),
      node_modules: resolve('node_modules'),
      dist: resolve('dist')
    }
    
    module.exports = {
      target: 'electron-renderer', // Added to integrate deep with Electron, it was 'node'
      entry: {
        app: './src/main.js'
      },
      externals: config.externals,
      output: {
        filename: 'electron.js',
        libraryTarget: 'commonjs2',
        path: folders.dist
      },
      resolve: {
        extensions: ['.js', '.json', '.node'],
        modules: [
          folders.src,
          folders.node_modules
        ]
      },
      node: {
        __dirname: false,
        __filename: false
      },
      module: {
        rules: [
          { // eslint
            enforce: 'pre',
            test: /\.js$/,
            loader: 'eslint-loader',
            include: folders.src,
            exclude: /node_modules/,
            options: {
              formatter: require('eslint-friendly-formatter')
            }
          },
          {
            test: /\.js$/,
            loader: 'babel-loader',
            include: folders.src,
            exclude: /node_modules/
          },
          {
            test: /\.json$/,
            loader: 'json-loader'
          },
          {
            test: /\.node$/,
            loader: 'node-loader'
          }
        ]
      },
      plugins: [
        new webpack.DefinePlugin({
          'process.env': config.env
        }),
        new webpack.LoaderOptionsPlugin({
          minimize: true
        }),
        // Progress Bar Webpack plugin format
        // https://github.com/clessg/progress-bar-webpack-plugin#options
        new ProgressBarPlugin({
          format: ' [:bar] ' + ':percent'.bold + ' (:msg)'
        }),
        new webpack.optimize.UglifyJsPlugin({
          minimize: true,
          compress: {
            warnings: false
          }
        })
      ],
      performance: {
        hints: false
      }
    }
    

    If you don’t find anything strange or wrong, I’ll try to set up a repo in Github



  • @rstoenescu I setup a Github repo: https://github.com/micheleangioni/quasarelectron

    In the readme I listed all the steps to reproduce the problem.
    The error I get is still

    (unknown) [vue-router] Failed to resolve async component default: Error: ENOENT, renderer/js/0.7b876bd774964b0640b6.js not found in /home/.../quasarelectron/electron/node_modules/electron/dist/resources/electron.asar
    

    Let me know if I can help you further 🙂



  • Hi @rstoenescu ,
    I’m sorry to make pressure on you, but have you taken a look at it or do you plan to do it in the next days?

    Really thanks!



  • Actually webpack targets have to been swapped, so electron-renderer should be add to root’s webpack, while electron-main to electron wrapper.



  • Also, remember that in Vue components, you’re on renderer process, so you have to invoke Electron features using remote module.

    I forked your repo and fixed with a little integration demo. I will send you a PR



  • Great @zuck , it seems it’s working! Thanks 🙂
    I still get

    Attempted to load extension "devtron" that has already been loaded.
    

    on the electron quasar dev console, but it’s not crashing anymore. I also pushed the fix to the Github repo.
    I’ll keep working, I’ll let you know whether other problems arise.

    @rstoenescu maybe you should document this “deep integration” in the documentation itself, because everyone that wants to use the Electron wrapper, is going to need this. I mean that without this deep integration, the current Electron wrapper isn’t really useful.
    Btw, thanks again for the effort you are putting on in!



  • Perfect @zuck , I merged it!
    I also MIT licensed it, it’s the minimum I can do.

    Just an idea: quasar-cli could have a quasar init --electron option to create such a “deep integration” out of the box.
    I’m absolutely available to move ownership of this repo to Quasar if needed.


  • Admin

    The plan is to create a starter kit specifically for deep Electron integration after v0.14 is released.



  • Nice idea 👍



  • hey guys you’ve saved my day!
    found an interesting article focusing on webpack targets for electron https://medium.com/@ad_harmonium/build-to-both-electron-js-and-browser-targets-using-webpack-59266bdb76a



  • “The plan is to create a starter kit specifically for deep Electron integration after v0.14 is released.”

    That’ll be Day 1 of my awaited Quasar career… ;-)…

    While I’m waiting… for the happy day ;-)… I’m building app ideas courtesy of Electron Vue (https://github.com/SimulatedGREG/electron-vue)…



  • I too would love to see the deep integration starter kit.

    In the meantime, it would be great to include a short blurb about this distinction (deep integration vs. not) in the Electron section so that people can be aware of it going in.


Log in to reply
 

Looks like your connection to Quasar Framework was lost, please wait while we try to reconnect.