rwaldron / johnny-five

JavaScript Robotics and IoT programming framework, developed at Bocoup.
http://johnny-five.io
Other
13.26k stars 1.76k forks source link

TypeError: fs_1.readFileSync is not a function #1415

Closed TheLLspectre closed 6 years ago

TheLLspectre commented 6 years ago

Hi everyone,

I work on TypeScript, I have this really strange error:

TypeError: fs_1.readFileSync is not a function at Object. (http://localhost:8100/build/main.js:145023:21) at Object.module.exports (http://localhost:8100/build/main.js:145112:30) at webpack_require (http://localhost:8100/build/main.js:20:30) at new RaspiIO (http://localhost:8100/build/main.js:149954:15) at Object. (http://localhost:8100/build/main.js:44283:9) at webpack_require (http://localhost:8100/build/main.js:20:30) at Object. (http://localhost:8100/build/main.js:87931:75) at webpack_require (http://localhost:8100/build/main.js:20:30) at Object. (http://localhost:8100/build/main.js:87860:73) at webpack_require (http://localhost:8100/build/main.js:20:30)

this error come with this code:

import five from 'johnny-five'; import Raspi from 'raspi-io'; import { debounce } from 'lodash.debounce'; const board = new five.Board({ io: new Raspi() });

I fixed differents problems on my project, but this one i don't know. Someone asked: if i installed it as user, and if i run it as root user, may be this is why i've this error! What do you think ??

If it's that how i can do this ? Because i'm on Microsoft Visual Studio 2017, on windows 10 of course, and with console of MVS it's impossible (i think), to use as root ...

fivdi commented 6 years ago

I'm not sure what the goal is here but it sounds like you would like to install raspi-io on a Windows machine. Is this correct? If so, I'm fairly certain that it's not going to work. raspi-io and some of the native modules that it depends on can only be successfully installed on Linux machines and in some cases only on the Raspberry Pi.

TheLLspectre commented 6 years ago

Yeah that it ! i work on windows, i want to make every functionnality and at the end, put the solution in the raspberry... It was impossible to download raspi-io on windows so i download it on the raspberry and i put it in the node_module folder

So i think too, to develop on windows on rasapberry make some problems, so can in develop on Linux and put the solution on raspberry ??? or i need to work directly on the raspberry ?

fivdi commented 6 years ago

I'm afraid I'm not familiar with what's needed to develop the way you would like to develop. Maybe @nebrius can provide more information.

What I usually do is edit on one Linux machine and then copy everything over to the Raspberry Pi for testing.

TheLLspectre commented 6 years ago

Ok ! Thanks! I just expect he can find a solution to my problem ... i'm waiting for him :)

TheLLspectre commented 6 years ago

It's really interresting, i make my project on Linux machine and now, he doesn't want to download raspi-io, so i think it's not the good one, i mean may be i need to work with 'raspi' only ??

EDIT: Absolutly not, it's only about the OS :

npm ERR! notsup Unsupported platform for raspi-io@8.1.0: wanted {"os":"any","arch":"arm"} (current: {"os":"linux","arch":"x64"})

fivdi commented 6 years ago

Don't install raspi-io on the Linux machine. Only add it as a dependency in package.json. Then copy the project to the Raspberry Pi and call npm i in the project directory on the Pi to install everything there only.

TheLLspectre commented 6 years ago

Ok so something like this ??

"dependencies": { "@angular/common": "5.0.1", "@angular/compiler": "5.0.1", "@angular/compiler-cli": "5.0.1", "@angular/core": "5.0.1", "@angular/forms": "5.0.1", "@angular/http": "5.0.1", "@angular/platform-browser": "5.0.1", "@angular/platform-browser-dynamic": "5.0.1", "@ionic-native/core": "4.4.0", "@ionic-native/splash-screen": "4.4.0", "@ionic-native/status-bar": "4.4.0", "@ionic/storage": "2.1.3", "ionic-angular": "3.9.2", "ionicons": "3.0.0", "johnny-five": "^0.11.7", "repl": "^0.1.3", "rxjs": "5.5.2", "sw-toolbox": "3.6.0", "zone.js": "0.8.18", "raspi-io":"8.1.0" },

also for the version.

That's mean, i need to recompile all the project on the raspberry ???? :O

fivdi commented 6 years ago

That looks very unusual to me.

I don't know what the following is for:

"": "5.0.1",
"": "5.0.1",
"": "5.0.1",
"": "5.0.1",
"": "5.0.1",
"": "5.0.1",
"": "5.0.1",
"": "5.0.1",
"": "4.4.0",
"": "4.4.0",
"": "4.4.0",
"": "2.1.3",

Something like this is needed:

"johnny-five": "^0.11.7",
"raspi-io":"8.1.0"

But this might be better:

"johnny-five": "^0.11.7",
"raspi-io":"^8.1.0"

I don't know about the rest because I don't know what you would like your application to do.

That's mean, i need to recompile all the project on the raspberry ???? :O

Not recompile, only compile with npm i

nebrius commented 6 years ago

Several of the dependencies in Raspi IO have installation scripts that can only be run on a Raspberry Pi, which is why we have the OS and CPU arch limitations in package.json. Otherwise, the errors are a lot more cryptic. As a result, there is no way to install this module on Windows (or macOS, or Linux on an x86 machine, etc, etc).

As it turns out, almost all of Raspi IO is written in TypeScript, although two of the top-level modules haven't been converted yet so it's not going to be obvious to users (yet), which means I deal with this problem regularly.

I get around this by carefully splitting my dependencies into dependencies and devDependencies. Everything needed to build the source code is in devDependencies, but all of the Raspberry Pi specific dependencies are set as dependencies. Then, when it's time to install dependencies on my laptop, I run npm install --only=dev which will skip over the Raspberry Pi specific dependencies and avoid the CPU/OS limitations. Then, when it's time to run the code on the Raspberry Pi, I switch it and run npm install --only=prod.

nebrius commented 6 years ago

Alllll of that said, going back to your original error:

TypeError: fs_1.readFileSync is not a function at Object. (http://localhost:8100/build/main.js:145023:21) at Object.module.exports (http://localhost:8100/build/main.js:145112:30) at webpack_require (http://localhost:8100/build/main.js:20:30) at new RaspiIO (http://localhost:8100/build/main.js:149954:15) at Object. (http://localhost:8100/build/main.js:44283:9) at webpack_require (http://localhost:8100/build/main.js:20:30) at Object. (http://localhost:8100/build/main.js:87931:75) at webpack_require (http://localhost:8100/build/main.js:20:30) at Object. (http://localhost:8100/build/main.js:87860:73) at webpack_require (http://localhost:8100/build/main.js:20:30)

Two things:

  1. fs_1.readFileSync is not a function: This isn't related to Johnny-Five, but it's bizarre. It looks like there was a bug in the TypeScript compilation of your module itself, aka a bug in the TypeScript compiler. For an example of how this should look, take a look at the compiled output of raspi-led (part of Raspi IO) here and here which has the exact same code. This is related to the fs module that is built into Node.js itself.
  2. It looks like you're using webpack to build your code, is this correct? If so, are you trying to run this code in a browser? This scenario is not supported unfortunately. If not, is there a reason you're using webpack instead of TypeScript directly?
TheLLspectre commented 6 years ago

Ok those help me a lot !

I use webpack, because this is inside a Ionic project, and i want to make an app embedded in the raspberry, and now is the webpack which make problems, with the child_process...

nebrius commented 6 years ago

I'm not familiar with the Ionic framework, but a quick glance it seems to be similar to PhoneGap, right? If so, that means it's running a web browser for the UI, and Raspi IO won't work in that environment because Raspi IO must be run inside of Node.js, not a web browser.

Do you need the UI component of Ionic? If not, can you run the project directly in Node.js?

TheLLspectre commented 6 years ago

Yeah it's look like the same as PhoneGap.

And yes i need the UI from Ionic... so .... :/

nebrius commented 6 years ago

Maybe you could create two separate apps? One is a server running in Node.js that contains all of the Johnny-Five code, and the other is the Ionic app, and you could create a REST API between them?

TheLLspectre commented 6 years ago

Yeah I think to this possibilitie from the beginning, but I don't sure about how to do.... because my raspberry have an Apache Php server on, for the ionic app, i can make something interresting just in user size and not in the server size, and i never wrote an API before...

Do you have some advice for this solution, i think i'm going to do this !

TheLLspectre commented 6 years ago

So i make my API, i have the nodeJs server on the raspberry, with a simple index.js file, i make a little function just to have a message from the console on the server. In my browser, on my computer(not on the raspberry ), i wrote the Url, and i have an access great, i can access to my function and have the return ! GREAT ! So now i need to know how to use it in Ionic ??? i have something like this but nothing work..... var url = '<a class="vglnk" href="http://169.254.25.25:8080/testSansHtml" rel="nofollow"></a>' var response = this.http.get("http://169.254.25.25:8080/testSansHtml").map(res => res.json()); console.log(response); return response;

I make all imports everything is ok, the button which this code is affected work correctly but any message in the console .....

nebrius commented 6 years ago

Ionic is just like any other browser since it is a browser, so the thing you do in your browser to talk to the API is the same thing you do in your Ionic app.

TheLLspectre commented 6 years ago

Yeah i try but nothing happen....

nebrius commented 6 years ago

Hmm, I would guess that's something with Ionic then, which is unfortunately outside of my area of expertise. Perhaps try asking the Ionic project?

TheLLspectre commented 6 years ago

Ok so i find the solution, i think ! the code i have in the typescript of Ionic is useless, i just have to put a HREF in the html code, to call the nodejs server !!! Do you know how i can just call a JS function? Because that work but he try to find the html page but i make a quick function without html return ...

dtex commented 6 years ago

@TheLLspectre You are wanting to call a JS function on the server (a node app) from the client (a web page)?

Have you looked at socket.io?

TheLLspectre commented 6 years ago

Absolutely that @dtex !!

I'm looking that !

TheLLspectre commented 6 years ago

hum..... The problem with that, i think, they show how to start with socket.io, but the HTML page is in the node app, mine is in the Ionic app, not in the node app, and i want to ask the node app thanks the ionic app !

TheLLspectre commented 6 years ago

Following the previous post, i find something call CORS for the nodeJS server, but i don't know why it doesn't want to work !!! i have this message from the browser:

polyfills.js:3 GET http://169.254.25.25/socket.io/?EIO=3&transport=polling&t=M0ILndh 404 (Not Found) Failed to load http://169.254.25.25/socket.io/?EIO=3&transport=polling&t=M0ILndh: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 404.

and i search how i can fix it but i don't know ....

This is the essential part of my nodeJS server:

app.use(function(request, response, next) { response.header("Access-Control-Allow-Origin", "*"); response.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); });

app.options('/api/*', function (request, response, next) { response.header("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS"); response.send(); });

app.get('/',function(req, res) { console.log("Application connecté au raspberry !")

});

app.get('/testSansHtml', function(req,res) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); console.log("Test sans HTML Well done !"); var a = 2; var b = 6; var c = a + b; console.log(a + " " + b + " " + c ); });

app.listen(8080, function(){ console.log('sur le port*:8080'); }); console.log("Server is running");`

dtex commented 6 years ago

I notice that your code has this app running on port 8080 but your request is to port 80. I suspect that's just a copy past error and not really the cause of your problem?

TheLLspectre commented 6 years ago

So,, I try on the port 80, and this doesn't work.this isn't my problem :)

TheLLspectre commented 6 years ago

I fixed this issue, on the server and on the Ionic App with for the server:

`var http = require('http'); var fs = require('fs');

// Chargement du fichier index.html affiché au client var server = http.createServer();

// Chargement de socket.io var io = require('socket.io').listen(server);

// Quand un client se connecte, on le note dans la console io.on('connection', (socket) => { console.log("Un client est connecté !");

socket.on('connection', function(socket)
{
    console.log("client connected");
});

});

server.listen(8080); console.log("Server is running");`

and also with typescript code for the Ionic App to emit message to the server.

DONE !

dtex commented 6 years ago

That's great news!

I'm going to close this issue. Feel free to re-open if there is something that has been missed.