6

I am very new to the topic of Angular, Javascript etc.

I try to write a (TypeScript) Angular2-Electron application which should access the file-system. Everyone just says to require the "fs" module and all is fine, but that doesn't work for me... .

If I do something like: var fs = require('fs');

I can see that my app tries to load that "fs" module from my app root folder: ..myapp/dist/fs net::ERR_FILE_NOT_FOUND

All my other external modules are referenced in the index.html:

    <!-- build:js app/scripts/combined.js -->
    <script src="../node_modules/jquery/dist/jquery.js"></script>
    <script src="../node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="../node_modules/systemjs/dist/system.js"></script>
    <script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
    <script src="../node_modules/angular2/bundles/http.js"></script>
    <script src="../node_modules/angular2/bundles/router.js"></script>
    <script src="../node_modules/rxjs/bundles/Rx.js"></script>
    <script src="../node_modules/bootstrap/dist/js/bootstrap.js"></script>
    <script src="../node_modules/pdfjs-dist/build/pdf.combined.js"></script>
    <script src="boot.js" type="text/javascript"></script>
    <!-- endbuild -->

And therefore I think they could be found, but "fs" belongs to node.js which is present in electron? Or have I made some big mistakes in my thoughts?

Thanks a lot,
Chris

Peter David Carter
  • 2,548
  • 8
  • 25
  • 44
  • When you say it doesn't work what happens? When you try to access localhost in the browser (assuming you are serving to localhost) what occurs exactly? – Peter David Carter Apr 16 '16 at 11:54
  • The app work fine if i use a server (and not use any Includes for "fs"), but i compile my angular app with electron to create a desktop application. I thought that in an electron app the node-modules are already "present" but that don't seem to work. The Application try to load the "fs" module from my application folder as mentioned above. Have i to npm-install any additional depedencies to use the node-modules within my electron app? – Christian Jansik Apr 16 '16 at 12:34
  • Hhhhhmmmm, I found a question that could plausibly be related to the issue. Do the answers to http://stackoverflow.com/questions/30664111/how-to-use-node-modules-within-electron-formerly-atom-shell help you at all? – Peter David Carter Apr 16 '16 at 12:37
  • Not really. I already do imports from npm-modules in my application (such as angular2) which can be retrieved by electron without any problem because i add them to my final application path. As i understand correctly "fs" belongs to node.js and should be available. Or have i to install any additional modules like "npm install 'fs' --save" to use them in my app? All Tutorials just require "fs" without any words about adding additional dependencies – Christian Jansik Apr 16 '16 at 12:55

4 Answers4

5

The problems seems to be that i use SystemJS in my Angular Application. SystemJS tries to load the modules from my own application.

I now have add this so my index.html which seems to work:

    <script>
    if (require) {
        window.$ = window.jQuery = require('./app/assets/js/jquery.min.js');
        window.fs = require('fs');
        window.path = require('path');
    }
</script>
  • 1
    This works, though it feels odd to add any module to window in order to be able to use it. It feels like there must be another solution... – mvermand Dec 14 '16 at 12:57
  • @mvermand Had the same feeling and came up with IMHO a better approach. See my answer. – Monsignor Dec 27 '16 at 20:29
3

There is a github project I manage, which covers even more than just Angular 2 and electron (it also involves native libraries).
I encountered a lot of problems that are similar to yours, in particular the issue of accessing node.js modules from electron application.
Probably it's worth to use it as a starting point, instead of trying to write everything from scratch.

As for your problem, you should use System._nodeRequire('fs') instead of require('fs') as SystemJS lookup mechanism is a bit different than node's one.

JeB
  • 11,653
  • 10
  • 58
  • 87
2

Let me cite the meltedspark's answer to a similar question:

System.js overrides Node.js's require method and uses it's own resolution mechanism.

Here is my solution to this problem:

  1. Create re-exports for each Node.js module you want to use:

    // scripts/node-re-exports/fs.ts
    declare const System: any;
    const fs = System._nodeRequire('fs');
    export = fs;
    
    // scripts/node-re-exports/electron.ts
    declare const System: any;
    const electron = System._nodeRequire('electron');
    export = electron;
    
  2. Let systemjs.config.js know where to search for these re-exports.

    map: {
      ...
    
      // Re-exports of Node.js modules.
      fs: 'compiled/node-re-exports/fs.js',
      electron: 'compiled/node-re-exports/electron.js'
    }
    
  3. Import these modules in your Angular2 components, as usual:

    import { Component } from '@angular/core';
    import { clipboard } from 'electron';
    import { existsSync } from 'fs';
    
    @Component({
      selector: 'my-app',
      template: `<h1>Hello {{name}}</h1>`,
    })
    export class AppComponent {
      name = 'Angular';
    
      constructor() {
          const text = existsSync("c:\\boot.txt") ? "exists" : "does not exist";
          clipboard.write({ text: text });
      };
    }
    
Community
  • 1
  • 1
Monsignor
  • 2,671
  • 1
  • 36
  • 34
1

Using "fs" : "@node/fs" in the systemjs map you can solve the problem completely. Then you can import the native node modules as usual:

import {existsSync} from 'fs';

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
bcndns
  • 11
  • 2