npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

grunt-amd-compile

v1.0.0

Published

Compile and optimize AMD modules from a files tree to a bundle.

Downloads

3

Readme

grunt-amd-compile

Compile and optimize AMD modules files into bundles.

Installation

npm i grunt-amd-compile --save-dev

AMD optimization

First what is optimizing AMD module ?

This is a not optimized module :

define(['require', 'exports'], function (require, exports)
{
    // ... 
});

The same module but optimized :

define('my/module/path/is/here/OptimizedModule', ['require', 'exports'], function (require, exports)
{
    // ... 
});

An optimized module have its path as a first argument of its define statement. Without this path, RequireJS can't know what is the virtual path of this module. Others modules can require this one from its path, like so :

define('my/module/path/is/here/OtherOne', ['require', 'exports', './OptimizedModule'], function (require, exports, OptimizedModule)
{
    // Here we can use OptimizedModule which is in the same folder 
});

Dependency paths are relative to each others, but RequireJS implementation takes care of this.

Optimizing, bundling and code-splitting

First, take a look at this AMD files tree as example :

  • amd/
    • common/
      • components/
        • CommonComponent.js
            define(['require', 'exports', 'react', 'react-dom'], function (require, exports, React, ReactDOM)
            {
              // Module code of a component using React and ReactDOM
            });
    • firstApp/
      • components/
        • FirstAppComponent.js
            define(['require', 'exports', 'react', 'react-dom', '../../common/components/CommonComponent'], function (require, exports, CommonComponent)
            {
              // Module code of a component using React, ReactDOM and another AMD module : CommonComponent
            });
      • Main.js
          define(['require', 'exports', 'react', 'react-dom', './components/FirstAppComponent'], function (require, exports, FirstAppComponent)
          {
            // Module code of a component using React, ReactDOM and another AMD module : FirstAppComponent
          });
    • secondApp/
      • Main.js
          define(['require', 'exports', 'react', 'react-dom', '../common/components/CommonComponent', './OtherModule'], function (require, exports, CommonComponent, OtherModule)
          {
            // Module code of a component using React, ReactDOM and another AMD module : FirstAppComponent
          });
      • OtherModule.js
          define(['require', 'exports'], function (require, exports, CommonComponent, OtherModule)
          {
            // Module code
          });

Note : This kind of file tree is easily generated with Typescript and is used seamlessly in solid-js framework.

We can see 2 things from this tree :

  • Modules are not optimized.
  • Modules files paths are representing the module paths.

We can optimize every modules easily and concat them into a big bundle with this grunt task... But that's not all !

Apps :

Some modules are using other modules but in other "apps". Apps here are these folder :

  • common/
  • firstApp/
  • secondApp/

Each apps can be bundled into one file :

  • common/**/*.js -> www/js/common.js
  • firstApp/**/*.js -> www/js/first-app.js
  • secondApp/**/*.js -> www/js/second-app.js

App to bundle is important to get because this is an powerful feature : Code-Splitting.

Each app have resources and dependencies. One app = one js file This is handy to optimize our application by loading bundled files for only the code we need.

Example :

  • Page a.html can load common.js and first-app.js because it does not use secondApp modules.
  • Page b.html can load common.js and second-app.js because it does not use firstApp modules.

Static libs

grunt-amd-compile can also concat static libraries. This is useful to bundle huge JS files, like react or jquery together, but without the AMD optimization. Concatenation is faster and libraries like react / jquery / gsap / pixi, etc, works well as global module. amdLite has an option to map global modules to dependencies. So when a module requires ['react', 'react-dom', 'gsap'], it will in fact returns window.React, window.ReactDOM and window.GreenSockGlobals See amdLite config file to see how it works.

Uglify

The option addUglifyTargets: true adds every amdCompile target to the uglify config node.

Usage

See this configuration file example.

In the browser

Now you have clean and optimized bundles containing your AMD modules, you need a library to define and require these modules from their virtual path.

The original RequireJS script is pretty big, can do a lot of stuff, and is complex to configure.

So I made a little RequireJS implementation for the browser, named amdLite. The configuration is easy, take a look !

Also, all of this is used transparently with solid-js framework. If you want something ready to use, give it a try :)

Links

  • Read this really good article about modular JS : https://addyosmani.com/writing-modular-js/
  • Solid JS framework is a Typescript framework using AmdLite
  • RequireJS optimization : http://requirejs.org/docs/optimization.html