Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import via npm #4

Closed
snajjar opened this issue Feb 26, 2018 · 5 comments
Closed

Import via npm #4

snajjar opened this issue Feb 26, 2018 · 5 comments

Comments

@snajjar
Copy link

snajjar commented Feb 26, 2018

Could you include a proper node export, so it can be used directly from npm with the import syntax ?

import Morris from 'morris.js06'
@pierresh
Copy link
Owner

Hello,

Actually I am not really an Node.js expert.. I am open to this idea -as long it does not break the compatibility with non-Node.js server- but I would need some help on this point.

@exodus4d
Copy link

exodus4d commented Feb 6, 2021

Hi, sure I´ll try to help:

  1. In your package.json add a new module prop. pointing to a new "ES6 Module"(also called: ES2015 Module) version of morris.js -> morris.esm.js.
    This is an alternative entry point which is used if someone tries to import Morris via ES6 module syntax. Keep the main prop. untouched.

    Hint: At some point yon you might also want to ship Morris as a "type": "module" package. In this case main should point to the esm.js version as your primary entry point. But for now (and to keep backwards compatibility), keep main untouched" it might be best to add a browser property with your current main main script, set main

    Current:

    "main": "morris.min.js",

    New:

    "main": "morris.min.js",
    "module": "morris.esm.js"
    

    In a project where Morris is used, we want to support this syntax:

    // package.json
    {
      "name": "myProject",
      "version": "1.0.0"
      "main": "index.esm.js",
      "type": "module",
      "dependencies": {
        "morris.js06": "^0.6.6"
      }
    }
    
    // index.esm.js
    import {Morris} from 'morris.js06';
    // ^^ ES6 Module import syntax, if `module` prop. exists in your `package.json` the import will be  `morris.esm.js`
    
    const chart = Morris.Area({...};

  1. How to get a esm.js version?
    You might want to build the esm.js from your morris.js. We come to this later. There are just a few changes to get a "hard coded" module version:

    1. Unwrap the outer IIFE . (ES6 Modules are scoped by file and every var exposed/visible to other files needs to be exported at the end).

    2. Export Morris at the file end. Add: export {Morris}

    3. Since Raphael is a required dependency we need to import it at the top, so it can be accessed in your scoped module file: import Raphael from 'raphael';

      Hint: This works because raphael is already installed as as a dependency (@ package.json) and is a shorthand for import Raphael from './node_modules/raphael/raphael.min.js'

    4. The window obj. is not available in Node context (server side). Since we can include Morris, we do not need a global variable:
      Current:

      Morris = window.Morris = {};

      New:

      Morris /* = window.Morris*/ = {};
      

      Hint: Alternatively you can check the existence of window and assign:
      if (globalThis.window) window.Morris = Morris; see: globalThis.

    With these changes you have a morris.esm.js. A working example: https://gist.github.com/exodus4d/0fa3a015d1f490bdaae4f5b8041b89cb


  1. How to build a esm.js
    Since we now have a ESM version/format it is best to build an IIFE format from it rather than the other way around.
    I´m not an expert in Grunt, but I´m sure there are grunt plugins as well.
    I recommend Rollup as bundler and replace Grunt.
    Why? Rollup is a next gen ESM bundler that works with ESM files. You can specify multiple "output" formats that will be generated at once. You can create an IIFE format (what you currently have), and/or amd, cjs, es, umd, system.
    If you are interested in using Rollup, and/or need help let me know, Ill try to help.

@pierresh
Copy link
Owner

pierresh commented Feb 7, 2021

Thanks a lot for your complete explanations, I will have some free time next week, I will try to do this at that moment.

pierresh pushed a commit that referenced this issue Feb 17, 2021
NPM import based on this file:
#4

Types definition based on:
mledour/angular-morris-js#13
@pierresh
Copy link
Owner

Hello,

Thanks again for your message, I have tried with Angular and the esm file indeed works very well :)
I have done some research and actually, the structure of morris.js is a bit old. Rather than grunt or Rollup, it should be coffee-script to generate the esm file with the transpile option.

I have simply added the esm file in the /dist folder. I may update the structure of the project in future, but I suppose that for the time being providing this esm file is enough.
Also, I took this opportunity to add the TypeScript types definitions (got from here) with the new options I have added in this fork.

Could you please have a check, and if everything is ok, I will release a new version on npm.

pierresh pushed a commit that referenced this issue Feb 21, 2021
@pierresh
Copy link
Owner

I just published this version to npm :)

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

No branches or pull requests

3 participants