umd-builder

2.16.5 • Public • Published

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.

Dependencies (39)

Dev Dependencies (6)

Package Sidebar

Install

npm i umd-builder

Weekly Downloads

0

Version

2.16.5

License

MIT

Unpacked Size

326 kB

Total Files

78

Last publish

Collaborators

  • smbape