Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Electron, Angular2, "fs"

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

like image 576
Christian Jansik Avatar asked Apr 16 '16 11:04

Christian Jansik


4 Answers

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>
like image 96
Christian Jansik Avatar answered Nov 19 '22 00:11

Christian Jansik


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.

like image 40
JeB Avatar answered Nov 19 '22 00:11

JeB


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 });
      };
    }
    
like image 2
Monsignor Avatar answered Nov 19 '22 01:11

Monsignor


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';

like image 1
bcndns Avatar answered Nov 18 '22 23:11

bcndns