Skip to content
This repository has been archived by the owner on Jun 1, 2022. It is now read-only.

Accessing Node core modules from within an Aurelia Electron App #537

Closed
seesharper opened this issue Jun 24, 2016 · 20 comments
Closed

Accessing Node core modules from within an Aurelia Electron App #537

seesharper opened this issue Jun 24, 2016 · 20 comments
Labels

Comments

@seesharper
Copy link

seesharper commented Jun 24, 2016

I am doing a little experiment with using Aurelia to build Electron applications.

You can find what I have got so far here.
https://github.com/seesharper/AureliaElectronHappiness

The question is how do I access core modules such as "fs" from within a typescript component?

I have tried this

import fs = require("fs");

VS Code does give the impression that this is okay since it provides the intellisense for the fs object, but at runtime this failes with an error.

Uncaught (in promise) Error: (SystemJS) Error: XHR error loading file:///Users/bernhardrichter/MyApp/dist/fs.js(…) 

Is it even possible to do this somehow?

@niieani
Copy link
Contributor

niieani commented Jun 24, 2016

import * as fs from 'fs';

Also, you might need to configure JSPM to declare 'fs' as external. Not sure how that's done with JSPM. You also need to enable nodeIntegration with Electron too.

@EisenbergEffect
Copy link
Contributor

EisenbergEffect commented Jun 24, 2016

In the past, I actually wrote a custom loader for jspm like this:

System.set('npm', System.newModule({
  'fetch': function(load, fetch) {
    var id = load.name.substring(0, load.name.indexOf('!'));
    load.metadata.requiredModule = require(id);
    return '';
  },
  'instantiate':function(load) {
    return load.metadata.requiredModule;
  }
}));

I just put this code in my main.js. Then I would do something like this whenever I needed a node module:

import * as fs from 'fs!npm';

@niieani
Copy link
Contributor

niieani commented Jun 24, 2016

The problem with your approach Rob is lack of TS typing in such a case. One
would need to declare a 'fs!npm' module manually. Webpack solves this
better as you can provide a list of packages that shouldn't be bundled,
perhaps, Bernhard, you could wait until I get the Electron implementation
into the Webpack skeletons (I use it locally and it works great).
On Fri, 24 Jun 2016 at 15:42, Rob Eisenberg notifications@github.com
wrote:

In the past, I actually wrote a custom loader for jspm like this:

System.set('npm', System.newModule({
'fetch': function(load, fetch) {
var id = load.name.substring(0, load.name.indexOf('!'));
load.metadata.requiredModule = require(id);
return '';
},
'instantiate':function(load) {
return load.metadata.requiredModule;
}
}));

I just put this code in my main.js. Then I would do something like this
whenever I needed a node module:

import * as fs from 'fs!npm';


You are receiving this because you commented.

Reply to this email directly, view it on GitHub
#537 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AAiZDaVlaajssi7xrURiGFYJ3wcI__P7ks5qO97FgaJpZM4I9uzd
.

@EisenbergEffect
Copy link
Contributor

EisenbergEffect commented Jun 24, 2016

Sure, of course...he wasn't asking about Webpack though. The above solution works fine for SystemJS. There may be another way to handle it with SystemJS, I'm not sure. I would ask the SystemJS team about that. It certainly would be better if there was a way to tell it to use the native require for certain modules. I'd like to know the answer to that myself.

@seesharper
Copy link
Author

That would be great. Accessing the file system would be a great example for the Aurelia/Electron skeleton since that is probably the first thing you would want to do in a desktop app :)

@seesharper
Copy link
Author

Discussed in this issue.

systemjs/systemjs#124

"If you're referring to the original question, Node core modules can now be imported with import {readFile} from '@node/fs', but that will only work in Node environments of course."

That did not work for me though :(

@seesharper
Copy link
Author

This is also maybe something to consider with regards to the Aurelia CLI.

@seesharper
Copy link
Author

FYI, I just tried the solution suggested by @EisenbergEffect

JSPM version 0.16.39

undefined:1 Uncaught (in promise) Error: (SystemJS) Error: XHR error loading file:///Users/bernhardrichter/Projects/MyProject/dist/npm.js(…)

Further help on this issue would be much appreciated

@seesharper
Copy link
Author

One step closer to success.

import {readdirSync} from '@node/fs';

This actually works at runtime, but vs code is not able to figure out the module so that means no intellisense. Anybody knows how to trick typescript/vscode into resolving '@node/fs' ?

@niieani
Copy link
Contributor

niieani commented Jun 27, 2016

@seesharper here's how you can do it: microsoft/TypeScript#6615
Note that this is a TypeScript 2.0 feature, but if you're using the latest skeleton, you should already have TypeScript 1.9-dev which is the prerelease of TS 2.0.

@seesharper
Copy link
Author

Nice, I will check it out

@seesharper
Copy link
Author

I can't figure out exactly what I need to do here. Could you point me in the right direction with an example?

@niieani
Copy link
Contributor

niieani commented Jun 27, 2016

If all you need is 'fs' you can just create an alias for it.

custom_typings/fs.d.ts:

declare module "@node/fs" {
    import * as fs from 'fs';
    export = fs;
}

this should work even with TS 1.8.
(haven't actually tested the code, but I'd imagine it should work...)

You'll obviously need the typings for node for this to work.

@seesharper
Copy link
Author

Worked like a charm. Thanks a lot for your help!!!!

@lu4
Copy link

lu4 commented Sep 2, 2016

@niieani TypeScript 2.0 goes away from notion of typings, they've introduced types that are installed via npm. You get @types folder in node_modules which contain all the necessary type information. The types are automatically loaded from @types folder. The problem with SystemJS remains in this regard, IDE looses track of type information if @node is concatenated as prefix to my core nodejs module like fs. So it would be nice to be able to specify that fs is a @node related package within System.configure({ packages: { ... } }) property.

@lu4
Copy link

lu4 commented Sep 2, 2016

On the other hand I've found a workaround for the above problem, it seems that you can kind of "map" fs and other standard node modules into @node/... like so:

SystemJS.config({
    transpiler: 'typescript',
    map: {
        "console": "@node/console",
        "buffer": "@node/buffer",
        "querystring": "@node/querystring",
        "events": "@node/events",
        "http": "@node/http",
        "cluster": "@node/cluster",
        "zlib": "@node/zlib",
        "os": "@node/os",
        "https": "@node/https",
        "punycode": "@node/punycode",
        "repl": "@node/repl",
        "readline": "@node/readline",
        "vm": "@node/vm",
        "child_process": "@node/child_process",
        "url": "@node/url",
        "dns": "@node/dns",
        "net": "@node/net",
        "dgram": "@node/dgram",
        "fs": "@node/fs",
        "path": "@node/path",
        "string_decoder": "@node/string_decoder",
        "tls": "@node/tls",
        "crypto": "@node/crypto",
        "stream": "@node/stream",
        "util": "@node/util",
        "assert": "@node/assert",
        "tty": "@node/tty",
        "domain": "@node/domain",
        "constants": "@node/constants",
    },
    paths: {
        'typescript': './node_modules/typescript',
    },
    packages: {
        'typescript': {
            main: 'lib/typescript'
        },
    }
});

@niieani
Copy link
Contributor

niieani commented Sep 2, 2016

@lu4 cool workaround. Note that the notion of typings does not go away as you stated. What changes is the tooling for installing typings - in favor of NPM in the @types scope.

@lu4
Copy link

lu4 commented Sep 2, 2016

Thanks, yeah probably that's a better way to express the change... :)

@mskutle
Copy link

mskutle commented Jan 5, 2017

I'm struggling with the same problem, but none of the solutions above have worked for me. I have mapped fs to "@node/fs" in my Systemjs config file, but I get this error when trying to use "fs" in my app:

import fs from 'fs'

aurelia-logging-console.js:54 ERROR [app-router] Error: (SystemJS) Error loading @node/fs. Can only load node core modules in Node.

@davidquinn
Copy link

@mskutle try:

Assuming you have the following in your System JS config:

System.config({
	...
	map: {
		...
		'fs': '@node/fs',
		...
	},
	...
});

Then use require rather than import in your js/ts file:

const fs = require('fs');

HTH.
D

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

6 participants