polvo

Polyvalent cephalopod mollusc. (aka ambitious app assember)

Usage no npm install needed!

<script type="module">
  import polvo from 'https://cdn.skypack.dev/polvo';
</script>

README

Polvo - Polyvalent cephalopod mollusc

Stories in Ready

Build Status Coverage Status

Dependency Status NPM version

What the ★★★★?

Polvo is a built system and an application assembler for the browser.

Yet another one.

Seriously?

Yes, built with simplicity in mind and based on a straightforward plugins architecture, Polvo is also agnostic to languages, libraries, frameworks and weather, like the majority of his competitors friends.

Philosophy (in short)

  1. Your scripts and templates become all one javascript, and your styles become one css

  2. Both scripts and templates are wrapped as CJS modules and thus can be require-d regularly as you'd do in NodeJS.

  3. You end up with 2 files, app.js and app.css

Include both in your html and you're done!

Installation

npm install -g polvo

Features

  • Auto-build on every change
  • LiveReload on every change
  • Syntax-check on every change
  • SourceMaps support [1]
  • Conditional-compilation for flexibility (if, elif, else, fi)
  • Partials supported for templates and styles
  • Simple Embeded Webserver [2] powered by Connect
  • Compression capabilities powered by UglifyJS and CleanCSS
  • Multi-purpose resolution algorithm for both files and partials
  • Simplistic Plugins architecture available for interoperability

[1] For languages that provide it
[2] Simple convenience (also for SPA, redirecting inexistent urls to index.html)

Contents

Dependency Resolution

Polvo uses the same resolution algorithm presented in NodeJS, so you can code your libraries doing global or local require-s as you wish, like if you were building a NodeJS app. In the end, everything will be ready for in-browser use.

★ Of couse, you won't be able to use NodeJS core modules once inside the Browser, such as fs, process, cluster and so on. The same applies to any other module you may find - if it uses any API not available for in-browser use, you won't be able to use it.

Packaging Systems

In order to not lock you up with one single packaging system, Polvo is intended to support some of them. It's not fully functional yet but the plans are there.

★ As each packaging system approaches the subject in its own opinionated way, it may be impossible to aggregate them all in an universal way. However its under serious study and implementation right now to check all possibilities.

At the moment you can use:

  • NPM Full support, hooray!
  • Component Partial support [1]
  • Bower Partial support, with some caveats [2]
  • Ender Yet to be done [3]

[1] Supporting only js and css for now, full implementation is a WIP
[2] TODO: Describe caveats
[3] Pondering the real benefits and possibilities of implementing Ender

Plugins (supported languages)

Again, Polvo is agnostic to languages -- however it needs individual plugins for each language in order to properly assemble it. Some of them is built in out of the box for you joy, and others should be done / installed separately.

Polvo will search and initialize aditional plugins present in the dependencies field of your package.json file.

Built in plugins

Each plugin is an independent repository.

Click the links to see individual README for each one.

★ Scripts

  1. Javascript (.js) Build Status Coverage Status
  2. CoffeeScript (.coffee) Build Status Coverage Status
    • ✓ Literate Coffeescript (.litcoffee, .coffee.md)
    • ✓ Source Maps

★ Styles

  1. CSS (.css) Build Status Coverage Status
    • partials supported
  2. Stylus (.styl) Build Status Coverage Status
    • nib available
    • partials supported

★ Templates

  1. HTML (.htm, .html) Build Status Coverage Status
    • partials supported
  2. Jade (.jade) Build Status Coverage Status
    • partials supported

CLI

Command line interface help screen.

Usage:
  polvo [options] [params]

Options:
  -w, --watch        Start watching/compiling in dev mode                
  -c, --compile      Compile project in development mode                 
  -r, --release      Compile project in release mode                     
  -s, --server       Serves project statically, options in config file   
  -f, --config-file  Path to a different config file                     
  -b, --base         Path to app's root folder (when its not the current)
  -x, --split        Compile files individually - useful for tests coverage
  -v, --version      Show Polvo's version                                
  -h, --help         Shows this help screen                              

Examples:
  polvo -c
  polvo -cs
  polvo -w
  polvo -ws
  polvo -wsf custom-config-file.yml

Config

Polvo's config file is simply a file named polvo.yml in your project.

You'll may need to setup six simple options to adjust Polvo to your needs:

  1. server
  2. input
  3. output
  4. alias
  5. minify
  6. boot

A Polvo's complete config file look such as:

polvo.yml

server:
  port: 3000
  root: ./public

input:
  - src

output:
  js: ./public/app.js
  css: ./public/app.css

alias:
  app: ./src/app

minify:
  js: false
  css: false

boot: ./src/app/app

Server

Basic infos to serve your application, just inform desired port and your public folder.

When using the option -s a basic webserver will be launched to serve the app.

Input

Project's input src folders, can be one or many.

Output

Project's output files, at least one should be specified.

★ If you're using conditional compilation, make sure you're aware that you can reuse the conditional [variables]((#final-notes) to compose the output path for your files.

Alias

It's a handy option that lets you map some names to specific dirs. These names will make folders act like gobal modules in your node_modules folder with all dirs listed in package.json directories field, so you can require them as such.

For example, imagine a structure like this:

myapp
├── polvo.yml
├── src
│   └── app
│       ├── app.coffee
│       ├── controllers
│       │   └── controller.coffee
│       ├── models
│       │   └── model.coffee
│       └── views
│           └── views.coffee
└── vendors
    └── myframework
        └── src
            └── lib
                ├── controller.coffee
                ├── model.coffee
                └── view.coffee

The app's controller.coffee can require the framework's controller.coffee as easy as:

Controller = require '../../../vendors/myframework/src/lib/controller'

However, sometimes these relative paths can get nasty. In these cases, aliases can help the way. Imagine this one:

alias:
  myframework: ./vendors/myframework/src

With this, myframework folder will act as if it was a NPM module present in your node_modules folder, and require calls can be made in global-style regardless of which file is requiring it:

Controller = require 'myframework/lib/controller'

Note that:

  1. The myframework keywork is the virtual alias in the config file
  2. It points to the folder vendors/myframework/src
  3. So requiring myframewok/**/* will be the same as requiring vendors/myframework/src/**/*
  4. Be cautious while using aliases. For instance if you have have an alias with the same name of a module you have in your node_modules folder, you'll end up with serious problems - hopefully you'll notice this immediately.

Minify

In some cases you may want to disable minification in release mode, even though in both development and release mode you'll always have a single .js and .css file.

So what's the catch?

In development mode other things will be injected among your scripts in the app.js file. For example, the LiveReload embedded functionality.

In release mode it's removed, nothing special is injected. So you may want to have a production ready release file (that doesn't includes magic), but at the same time keep it uncompressed. In case you do, that's the way to go.

Boot

By default, Polvo will wrap all your scripts and templates in CJS module and register them all at startup. However, none will be require-d and therefore none will be initialized.

You need to specify your app's entry point within the boot property. With this Polvo will do a simple require to this file at startup, after everything is registered.

Following the config presented above, it'd be:

require( 'src/app/app' );

Conditional compilation

Looking forward for greater flexibility when compiling something for multiple targets, there's 4 directives available to control conditional compilation:

  • polvo:if
  • polvo:elif
  • polvo:else
  • polvo:fi

You can use these in any kind of file you have, be it a template, a style or a script.

These conditionals are processed before files are compiled with each its respective pre-processor and also before their output is scanned for dependencies.

So just insert these directives in form of a comment for the language your are using and they will be processed accordingly.

You can use both equality and inequality operators:

# polvo:if ENV = browser
equality = 'is browser'
# polvo:fi

# polvo:if ENV != browser
inequality = 'is not browser'
# polvo:fi

Example 1 (Browser x NodeJS)

# polvo:if ENV=node
request = require 'node-request-library'
# polvo:elif ENV=browser
request = require 'browser-request-library'
# polvo:fi

request.do_stuff [...]

With this code, you can compile the project in a few different ways, saying which build do you want, i.e.:

Targeting NodeJS

$ ENV=node polvo -c

Targeting Browser

$ ENV=browser polvo -c

The same example in plain Javascript:

// polvo:if ENV=node
var request = require('node-request-library');
// polvo:elif ENV=browser
var request = require('browser-request-library');
// polvo:fi

request.do_stuff( /* ... */ );

Example 2 (Desktop x Mobile)

Many people choses between JQuery or Zepto depending on what target, lets check how it'd be done easily for having hybrid builds.

# polvo:if ENV=desktop
$ = require 'jquery'
# polvo:elif ENV=mobile
$ = require 'zepto'
# polvo:fi

$('element').do_something [...]

Targeting Desktop

$ ENV=desktop polvo -c

Targeting Mobile

$ ENV=mobile polvo -c

Example 3 (Advanced)

You can have multiple conditions as well, many elifs and also a final else directive, depending on your needs:

# polvo:if ENV=desktop
$ = require 'jquery'
# polvo:elif ENV=mobile
$ = require 'zepto'
# polvo:elif ENV=node
$ = require 'cheerio'
# polvo:else
$ = require 'god-help'
# polvo:fi

$('element').do_something [...]

Variables naming

In the examples above we used the var ENV to get around the conditionals. However you can use any var you want:


# polvo:if ANIMAL=carnivore
food = require 'meat'
# polvo:elif ANIMAL=herbivore
food = require 'vegetables'
# polvo:fi

[...code here...]

And compile your project using the variables you just declared inside your code:

$ ANIMAL=carnivore polvo -c
$ ANIMAL=herbivore polvo -c

Final notes

Some final considerations:

Supported languages

Remember that every language is supported, you just need to add the explained directives in your source file in a form of a comment, so they doesn't affect your code.

All of them will be processed.

Output files

You can use a single polvo.yml with multiple targets, by setting your output file according the vars you're using for conditional compilation.

Example

input:
  - ./src

output:
  js: ./lib/app-{ENV}.js

When compiled with ENV=browser polvo -c, the output js file will be saved as ./lib/app-browser.js.

Or ./lib/app-node.js when compiled with ENV=node polvo -c, and so on.

The same applies for styles.

License

The MIT License (MIT)

Copyright (c) 2013 Anderson Arboleya

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.

Bitdeli Badge