electron-userland / electron-compile

DEPRECATED: Electron supporting package to compile JS and CSS in Electron applications
1.01k stars 99 forks source link

Strange Vue Component Compilation Issue #296

Closed RichFromGalvanize closed 6 years ago

RichFromGalvanize commented 6 years ago

So, I ran into a strange issue where my component is being compiled fine on Mac but on Windows it doesn't seem to be compiled. I have googled, tried a bunch of different things (sane and insane), and looked at the debug output. Everything points to it should be compiling but it isn't. The strangest part to me is that using import in the main JS file seems to work, but using require doesn't.

Before I start listing files, keep in mind I have some complex requirements, but please remember that this all works 100% on my Mac, so it has to be something with Mac vs Windows.

Anyway, here are some file/code dumps.

Package.json

{
  "main": "startup.js",
  "scripts": {
    "start": "electron .",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Richard Key <rich@busyrich.com>",
  "license": "ISC",
  "dependencies": {
    "lodash": "^4.17.5",
    "mongodb": "^3.0.4",
    "request": "^2.85.0",
    "vue": "^2.5.16",
    "vueify": "^9.4.1"
  },
  "devDependencies": {
    "babel-preset-es2015-script": "^1.1.0",
    "electron-prebuilt-compile": "^1.8.4"
  }
}

I give you my word that startup.js is just a basic "create window and go" startup for electron. Nothing special in there.

.compilerc

{
  "application/javascript": {
    "ignore": ["lib/**", "plugins/**/!(ui)"],
    "presets": [["env", {
      "targets": {
        "chrome": "60"
      }
    }]]
  }
}

I have tried removing stuff from the ignore, changing the slash directions (I know that doesn't do anything and will not work, but I was desperate), and I tried changing the presets a bit. This seems to work great on my Macbook as is.

commands.vue

<template>
  <div id="commands">
    <h1>This is commands!!!!!</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {something: 'dude'};
  }
}
</script>

<style lang="scss" scoped>
</style>

Fairly basic and empty view. In order to get the compiler to compile on the Mac, I HAD to put something in the export defaults. Having it with just export default {} didn't work, got the same error.

Offending line

Vue.component('commands', require(absoluteFilePath));

I understand more context would be great for some, but its not really necessary here. I need to load some components dynamically and this was the only way I could get it to work when working on my Macbook (I tried pretty much everything else outlined in the Vue documentation for async and dynamic component loading). I have other components (non-dynamic paths) being loaded via the import command/keyword in the same file as this line and those work just fine. Comment out this line and it loads up and starts working, just without the other component of course.

Trying to load up this stuff on Windows gives me "Uncaught SyntaxError: Unexpected token export", which means the component was not compiled and electron's webkit flips out. It is also not listed with the other compiled files in the sources tab in the dev tools inside the electron window. The debugger does how that it runs through the paces of trying to compile it, but the output does not say whether it passed the "ignore" check or not, so its hard to be sure if the underlying vueify/babel ACTUALLY compiled it.

Debug output for file in question (blah = full path to the project)

electron-compile:compiler-host Compiling blah\plugins\simple_command\ui\commands.vue +35ms
blah\node_modules\debug\src\browser.js:123 electron-compile:sanitize-paths Cache miss for cachedRealpath: 'blah\plugins\simple_command\ui\commands.vue' => 'blah\plugins\simple_command\ui\commands.vue' +1ms
blah\node_modules\debug\src\browser.js:123 electron-compile:file-change-cache Cache entry for blah/plugins/simple_command/ui/commands.vue: {"ctime":1522957263531,"size":212,"info":{"hash":"a3ec17a5a7838af34927e450d7b0409d99b24d39","isMinified":false,"isInNodeModules":false,"hasSourceMap":false,"isFileBinary":false}} +0ms
blah\node_modules\debug\src\browser.js:123 electron-compile:compile-cache Fetching blah\plugins\simple_command\ui\commands.vue from cache +0ms

As I mentioned, this debug output is pretty much identical compared to my other components, minus the path in which the component lives and how it is loaded in code.

I should note I have spent many hours getting this all to work together properly, so I have read a lot of the Vue documentation, a bunch of issues on this repo (for various reasons), and a metric crapton of stack overflow threads. I may just have to start looking the the source code here to see if I can piece together how it determines what to compile and what to not, and how it may differ per OS.

The main issue I have had is that there is very little on how electron compile pieces together all its internals to provide the compilation of files. I admit this part is fairly new to me as far as babel and vueify, but otherwise I am starting to get a handle on how Vue works itself. I believe I have done my due diligence in terms of making sure I am organizing everything and using the write methods to accomplish the things I want to do. I try not to use "hacks" or just force things into place.

So strange issue here and I am going to keep on looking and looking. I am convinced it has to be something with how electron compile's require hook works somehow, but you never know. If you have any advice please feel free to toss it at me.

RichFromGalvanize commented 6 years ago

I did have someone try the code on a Macbook Air and they seemed to have run into the same issue. I am not 100% sure if its related yet, but just wanted to note there is a chance this is not related to the OS as I first thought. Will keep this ticket updated as I try more things.

RichFromGalvanize commented 6 years ago

Alright, after a lot of thought and some more googling, I came up with this workaround:

<script>
module.exports = {

}
</script>

That seems to work a lot better than using export, in several cases actually. I know its not the standard way to do things in Vue components, but for now this fixes some strange issues for me and I am going to use it.

I am still convinced there is something fishy going on with the require hook and the compiling logic internally, but with different computers doing different things its hard to pin down an exact cause. I am going to close this out and hopefully this helps someone down the road.