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

umd-builder

v2.16.5

Published

Build modular client application with support of commonjs, requirejs and nodejs without duplicating source code

Downloads

105

Readme

umd-builder

This library is part of a bigger project developped for the following reasons:

  • Test how much Asynchronous module definition (AMD) is slower than CommonJS module definition and up to which file size
  • To have both module definitions without duplicating code and serve AMD files if the single page application file becomes too big
  • To make debugging easier. A big javascript file is harder to debug that a small one even with source map
  • To be able to reuse the same code with a nodejs server
  • Because I have the feeling that as the project grows, a big javascript file may become a nuisance

Even though this library can be used as a replacement of [brunch], actually it can be seen as a customized version of brunch.

This library build a mix of CommonJS files and AMD files.

Project example

There is a project example in examples/project

Here is the project's structure

app/
    assets/             // Files inside `assets` would be simply copied to `public` dir.
        index.jst       // Will be used to generate index.classic.html and index.single.html.
    node_modules/
        examples/       // Some files used by the application.
        initialize.js   // Application entry point.

server/
    HttpServer.js       // An http server that will
                        // serve index.classic.html when requesting /web.
                        // and serve index.single.html when requesting /app.

vendor/                 // third party libraries needed.

.babelrc                // babel configuration. Allows to parse jsx code.
.jshintrc               // Some jshint rules.

bower.json              // Describes which dependencies your client app uses.
brunch-config.coffee    // Basic assumptions about the project, like paths & outputs.
build.js                // cli for building. Usage is the same as brunch
package.json            // Describes which dependencies and Brunch plugins your app uses.
test.js                 // Example of how to use generated files in nodejs

From project, issue

npm install

Build and start the server by issueing

node build.js w -s

In your favourite browser, navigate to

The application can also be viewed without starting a server by opening in your favourite browser

  • public/index.single.html single page version
  • public/index.classic.html amd version

Universal module definition (UMD) module file

A file is considered as an UMD module file if it has a top level function name factory or freact.
freact will make React and ReactDOM variables available.
Depencies of the module must be defined in a deps variable.
UMD builder will look into all files that transformed in a javascript to check if they are UMD files

// app/node_modules/some/path/module.js
 
import relative from './relative';          // look for module defined in app/node_modules/some/path/relative.js
import forAll from 'for-all';               // look for module defined in app/node_modules/for-all.js. In nodejs, will use the classic require
import globalForAll from '!global-for-all'; // look for global variable global-for-all
 
import specificPerEnv from "%{ common: 'use-this-in-single-page-mode', amd: 'use-this-in-amd-mode', node: 'use-this-in-nodejs' }";
 
// in single page, look for global variable use-this-global-in-single-page-mode
// ignore other environments
import commonOnly from "%{ common: '!use-this-global-in-single-page-mode' }";
 
// Can also be used with require
 
// Dependency resolution will happend at runtime and the generated file will have a bigger overhead
// For that reason, use require only when you need computed dependencies
const nodeOnly = require({ node: "fs" });
 
// this require style is always supported
// it only loads modules asynchronously when in an AMD environment
// otherwise, it is just a wrapper for the commonjs require
require([ './relative',  'for-all', '!global-for-all', { node: "fs" }], (relative, forAll, globalForAll, nodeOnly) => {
    // ...
});

Wild cards in bower.json file

When defining main, scripts or styles files in bower.json, you can use anymatch pattern.

The classic brunch do not allow that.

{
    "jquery-ui": {
        "main": [
            "jquery-ui.js"
        ],
        "styles": [
            "themes/redmond/**"
        ],
        "scripts": [
            "ui/version.js",
            "ui/keycode.js",
            "ui/widgets/datepicker.js",
            "ui/i18n/datepicker-ar.js",
            "ui/i18n/datepicker-fr.js",
            "ui/i18n/datepicker-he.js",
            "ui/i18n/datepicker-zh-TW.js"
        ]
    }
}

Deal with traditional "browser globals" scripts

From requirejs config shim

Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value.

{
    "bootstrap": {
      "main": [
        "dist/css/bootstrap.css",
        "dist/js/bootstrap.js",
        "dist/fonts/**"
      ],
      "dependencies": {
        "jquery": "*"
      },
      "exports": "jQuery.fn.emulateTransitionEnd"
  }
}

Compilers

With the classic brunch, the only way to add a compiler is to delacre it in package.json.
That is too restrictive for me for 3 reasons:

  • First, I am too lazy to always create an npm package when I am testing stuff
  • Second, I am also too lazy to spend time to find a way to try completely separate my custom compilers from umd-builder package
  • Third, the benefits of being lazy seem to me far greater than the benefits of having a package

For those reasons, I made a way to add compilers directly in brunch-config file.

Nevertheless, if I am aware of better benefits than being lazy, I will spend time to try to make things cleaner.

AmdCompiler

Depends on umd-builder.

Mandatory. Transform files with a top level factory or freact function in umd module.

exports.config =
    compilers: [
        require('umd-builder/lib/compilers/amd')
    ]

    plugins:
        amd:
            strict: true # add 'use strict' in module definition (factory or freact)
            jshint: true # lint generated javascript using jshint

        jshint:
            warnOnly: true # if false, failed linted will be considered as error
            # ignore: ignore    # function(path) called to determined if file should be linted.
                                # Usually, third party libraries should be ignored
            # options: {} # if defined, ignore rules defined in .jshintrc

CopyCompiler

Depends on umd-builder.

Recommended. Copy all watched files that do not match a javascript or stylesheet compiler.
Usefull for images, fonts required in stylesheets.

exports.config =
    compilers: [
        require('umd-builder/lib/compilers/copy')
    ]

RelativeCSS

Depends on umd-builder.

Recommended. Keep correct path in css. ex: bootstrap.
Usefull for images, fonts required in stylesheets.

exports.config =
    compilers: [
        require('umd-builder/lib/compilers/relativecss')
    ]

BabelCompiler

Transform every javascript code using babel.

exports.config =
    compilers: [
        require('umd-builder/lib/compilers/babel')
    ]

    plugins:
        babel:
            # optional transformations
            pretransform: [
                [
                    # add spModel, spClick, spShow, ... more details later
                    require('umd-builder/lib/spTransform'), {transformations: mdl: false}
                ]
            ]

            # ignore: ignore    # function(path) called to determined if file should be transform with babel.
                                # Usually, third party libraries should be ignored
            # if no other option is setted, use rules defined rules in .babelrc

HandlebarsCompiler

Transform handlebars files into UMD modules

Similar to handlebars-brunch.

At the time I started this library, handlebars-brunch was not using the latest version of handlebars and I was using handlebars the new features.

exports.config =
    compilers: [
        require('umd-builder/lib/compilers/handlebars')
    ]

HtmlCompiler

Transform html and htm files into UMD modules.

exports.config =
    compilers: [
        require('umd-builder/lib/compilers/html')
    ]

JstCompiler

Transform jst files into UMD modules that expose a lodash template.

I added an ignore option to use comments in files.

<% is to be able to use Java Server Page (JSP) syntax highlight in sublime text and notepad++ since Java is not far from Javscript.

exports.config =
    compilers: [
        require('umd-builder/lib/compilers/jst/jst')
    ]
    plugins:
        jst:
            # _.template uses with when no variable is given. Since with is not recommended on MDN, I prefer not to use it
            # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with
            variable: 'root'
            ignore: /<%--([\s\S]+?)--%>/g # added for comments within templates
            escape: /<%-([\s\S]+?)%>/g # default value
            interpolate: /<%=([\s\S]+?)%>/g # default value
            evaluate: /<%([\s\S]+?)%>/g # default value
            strict: true

MarkdownCompiler

Transform markdown files into UMD modules

exports.config =
    compilers: [
        require('umd-builder/lib/compilers/markdown')
    ]
    plugins:
        # https://github.com/chjj/marked
        # defined maked options
        markdown:
            jst: false  # Allow interpertation of javascript code within jst brackets. Look at JstCompiler for more details
                        # example: You can follow the [tutorial](<%= app.router.engine('default').getUrl({module: 'tutorial', controller: 'home', action: 'step0'}) %>)

StylusCompiler

Transform stylus files into stylesheet files.

I don't remember why I created this since there is stylus-brunch that does the same job.

exports.config =
    compilers: [
        require('umd-builder/lib/compilers/stylus')
    ]

Known issues

Partial build for large projects

It is hard to define large projet, let's say a project on which copy all files (app, bower_components, vendor) will take more than 60 seconds.

With those kind of projects, sometimes, build does not start correctly.

Re-run the build in those cases.

Because there is a workaround and not easy to reproduce, I don't want to spend time trying to fix it.

Source maps

With all those transformations, I have difficulties keeping the source map correct. The truth is, I don't understand a thing about source maps.

License

The MIT License (MIT)

Copyright (c) 2014-2018 Stéphane MBAPE (http://smbape.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.