shashwatak / satellite-js

Modular set of functions for SGP4 and SDP4 propagation of TLEs.
MIT License
911 stars 145 forks source link

satellite.min.js #80

Closed JaniniRami closed 3 years ago

JaniniRami commented 3 years ago

I saw on the readme page that there is support for script tag, but I cant find the satellite.min.js anywhere, does anybody know where to find it or download it?

ezze commented 3 years ago

You should install satellite.js with your package manager (npm or yarn):

npm install satellite.js

or

yarn add satellite.js

and then find satellite.min.js in node_modules/satellite.js/dist directory.

Another option is to clone the repository, install dependencies and build it manually (find the results in dist subdirectory):

git clone git@github.com:shashwatak/satellite.js
cd satellite.js
npm install
npm run build
thkruz commented 3 years ago

This was super helpful! Might be worth adding to the readme.

Is there a reason why the satellite.js and satellite.min.js files are not included on the releases page or that the dist folder is not shown on github?

I don't have a ton of familiarity with npm and yarn, but usually see a dist folder available on other projects.

@ezze - you're doing an amazing job keeping this library modern! Not meant to be a complaint. I am asking to help the other idiots like me figure out how it all works.

ezze commented 3 years ago

@thkruz Thanks for your question, mate!

The reason why dist directory is not shown on Github (both in sources and on releases page where tagged commits from master branch are shown only) is that satellite.js is not written in plain old JavaScript (ES5) anymore but ported to latter JavaScript versions ES6+ (you can refer to them here or dive into language specifications).

The source code located in src directory was ported to ES6+ in order to make the library compatible with new JavaScript versions and make it easier to migrate to them in the future (as soon as all widely used JavaScript environments will support them out of the box). At the moment, some browsers such as Google Chrome already have a native support for most ES6+ features , recent versions of Node.js can also run ESM modules but in order to be able to run the code in all legacy (and still widely used) environments we stiil have to provide ES5 versions of the library. For this reason we have the build instructions. When you run build npm script you get the following variants of the library:

  1. dist/satellite.js and dist/satellite.min.js ES5 compatible files meant for browser environments mostly, you can see the following construction at the beginning of each file:

    (function (global, factory) {
      typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
      typeof define === 'function' && define.amd ? define(factory) :
      (global.satellite = factory());
    }(this, (function () {
      // ...
    
      return { ... };
    })));

    This is so called Unified Module Definition (UMD). You can see Immediately Invoked Function Expression (IIFE) here, the function receives two arguments:

    • global storing a reference to execution context (it differs depending on the JS environment);
    • factory function which prepares an object with exported library constants, functions and objects.

    Thanks to UMD, these files can be used in global browser namespace (satellite.js is available in global.satellite when you include <script src="dist/satellite.min.js"></script> on your page), in AMD environment with Require.js (see demo repository) or Common.js:

    var satellite = require('./path/to/satellite.js');
  2. lib/index.js file and a bunch of related files are ES5 compatible Common.js modules. When you require the library like this:

    var satellite = require('satellite.js');

    Node.js will search for the closest node_modules/satellite.js/package.json file to your source code directory (when library is installed with npm or yarn) and look for the main property there. Script file (lib/index.js in our case) pointed out by this property will export the result for require function call.

  3. dist/satellite.es.js file meant for ES compatible environments. It's imported from module or jsnext:main properties of the package.json:

    import satellite from 'satellite.js';

Back to your question, only src directory is included in the Git repository, dist and lib directories are ignored. It's done intentionally to retain the size of the repository as small as possible. Keep in mind how Git stores the files. It saves the whole copies (not diffs) of each version of each file and that's what makes Git to work very fast. So, if we include all these build artifacts and minified versions of the library per each new (even small) commit or release we will get the repo many times larger than it's at the moment because every change in src directory will lead to new satellite.js and satellite.min.js output files with new unique sha1 hashes.

Therefore, package managers are here to help. Git is for the sources, npm registry is for the distribution! Nowadays, most of JS developers (backend and frontend) use it to publish and install the packages by a single console command:

npm install satellite.js

or

yarn add satellite.js

or even

pnpm add satellite.js

It's a common practice, as I see.

If you are a frontend developer supporting some legacy code the best and simpliest way to use the library is to copy satellite.min.js to your project. You can also include satellite.min.js script installed from npm registry (it's already mentioned in the docs):

<script src="node_modules/satellite.js/dist/satellite.min.js"></script>

but usually it's not how you want to organize the code.

It's possible to write frontend source code in ES6+, moreover, some popular frontend libraries (such as React.js) introduce custom language extensions (such as JSX) or improve development experience with TypeScript (by the way, thanks to @kylegmaxwell we have TypeScript definitions for satellite.js). All of these require source code transpilation to ES5, otherwise it won't work in browsers. The best option is to use module bundlers in these cases. Webpack is the first and the most popular choice.

Not sure that we should put everything above in README.md but adding a reference to this issue or describing how to use it in legacy frontend projects not relying on package managers would be fine. PR is welcome! ;)

thkruz commented 3 years ago

@ezze amazing answer. As someone who learned javascript as a hobby, the ES6+ stuff has been in the "I should really get around to learning that stuff" category and I think you just gave me a huge push. I will make the PR this week with some info from here and a link back to the full explanation. Thank you!