How to make npm modules compatible?

Posted on
  • I'm, trying to require quite small modules through the Web IDE and on a Pico board 1v76

    No matter what I require, it's always the same:

    WARNING: Module "anything" not found
    

    I'm requiring on the right side, which is also graphically telling me every time that module hasn't been found.

    this module is just an example, but reading the documentation I also spot the following:

    the Web IDE will automatically look online for minified versions of the modules you need, download them, and load them onto the board.

    In node.js and io.js world I've never thought minification would have been useful but I understand its value for small devices like the Espruino Pico.

    However, I wonder if there's any official procedure able to make a module compatible with the pico: any specific field in the package.json file? Should the main file be the one minified, called .min?

    Please let me know what I should do in order to write Espruino Pico capable code, thank you.

  • Hi,

    The Espruino Web IDE usually looks in http://www.espruino.com/modules to find anything you've require()d. However if you go into settings/communications then you should find something called Load modules from NPM (BETA) that you can enable, which will drag modules off NPM (assuming they consist of a single js file).

    I just tried yours and it doesn't seem to work though - it's loading http://registry.npmjs.org/get-own-property-symbols/-/get-own-property-symbols-0.1.2.tgz but trying to find ./build/get-own-property-symbols.node.js and failing because the path is actually package/build/get-own-property-symbols.js.

    I haven't really done much work on NPM support, because most modules I looked at in NPM pulled in loads of dependencies and filled up the available memory - it could be that something has changed or I'm just not dealing with that particular case (the NPM loader's code is here)

    Another simple hack is just to stick the JS file's URL into require:

    require("https://raw.githubusercontent.com/WebReflection/get-own-property-symbols/master/src/get-own-property-symbols.js");
    

    You can use localhost and a server, or you can use the 'project' feature in the Web IDE so that you can pull single files directly off a directory on your hard disk.

  • uhm ... OK, thanks for the info. If I load it manually I get this error:

    ncaught Error: Field or method "exports" does not already exist, and can't create it on undefined
     at line 4 col 428
    ...OwnPropertySymbols");module.exports=Object.getOwnPropertySym...
    

    And looking at "official" modules I see module is never used, only exports is.

    It is quite common in npm-land to module-exports = ... so that you can just require what's exported. It looks like in Espruino this pattern is not allowed: any specific reason for that?

    Back to the fragmentation quick chat we had on twitter few days ago, having a different way to export for Espruino only would be somehow weird for most modules.

    I understand not every module will or should run in here, but I've been coding small modules since about ever and I'm curious to see what works here and how well.

    Thanks

  • exports actually works fine. The issue is that the module global variable isn't defined (global is, but so far all the espruino modules have done fine just referencing exports directly).

  • OK, I wrote it not so clear indeed ...

    This is current/common status in npm

    // the module
    module.exports = function () {
      console.log('I am the module');
    };
    
    
    // the consumer
    var module = require('my-module');
    module(); // I am the module
    

    With current Espruino there's no way to directly export the object or the function, you can only attach properties to the exports variable.

    Will this be improved to reflect common npm modules pattern or the module object won't ever be exposed?

    Thanks

  • Right now the following works:

    // the module
    exports = function () {
      console.log('I am the module');
    };
    // the consumer
    var module = require('my-module');
    module(); // I am the module
    

    In fact I think even prefixing your module with var module=this; will work.

    But yes, I'll make sure that there's a modules variable - I've filed a bug

  • In fact I think even prefixing your module with var module=this; will work.

    watch out, the this inside a module is the exports itself, not the module ... I know it's quite confusing but better knowing this before doing any work.

    console.log(this === module.exports);
    

    If you require a file like that, the log is true in (node|io).js

  • Ahh, interesting - thanks. I'll make sure I check that's the case here too

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

How to make npm modules compatible?

Posted by Avatar for WebReflection @WebReflection

Actions