-
• #2
One way to get a module into the espruino is to put it on a micro SD card in in node_modules directory, then load it from within the Espruino. You need to put the require command in left hand side, or on the right, you need to confuse the IDE like so:
var d="DHT22dev" var dht=require(d).connect(B0)
(if you do require() with a string that the IDE can't find on the website, it'll refuse to send it at the moment....)
other way is to do:
modules.addCached("modulename","module source code goes here");
I think a way to set a local directory to look for modules in is planned
-
• #3
1) 2 modules is probably better... I don't see any real reason why not - people may just want Date and not clock, and then they won't want the extra memory used up...
2) You should be able to do:
var x =require("http://foo/bar.js");
If you have a webserver on your PC, you should be able to load from localhost... @JumJum's made a 'project' extension for the Web IDE that allows local files, but I've yet to integrate it properly I'm afraid.
3) I'd try
https://github.com/espruino/EspruinoDocs/tree/master/modules
4) I'm afraid not. It's an interesting thought actually. To date, most of the modules have been interfacing to hardware so tests haven't been an issue. Perhaps we should start a tests folder. If tests were arranged like: https://github.com/espruino/Espruino/tree/master/tests then the existing Espruino executable could test them...
-
• #4
Gordon, DrAzzy
Thanks. I got the require("http").. working
But how do I create a Date() type within a module which is accessible to users of the module using 'new'? So for example
require("date");
d=new Date();
I did have a reasonable look for any other file like this, didn't see one... maybe I missed it?
Martin
-
• #5
Hi Martin,
d=require('date').connect();
Sacha
-
• #6
Sacha
Thanks, but I was hoping for something a bit more like 'new'
Imagine I want three date objects. I guess I'd have to write
x=require('date');
d1=x.connect();
d2=x.connect();It's not very elegant, IMHO :)
There's also the problem of passing constructors.
d=require('date'.connect(args)
I think I can do this using 'apply' inside the 'connect'' function but I'm not sure
how exactly it would look.Martin
-
• #7
Yeah I also noticed that you can't export a single class. But the example would be:
var Date = require('date').connect;
var d1 = new Date()
var d2 = new Date():)
You could also call 'connect' something like '_constructor'.
-
• #8
As i understand it, the connect function has to return a new object like this:
exports.connect = function(arg) {
return new Date(arg);
};
var Date=function(arg) {
this.value=arg;console.log('Its alle about Date: '+this.value);
};
Then you are able to create it like this:
var d1=require('date').connect('Object_1');
var d2=require('date').connect('Object_2');your output should be like this:
Its alle about Date: Object_1
Its alle about Date: Object_2Sacha
-
• #9
@gadicc - your solution looks good, but I don't know what it would look like inside the module source. "connect" is usually declared as a function member of 'exports' and I suspect declaring the date constructor as "exports.connect = function.." might stop it being a date constructor...
Ah, someone at my work has said that if I declare the date as normal
Date = function ()...
Then put a line like this
exports.Date=Date;
Then I can use it like this
Date = require('date').Date;
var d1 = new Date();
I'll test this approach soon...
Martin
Martin
-
• #10
Yes please don't call the constructor for a new Date 'connect' - that wouldn't have any sense!
-
• #11
I think this is solved.
In the module file:
function Date() { // Constructor code } exports.constructor=Date;
In the referring file
var Date=require("Date.js").constructor; var d1=new Date(); var d2=new Date(2014,10,1,12,0,0,0);
-
• #13
Gordon
Thanks. However, I hit another problem last night: I now have this
Main file
var Clock = require("http://192.168.0.12/clock.js").constructor;
Clock file:
var Date= require("http://192.168.0.12/date.js").constructor;
Is there any issue with doing nested requires?
Note - I previously appeared to have corruption problems, so I turned on the 'throttle' option. It now seems to be missing some of the code in the second require - is there any chance the throttle setting only applies to the first file?
BTW - throttle is very slow :(
Thanks
Martin
-
• #14
Do you have 1v61? That will hopefully solve a lot of issues you would have had with lost characters.
I've just looked at this - there's no issue with recursive module loading, but there is when one module requires the other. Is there any reason that Date requires Clock? IMO it shouldn't (as it defeats the point of having two modules!).
I've fixed the Web IDE (from GitHub) anyway now, but the Chrome Web Store one probably won't get updated for another 2 weeks because of the Maker Faire,
-
• #15
Gordon
re: 1v61 - yes, I think so. Will check. I am updating quite often, but have multiple devices.
re: Recursive - Clock requires Date, but Date doesn't require Clock. Clock creates a subclass of Date.
The error really does look odd - I included print statements in the module, and it seems to just skip some of them and jump to a lower statement and then complain.
It's not lost characters, more like lost chunks of 100 bytes or more. Hard to debug - I can't see what it's actually getting.
Martin
-
• #16
That does sound pretty strange. Could you paste up your modules and code? maybe as a Gist if it seems too big for the forum?
-
• #17
Gordon
Thanks. Files attached. Please remember this is my first serious piece of JS - feedback appreciated :)
My current test code for using it looks like this:
var Date=require("http://192.168.0.12/date.js").constructor; var Clock2=require("http://192.168.0.12/clock.js").constructor; print("hello"); print(Clock2); var clk=new Clock2(2014,15,4,23,57,0,0); function showClock() { print(clk.getClockTime().toString()); } setInterval(showClock,1000);
The result on running:
Date Module - Loading...
Before date fn
After date fn
getDayssinceepoch
setDayssinceepoch
Done Loading Clock Module
Date Module - Loaded.
Clock Module - Loading
xLoading Date
xDone loading Date
ERROR: Using '.' operator on non-object at line 66 col 29
print("Clock module - Loaded.");^
ERROR: Got String:');
' expected ID at line 66 col 31
print("Clock module - Loaded.");^
hello
undefined
ERROR: Constructor should be a function at line 1 col 161
var Date=require("http://192.168.0.12/date.js").constructor,Clock2=require("http://192.168.0.12/clock.js").constructor;print("hello");print(Clock2);var clk=new Clock2(2014,15,4,23,57,0,0);function showClock(){print(clk.getClockTime().toString())}setInterval(showClock,1E3);^
Throttle sending is ON. Minify is set to 'simple optimisations'
Martin
2 Attachments
-
• #18
exports.constructor=Date;
I've always done:
exports.constructor = function() { return new Date(); }
like the example modules do.
Last time I tried optimization from WebIDE, it didn't work. Try turning off minification for now. I was asked to provide simplified code that would make it fail, but I've been super busy lately, and haven't had any time to fiddle with that and cut the code that caused it to a smaller size than "my whole project"
-
• #19
DrAzzy
Your method above won't support arguments to the constructor - my code supports zero, 1 and 7 arguments. Gordon seemed to think my method was fine :)
I just retested with minify off, and I get the same sort of bizarre error.
I then just copied the whole of Date and Clock modules into RHS, and fixed
the exports to use a variable - and it all works.Just to double-check, I copied the modules to the SD card - again it works fine.
These errors strongly suggest that throttle isn't working and characters or chunks of source are being dropped. I could just copy the files to SD card and re-test.
Gordon - I have 1v61, Chrome 34.0.1847.116 on Win 8.1 pro
I think this may be only happening because I'm nesting requires. Not sure.
Martin
-
• #20
Just to be absolutely clear - I only get this problem when the modules are being sent to the device by loading from a web-server using a require in the RHS.
In all other cases - code in the RHS directly or on SD card, there's no problem.
Thanks :)
-
• #22
@graf - @mgg1010's method should work fine. AFAIK nothing stops you from doing
new require("foo").Bar
.@mgg1010 - very odd about your issues with the files from http. I actually just tried here and got some problems too. Try turning on
throttle send
in settings and see if that helps (it'll be slower though).It looks like it's taking a while for Espruino to receive/execute the module, as it gets turned into a giant string and sent over (rather than being able to be executed line by line). It means it's losing some characters - although I really hoped I'd fixed that in 1v61.
I guess the easy fix would be to add the option to auto-minify modules, as currently clicking the 'minify' option will minify the RHS, but not any modules it loads.
-
• #23
@graf - your method can't handle a varying number of arguments. Note - I have tested my method, and it works fine :) It's actually pretty logical now that I've understood JS a bit better. The constructor is just a function, and I'm just passing a reference to it out :)
It does say a few messages back that I'd tried throttle before, and it doesn't help.
Actually, I'll be more specific. Right now I'm doing the following
- Requiring date in my RHS test code - this works with throttle on
- Requiring clock in my RHS test code
- requiring date again inside my clock code
It seems to be only the LAST one that generates the odd errors.
This raises questions
If there's a module cache, why does my second-level require inside clock attempt to re-load date? (I can see it printing log messages, so it is doing
this)Hmm - presumably the second-level require inside clock is being handled by the device, not the IDE. Maybe the problem is that the code in the device to read from an HTTP address also needs throttle?
Martin
- Requiring date in my RHS test code - this works with throttle on
-
• #24
It's actually a bug in the Web IDE (causing it to reload a module that was already loaded) that I fixed yesterday - so the Web IDE from GitHub shouldn't have the issue.
The device itself won't get from HTTP at the moment - it just pulls it out of its cache (that got loaded from the Web IDE) when it encounters the
require
.
-
• #25
Does the webIDE recursively check requires? I require a module in RHS from website. webIDE downloads it. Does it check inside the downloaded text for a new require?
Does the webIDE have some way to tell the device "this is a module, insert it into your cache". What name does it give it? I mean, if I use require("http://....date.js") is it added to the cache with the full path or just the filename? (Just curious)
I still think there is a throttle bug somewhere. I'll try the gitHub webIDE, but otherwise I'll finalize the modules and put them on SD card... that will work around it for now.
Thanks
Hi All
I've written a Date and Clock module. The Date module uses the same API as JS Date (but doesn't implement everything at all), and Clock inherits from it. (It's all a bit rough so want to polish a bit more before sharing :)
I'm a bit of a newbie at JS, so have a few questions...
Should these be two modules or one? I guess two... any reason why not?
Is there any way to get WebIDE to pull modules from either a) my PC or b) multiple locations? Can it pull them direct from my github account?
These aren't device modules - where would I put them in github?
Is there any convention for unit tests for Espurino modules?
Thanks
Martin