Skip to content
This repository was archived by the owner on Nov 3, 2021. It is now read-only.
This repository was archived by the owner on Nov 3, 2021. It is now read-only.

Electric + Senna basePath resolve #146

Open

Description

@marceloavf

I'm implementing Electric with Electron to run it as desktop application, but I'm having some problems with basePaths. I'll describe the actual approach and the errors that occurs.

  • I'm using electron-webpack to build electron with dist folder after electric build finishes.
    package.json:
yarn electric build --env production && yarn compile && electron-builder --win
  • The env production handles the basePath of the application.
    electric.config.js:
envOptions: {
    production: {
      basePath: './',
    }
  },
  • Electron uses the dist path inside it's app.asar file to archive all electric pages
    main\index.js:
window.loadURL(formatUrl({
      pathname: path.join(__dirname, 'dist/index.html'),
      protocol: 'file',
      slashes: true
    }))

When I build electron with these configs the first page works normally, but when I try to navigate to some link these erros appears:

Senna initialized from data attribute.
Senna can't find route elements, adding default.

Navigate to [/C:/Users/Marcelo/AppData/Local/Programs/documentation/resources/app.asar/dist/docs/]

Create screen for [/C:/Users/Marcelo/AppData/Local/Programs/documentation/resources/app.asar/dist/docs/] [screen_1]

Screen [screen_1] beforeActivate

GET file:///C:/Users/Marcelo/AppData/Local/Programs/documentation/resources/app.asar/dist/docs/ net::ERR_FILE_NOT_FOUND

Navigation error for [screen_1] (Error: Request terminated prematurely)

The error appear even if I don't use .asar file, so I change the basePath to something that I could try to build latter passing the __dirname to it:

basePath: 'file:///C:/Users/Marcelo/AppData/Local/Programs/documentation/resources/app.asar/dist/'

Then all the links that points to specific .html works, but the links that goes to docs/ doesn't work.

Activity

  1. matuzalemsteles commented on Apr 12, 2018

    @matuzalemsteles
    Contributor

    Hey @marceloavf, First of all sorry for the delay.

    This is an interesting case, O senna.js was made to work with the browser, all parse logic in the URI is based on the browser, it makes an Ajax request to get the page and can handle it. This works great on the Web, but maybe this process does not make sense in an Electron application, since everyone is on localhost, it would be more interesting to have all the pages pushed into the final bundle for the Electron application and handle the routing on the Client side, would certainly have an enjoyable experience for the user.

    At the moment I would not recommend using it with Electron, I do not know if we will look at this now, but maybe we can improve this in the future, thanks for your feedback.

  2. marceloavf commented on Apr 12, 2018

    @marceloavf
    Author

    Hi @matuzalemsteles, Thank you for your response!

    The most important problem is that electric has a intern (package) webpack build and with Senna.js they work together for the web browser only. There is some tutorials of React building with electron with no eject that improves my vision about this situation.

    With that I was able to make it work only with specific point of electron instalation (not dynamic or user choice) and a Middleware component to persist the routes in browser and also in Electron.

    This is the main middleware code that make it work nicelly:

    app.on('beforeNavigate', middlewareClass.beforeNavigate);
    /**
       * Check before each navigation for bad URL and rework it.
       * Why? URL that doesn't have index.html at the end doesn't work with Electron
       * and others non-server hosts, and we need also to set basePath for links that
       * doesn't start with it, some of them are from internal packages of Electric
       * @param {any} e => Senna event handler
       * @memberof Middleware
       */
      beforeNavigate(e) {
        console.log('Check route:', e);
        const endsHashNumber = new RegExp("#\\d+$");
        const basePath = encodeURI(window.electric.data.site.basePath);
        if (!e.path.endsWith('.html')) {
          if (!endsHashNumber.test(e.path)) {
            e.path = e.path + 'index.html';
          }
        }
        if (basePath != "") {
          if (!e.path.startsWith(basePath)) {
            e.path = basePath + e.path.substr(3); // Include basePath and remove system initial base
          }
        }
      }

    In that case, I realize that not all routes have basePath included and no index.html href to properly get there.

    Now the final step is to make Electron talks with Senna/Electric to send IPC commands, get basePath dynamically based on where the user installed it and also get some remote options, I tried to do some tests by changing webpack target to electron-renderer but it messed up with Senna.js.

    Anyway, I'll continue searching for it and this could help someone else who try the same and in the future we can get a solution for that.

  3. matuzalemsteles commented on Apr 12, 2018

    @matuzalemsteles
    Contributor

    Awesome @marceloavf, Thanks for going deeper into the details.

    It really can be a problem for this case, but Electric was initially made thinking of generating static sites and focused on documentation at first glance. I'm not sure exactly what your case is about using it with Electron, maybe we can look at it in the future.

    But on IPC communication with Electron and Electric. Electric uses Metal.js which is quite similar to React, can you send a command from your window to the files compiled after the internal compilation of Electric easily?

    You could maybe use something like redux-electron-ipc. Because Electric compiles your application internally, you may not be able to find the electron package. Try to do a dynamic import in your Electric application of electron. To check if the package exists, do nothing, after being called on the main Electron can find. Maybe it helps to fool Electric internal compiler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions