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

panto

v0.1.0-rc.1

Published

PantoJS is an extreme flexible file transforming engine

Downloads

44

Readme

panto

NPM version Downloads Build Status Build status Coverage Status Dependency status Dev Dependency status

NPM

中文版 README

PantoJS is an extremely flexible file transforming engine. It is usually used for building projects, especially web front-end projects.

It works like Grunt or Gulp, but more efficient, powerful and flexible.

Core Features

  • Any building process topology

Panto supports almost any building process

  • Collecting rest files

You can select rest files that not selected by selectors

  • Read a file once at most

Read a file only once, even more than one transforming on a file

  • Transform a file once at most

Avoid duplicated processing

  • Cache at file

Avoid duplicated transforming

  • Incremental file transforming

More efficient watching

Panto vs Grunt/Gulp

| | Grunt | Gulp | Panto | | ------------------- | ----- | ---- | ----- | | Stream task | ✘ | ✔ | ✔ | | Topological process | ✘ | ✘ | ✔ | | Read once | ✘ | ✘ | ✔ | | Accurate cache | ✘ | ✘ | ✔ | | Accurate increment | ✘ | ✘ | ✔ |

Quick Start

Like Grunt or Gulp, Panto needs a process configurable file pantofile.js in root directory of your project, coffeescript syntax is not supported. A simplest pantofile.js contains:

module.exports = panto => {};

Notice that Panto requires Node.js 6.0.0 or higher, so feel relieved to write ES2015 codes.

Like loading Grunt/Gulp plugins, transformers should be loaded first. A transformer defines how to transform file contents.

module.exports = panto => {
    panto.loadTransformer('read');
    panto.loadTransformer('less');
    panto.loadTransformer('copy');
    panto.loadTransformer('write');
};

The above needs to install some npm packages:

npm install panto panto-transformer-read panto-transformer-less panto-transformer-copy panto-transformer-write --save-dev

Next, we need to define some parameters: cwd/src/output. src and output are relative to cwd:

panto.setOptions({
    cwd: __dirname,
    src: 'src',
    output: 'output'
});

Now we start to define building process. Here we transform .less files as an example:

panto.pick('*.less').read().less().write();

The above codes search .less files in src directory, read them, transform to css format, and write to output. E.g., src/style/foo.less transformed to output/style/foo.less.

Then we copy files other than .less files to output:

panto.rest().copy();

i.e. src/config/c.yml copied to output/config/c.yml.

The total pantofile.js is:

module.exports = panto => {
    panto.loadTransformer('read');
    panto.loadTransformer('less');
    panto.loadTransformer('copy');
    panto.loadTransformer('write');

    panto.setOptions({
        cwd: __dirname,
        src: 'src',
        output: 'output'
    });

    panto.pick('*.less').read().less().write();
    panto.rest().copy();
};

You can use load-panto-transformers to avoid writing many panto.loadTransformer('xxx') statements. time-panto is used for monitor, the simpler pantofile.js is:

module.exports = panto => {
    require('load-panto-transformers')(panto);
    require('time-panto')(panto);

    panto.setOptions({
        cwd: __dirname,
        src: 'src',
        output: 'output'
    });

    panto.pick('*.less').read().less().write();
    panto.rest().copy();
};

At last, for starting tasks in terminal, you need to install panto-cli first:

npm install panto-cli -g

Run:

panto -f pantofile.js

All above are in https://github.com/pantojs/simple-panto-usage.

Transformer

Transformers define logic of how to transform files. Extend panto-transformer to implement a transformer:

const Transformer = require('panto-transformer');

class FooTransformer extends Transformer {
    _transform(file) {
        file.content += 'A';
        return Promise.resolve(file);
    }
    isTorrential() {
      return false;
    }
    isCacheable() {
      return true;
    }
}

module.exports = FooTransformer;

If the files are transformed independently, just implement _transform() function, or else transformAll(), they both return Promise object, distinguished by isTorrential() function. Please see panto-transformer-browserify and panto-transformer-uglify.

If a transformer is idempotent strictly, it's cacheable, isCacheable() returns true. Any factors beyond file content that affect transforming results between two transformings will lead to uncacheable. E.g., for calculating md5 of content, same content result in same md5 value, affected by no factors. As another example, appending current date time to file content result in uncacheable, of course.

Input and output of transformers are files or file arrays. A file is a plain JavaScript object, contains filename and content these two properties at least. You can append other properties too.

Stream

Panto uses stream to define transforming tasks. As a node, streams consist of a directed acyclic graph.

const Stream = require('panto').Stream;
const s1 = new Stream();
const s2 = new Stream();
const s3 = new Stream();
const s4 = new Stream();

s1.connect(s2).connect(s4);
s1.connect(s3);

Above codes construct a topology graph:

A stream needs a transformer as a constructing parameter, or nothing is acceptable too.

new Stream(new Transformer())

By defining topological streams and transformers, you can describe how to build a project easily and clearly. The following is a complicated building process topology:

panto topology

A more typical configurable case:

module.exports = panto => {
	panto.setOptions({
    	cwd: __dirname,
	    src: 'src',
    	output: 'output' // not as same as src
	});

	require('load-panto-transformers')(panto);

	const srcJs = panto.pick('**/*.{js,jsx}').tag('js(x)').read();

	srcJs.babel(clientBabelOptions).write();

	srcJs.babel(serverBabelOptions).write();

	panto.pick('**/*.less').tag('less').read().less().write();

	// node_modules should be processed only once
	panto.pick('node_modules/**/*', true).tag('node_modules').copy();

	panto.rest().tag('others').ignore().copy();
}

API

Panto is available through API:

const panto = require('panto');

panto.setOptions({
    
});

panto.on('start', buildId => {})
    .on('flowstart', ({tag}, flowId) => {})
    .on('flowend', ({tag}, flowId) => {})
    .on('error', (err, buildId) => {})
    .on('complete', (files, buildId) => {})

panto.build().then(() => {
    panto.watch();
});

Options

  • cwd: string, current working directory, default process.cwd()
  • src: string, source directory, default '.'
  • output: output string, file directory, default 'output'
  • binary_resource: string, binary file extensions, e.g. 'zip,tar,jpg', default is same as binary-extensions
  • watch_ignore: array, ignored files when watching, e.g. '["/*.pyc", "/*.class"]', default is []

Boilerplate

Transformers

Some official transformers: