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

angular-lazy-bundler

v0.2.3

Published

## Table of contents - [What does it do?](#what-does-it-do) - [How is it different from tools like Browserify?](#how-is-it-different-from-tools-like-browserify) - [Requirements](#requirements) - [API](#api) - [Usage example](#usage-example) - [Troubleshoo

Downloads

9

Readme

Angular Lazy Bundler

Table of contents

What does it do?

Lazy loading components at runtime gives us the advantage to ony load code that is going to be used by the client. At the same time it introduces one big disadvantage; it increases the number of network calls we need to make to load a component / library. This leads to slower page load times and affects the user experience negatively. This is what Angular Lazy Bundler tries to solve.

Lets take the following component as an example:

+src
|  +components
|  |  +home-state
|  |  |  home-route.js
|  |  |  home-state.html
|  |  |  home-state-controller.js
|  |  |  index.js

To load the home state component the browser would need to make at least four requests. Angular Lazy Bundler solves this issue by creating a bundle of our source code per component. Given the above example, the bundler would create a combined file containing all four of the home state's files.

+src
|  +build
|  |  +bundles
|  |  |  home-state.js

The same is applied for JSPM packages. As of now, if you load JSPM packages in the browser you at least make two server calls. One for the package file, e.g. [email protected]. The only purpose of that file is to reference the main package file defined in package.json, e.g. index.js for lodash. This is a necessary evil to make NPM packages easy loadable by name in the browser. The Bundler optimizes this load process by combining the package and the main file into one.

After creating the bundles you can tell Angular Lazy Bundler to also update your SystemJS configuration, so that the loader knows about the bundles and loads the combined resources instead of the individual files. See the bundle config API in the SystemJS documentation.

How is it different from tools like Browserify?

Browserify and similar tools, by default, create one big bundle which contains all the application's source code. This works good for smaller applications. But when you have a few megabytes of code this becomes somewhat of a burden. Let's say our application has 20 different states / screens. The only thing the user wants to do is check his new messages which is one state. But even in that scenario the browser would actually download the remaining code of the application before the user can look at his inbox. This unnecessary wait time is what we want to omit by loading only the parts of the application the user is actually going to access.

Requirements

For the bundler to work it's required to have a project structure as generated by Angular Lazy Generator. Each index.js file in the src folder indicates a root of a component. Only resources which are referenced / imported by the corresponding index.js file, and their sub-dependencies, will land in the resulting bundle. Files which are not imported statically from anywhere will not be bundled. But they will still get loaded by SystemJS individually.

API

new Bundler(options)

new Bundler(options)

| Param | Type | Default | Description | | --- | --- | --- | --- | | options | Object | | Bundler options. | | [options.source] | String | src | Where to search for components / index.js files. | | [options.baseUrl] | String | . | Base URL on the file system to use for bundling. | | [options.dest] | String | build/bundles | Destination folder where the bundled resources will be written to. | | [options.bundlesBaseUrl] | String | bundles | Path relative to the baseURL of SystemJS in the browser of the destination folder. | | [options.systemJsConfig] | String | config/system.js | Path to the SystemJS configuration file. | | [options.sourceMaps] | Boolean | true | Enable / disable sourcemap generation. | | [options.minify] | Boolean | true | Enable / disable minification of bundled resources. | | [options.cssOptimize] | Boolean | false | Enable / disable CSS optimization through SystemJS' CSS plugin. The plugin uses clean-css in the background. | | [options.tab] | String | 4 spaces | What to use as tab when formatting the updated SystemJS configuration. |

bundler.bundle(content, saveAs) ⇒ Promise

Bundles components and 3rd-party packages.

| Param | Type | Description | | --- | --- | --- | | content | Object | Bundle content. | | [content.components] | Array | Which components to bundle (without "components/" prefix and without "/index.js" sufix). | | [content.packages] | Array | Which packages to bundle. | | saveAs | String | Name of the resulting bundle (without .js extension). |

bundler.bundleComponent(index) ⇒ Promise

Bundle a specific component.

| Param | Type | Description | | --- | --- | --- | | index | String | Path to the index.js file of the component. |

bundler.bundleComponents(componentNames, saveAs) ⇒ Promise

Combine multiple components into one bundle.

| Param | Type | Description | | --- | --- | --- | | componentNames | Array | Which components to bundle (without "components/" prefix and without "/index.js" sufix). | | saveAs | String | Name of the resulting bundle (without .js extension). |

bundler.bundlePackage(packageName) ⇒ Promise

Bundle a certain vendor package.

| Param | Type | Description | | --- | --- | --- | | packageName | String | Package name, same as in the SystemJS configuration. |

bundler.bundlePackages(packageNames, saveAs) ⇒ Promise

Combine multiple vendor packages into one bundle.

| Param | Type | Description | | --- | --- | --- | | packageNames | Array | Which packages to bundle. | | saveAs | String | Name of the resulting bundle (without .js extension). |

bundler.bundleRemainingComponents() ⇒ Promise

Bundles all components which are not yet part of an existing bundle.

bundler.bundleRemainingPackages() ⇒ Promise

Bundles all vendor packages which are not yet part of an existing bundle.

bundler.saveConfig() ⇒ Promise

Saves bundle information to the SystemJS configuration.

Usage example

const Bundler = require('angular-lazy-bundler').Bundler;

const bundler = new Bundler({
    systemJsConfig: 'config/system.js'
});

bundler
    .bundle(
        {
            components: [
                'application',
                'home-state'
            ],
            packages: [
                'angular',
                'angular-resource',
                'angular-sanitize',
                'angular-ui-router',
                'ui-router-extras'
            ]
        },
        'main'
    )
    //bundles the sources of our application per component
    .then(() => bundler.bundleRemainingComponents())
    //creates a custom bundle with all packages required for boostrapping the application
    .then(() => {
        return bundler.bundlePackages(
            [
                'date-picker',
                'moment'
            ],
            'date-picker'
        );
    })
    //bundles the remaining packages individually
    .then(() => bundler.bundleRemainingPackages())
    //updates our SystemJS configuration
    .then(() => bundler.saveConfig())
    //here we can handle errors
    .catch((err) => { });

Troubleshooting

A lot of packages don't declare their dependencies properly. For example, UI Router doesn't declare a dependency to Angular in it's package.json. Same with Bootstrap, which doesn't have a dependency to jQuery. This leads to errors when bundling such libraries as their dependencies don't get included properly. If you encounter such issues search for special distribution build of the package on it's GitHub page, e.g. github.com/angular/bower-angular-animate for angular-animate. In that case try installing the package from there.

Another possibility is to amend the missing information in config/system.js as already done by JSPM when it finds dependency declarations in package.json or in the JSPM registry itself.