├── .gitignore ├── .npmignore ├── .travis.yml ├── README.md ├── index.js ├── lib ├── license.js └── pixify.js ├── package.json └── test ├── index.js ├── package.json └── src └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /test/bin -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .gitignore 3 | .travis.yml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "4" 5 | 6 | install: 7 | - npm install 8 | 9 | cache: 10 | directories: 11 | - node_modules 12 | 13 | script: 14 | - npm test -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pixify 2 | 3 | [![Build Status](https://travis-ci.org/pixijs/pixify.svg?branch=master)](https://travis-ci.org/pixijs/pixify) 4 | 5 | Browserify bundle process for PIXI libraries. 6 | 7 | This creates two build files, compressed and uncompressed. Both with sourcemaps and license headers. 8 | 9 | ## Installation 10 | 11 | ```bash 12 | npm install pixify --save-dev 13 | ``` 14 | 15 | ## Commandline Usage 16 | 17 | ```bash 18 | pixify --name [library-name] 19 | ``` 20 | 21 | For instance, 22 | ```bash 23 | pixify --name my-library 24 | ``` 25 | 26 | ### Options 27 | 28 | * **--name** or **-n** (required) The name of the output file and Browserify's `standalone` argument. 29 | * **--source** or **-s** (default: `./src/` Application source to build. 30 | * **--dest** or **-d** (default: `./bin/`) Destination folder for building. 31 | * **--exclude** or **-e** (optional) Folder names in `--source` to ignore, for custom builds. 32 | * **--outputName** or **-o** (optional) The name of the output file if different from `--name`. 33 | * **--license** or **-l** (default: `{pixify}/lib/license.js`) License template to use 34 | * **--watch** or **-w** (default: `false`) `true` to run watchify when running bundling. 35 | * **--minify** or **-m** (default: `true`) `false` or `--no-minify` to only generate the uncompressed version of the library 36 | * **--external** or **-x** (default: `true`) `false` or `--no-external` to not bundle external modules. 37 | * **--plugin** or **-p** (optiona) Additional plugin(s) to use for Browserify, such as tsify. 38 | * **--transform** for **-t** (optional) Addtional transform(s) to use for Browserify, such as babelify. 39 | 40 | ## API Usage 41 | 42 | Alternatively, use the Node API: 43 | 44 | ```js 45 | var pixify = require('pixify'); 46 | 47 | // Full verbose options 48 | pixify({ 49 | output: 'library.min.js', 50 | name: 'library', 51 | source: './src/', 52 | dest: './bin/', 53 | license: './lib/license.js', 54 | compress: true, 55 | external: true, 56 | watch: false 57 | }); 58 | 59 | // Short-hand with all defaults with callback 60 | pixify('library.min.js', function(){ 61 | // done! 62 | }); 63 | ``` 64 | 65 | ### Parameters 66 | 67 | * **options.output** (`String`) Output file name (e.g. "library.js") 68 | * **options.name** (`String`) Standalone name for Browserify (e.g. "library") 69 | * **options.compress** (`Boolean`, default: `true`) `true` to compress output 70 | * **options.source** (`String`, default: `"./src/"`) Output source name 71 | * **options.dest** (`String`, default: `"./bin/"`) Output folder 72 | * **options.license** (`String`, default: `"{pixify}/lib/license.js"`) License template 73 | * **options.exclude** (`String|String[]`) List of modules to ignore from output. Useful for creating custom builds. 74 | * **options.watch** (`Boolean`, default: `false`) `true` to run watchify when bundling. 75 | * **options.external** (`Boolean`, default: `true`) `false` to not bundle external modules. 76 | * **callback** (`Function`) Optional callback function when complete 77 | * **plugin** (`String|Array`) Additional plugin(s) to use for Browserify, such as tsify. 78 | * **transform** (`String|Array`) Addtional transform(s) to use for Browserify, such as babelify. 79 | 80 | ## License 81 | 82 | This content is released under the [MIT License](http://opensource.org/licenses/MIT). 83 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | "use strict"; 4 | 5 | const minimist = require('minimist'); 6 | const pixify = require('./lib/pixify'); 7 | 8 | // Get the commandline arguments 9 | const args = minimist(process.argv.slice(2), { 10 | alias: { 11 | e: 'exclude', 12 | d: 'dest', 13 | l: 'license', 14 | s: 'source', 15 | n: 'name', 16 | o: 'outputName', 17 | w: 'watch', 18 | x: 'external', 19 | p: 'plugin', 20 | t: 'transform', 21 | m: 'minify' 22 | }, 23 | boolean: [ 24 | 'watch', 25 | 'external', 26 | 'minify' 27 | ], 28 | string: [ 29 | 'name', 30 | 'dest', 31 | 'source', 32 | 'outputName', 33 | 'license', 34 | 'plugin', 35 | 'transform' 36 | ], 37 | default: { 38 | dest: './bin/', 39 | source: './src/', 40 | watch: false, 41 | external: true, 42 | minify: true 43 | } 44 | }); 45 | 46 | const outputName = args.outputName || args.name; 47 | 48 | if (!outputName) { 49 | console.log('> ERROR: Must include name for output.'); 50 | process.exit(1); 51 | } 52 | 53 | // Bundle and show the timestamps 54 | function bundle(options, callback) { 55 | // Build time isn't needed using watchify 56 | // time and size are generated automatically 57 | let startTime; 58 | if (!args.watch) { 59 | startTime = Date.now(); 60 | } 61 | options = Object.assign({}, options, args); 62 | pixify(options, function() { 63 | if (!args.watch) { 64 | // Display the output, on in non-watch mode 65 | const sec = (Date.now() - startTime) / 1000; 66 | console.log('> Built %s in %d seconds', options.output, sec); 67 | } 68 | callback(); 69 | }); 70 | } 71 | 72 | // Do the debug build 73 | bundle({ 74 | cli: true, 75 | compress: false, 76 | output: outputName + '.js' 77 | }, 78 | function() { 79 | // Don't do minify release when watching 80 | // it's too slow because of uglify 81 | if (!args.watch && args.minify) { 82 | // Do the release build 83 | bundle({ 84 | cli: true, 85 | compress: true, 86 | output: outputName + '.min.js' 87 | }, finish); 88 | } 89 | else { 90 | finish(); 91 | } 92 | }); 93 | 94 | // Adds an extra line 95 | function finish(){ 96 | console.log(''); 97 | } 98 | -------------------------------------------------------------------------------- /lib/license.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ${pkg.name} - v${pkg.version} 3 | * Compiled ${date} 4 | * 5 | * ${pkg.name} is licensed under the MIT License. 6 | * http://www.opensource.org/licenses/mit-license 7 | */ 8 | -------------------------------------------------------------------------------- /lib/pixify.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const browserify = require('browserify'); 4 | const source = require('vinyl-source-stream'); 5 | const buffer = require('vinyl-buffer'); 6 | const vfs = require('vinyl-fs'); 7 | const uglify = require('gulp-uglify'); 8 | const gulpif = require('gulp-if'); 9 | const header = require('gulp-header'); 10 | const sourcemaps = require('gulp-sourcemaps'); 11 | const preprocess = require('gulp-preprocess'); 12 | const path = require('path'); 13 | const watchify = require('watchify'); 14 | const fs = require('fs'); 15 | const chalk = require('chalk'); 16 | 17 | /** 18 | * Create the bundle 19 | * @function bundle 20 | * @param {Object|String} options The options or the output name 21 | * @param {String} options.output Output file name (e.g. "library.js") 22 | * @param {String} options.name Standalone name for Browserify (e.g. "library") 23 | * @param {Boolean} [options.compress=true] `true` to compress output 24 | * @param {String} [options.source='./src/'] Output source name (e.g. "./src/") 25 | * @param {String} [options.dest='./bin/'] Output folder (e.g. "./bin/") 26 | * @param {Boolean} [options.external=true] `true` to bundle external modules. 27 | * @param {Array|String} [options.exclude] List of folders to exclude. 28 | * @param {Function} [callback] Optional callback when complete 29 | */ 30 | module.exports = function(options, callback) { 31 | 32 | if (typeof options === "string") { 33 | options = { output: options }; 34 | } 35 | 36 | options = Object.assign({ 37 | compress: true, 38 | source: './src/', 39 | dest: './bin/', 40 | license: path.join(__dirname, 'license.js'), 41 | cli: false, 42 | watch: false, 43 | external: true, 44 | name: path.parse(options.output).name 45 | }, options); 46 | 47 | const bundler = browserify({ 48 | entries: options.source, 49 | standalone: options.name, 50 | bundleExternal: options.external, 51 | debug: true, 52 | cache: {}, 53 | packageCache: {} 54 | }); 55 | 56 | function done(err) { 57 | if (err) { 58 | if (options.cli) { 59 | console.log(chalk.red('> ERROR: %s'), err.message); 60 | } 61 | else { 62 | console.error(err.message); 63 | } 64 | } 65 | if (callback) { 66 | callback(err); 67 | } 68 | } 69 | 70 | if (options.watch) { 71 | bundler.plugin(watchify); 72 | } 73 | 74 | // Check for additional plugins 75 | let plugins = options.plugin; 76 | if (plugins) { 77 | if (!Array.isArray(plugins)) { 78 | plugins = [plugins]; 79 | } 80 | plugins.forEach(function(p) { 81 | bundler.plugin(p); 82 | }); 83 | } 84 | 85 | // Check for additional transforms 86 | let transforms = options.transform; 87 | if (transforms) { 88 | if (!Array.isArray(transforms)) { 89 | transforms = [transforms]; 90 | } 91 | transforms.forEach(function(tr) { 92 | bundler.transform(tr); 93 | }); 94 | } 95 | 96 | let license; 97 | 98 | try { 99 | license = fs.readFileSync(options.license, 'utf8'); 100 | } 101 | catch(e) { 102 | done(new Error('License file not found: ' + options.license)); 103 | return; 104 | } 105 | 106 | let packageInfo; 107 | 108 | try { 109 | packageInfo = require(path.resolve(process.cwd(), 'package.json')); 110 | } 111 | catch(e) { 112 | done(new Error('No package.json found in the current directory')); 113 | return; 114 | } 115 | 116 | // Exclude certain modules 117 | if (options.exclude) { 118 | let excludes = options.exclude; 119 | if (!Array.isArray(excludes)) { 120 | excludes = [excludes]; 121 | } 122 | excludes.forEach(function(exclude){ 123 | try { 124 | const excludePath = path.resolve(process.cwd(), options.source, exclude); 125 | bundler.ignore(require.resolve(excludePath)); 126 | if (options.cli) { 127 | console.log('> Ignoring module \'%s\'', exclude); 128 | } 129 | } 130 | catch(e){ 131 | if (options.cli) { 132 | console.log(chalk.yellow('> WARNING: Module not found for \'%s\''), exclude); 133 | } 134 | else { 135 | console.warn('Module not found for \'%s\'', exclude); 136 | } 137 | } 138 | }); 139 | } 140 | 141 | function rebundle() { 142 | return bundler.bundle() 143 | .on('error', done) 144 | .pipe(source(options.output)) 145 | .pipe(buffer()) 146 | .pipe(sourcemaps.init({loadMaps: true})) 147 | .pipe(preprocess({ 148 | context: { 149 | DEBUG: !options.compress, 150 | RELEASE: !!options.compress, 151 | VERSION: packageInfo.version 152 | } 153 | })) 154 | .pipe(gulpif(options.compress, uglify())) 155 | .pipe(header(license, { 156 | date: (new Date()).toUTCString().replace(/GMT/g, "UTC"), 157 | name: packageInfo.name, 158 | version: packageInfo.version, 159 | pkg: packageInfo, 160 | options: options 161 | })) 162 | .pipe(sourcemaps.write('./', { sourceRoot: '' })) 163 | .pipe(vfs.dest(options.dest)) 164 | .on('end', done); 165 | } 166 | bundler.on('update', rebundle); 167 | bundler.on('log', function(message) { 168 | if (options.cli) { 169 | console.log('>', message); 170 | } 171 | else { 172 | console.log(message); 173 | } 174 | }); 175 | rebundle(); 176 | }; 177 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pixify", 3 | "version": "1.9.0", 4 | "description": "Browserify bundle process for PIXI libraries", 5 | "main": "lib/pixify.js", 6 | "scripts": { 7 | "pretest": "npm run lint", 8 | "test": "mocha test/index.js", 9 | "lint": "jshint --reporter=node_modules/jshint-stylish index.js lib", 10 | "postversion": "git push && git push --tags" 11 | }, 12 | "bin": "index.js", 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/pixijs/pixify.git" 16 | }, 17 | "jshintConfig": { 18 | "esversion": 6, 19 | "node": true 20 | }, 21 | "keywords": [ 22 | "Browserify", 23 | "sourcemaps", 24 | "uglify", 25 | "bundle", 26 | "header", 27 | "license" 28 | ], 29 | "engines": { 30 | "node": ">=4.0" 31 | }, 32 | "author": "Matt Karl ", 33 | "license": "MIT", 34 | "bugs": { 35 | "url": "https://github.com/pixijs/pixify/issues" 36 | }, 37 | "homepage": "https://github.com/pixijs/pixify#readme", 38 | "dependencies": { 39 | "browserify": "^13.1.0", 40 | "chalk": "^1.1.3", 41 | "gulp-header": "^1.8.7", 42 | "gulp-if": "^2.0.1", 43 | "gulp-preprocess": "^2.0.0", 44 | "gulp-sourcemaps": "^1.6.0", 45 | "gulp-uglify": "^2.0.0", 46 | "minimist": "^1.2.0", 47 | "vinyl-buffer": "^1.0.0", 48 | "vinyl-fs": "^2.4.3", 49 | "vinyl-source-stream": "^1.1.0", 50 | "watchify": "^3.7.0" 51 | }, 52 | "devDependencies": { 53 | "jshint": "^2.9.2", 54 | "jshint-stylish": "^2.2.0", 55 | "mocha": "^3.0.2", 56 | "rimraf": "^2.5.4" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const pixify = require('../lib/pixify'); 4 | const rimraf = require('rimraf'); 5 | const assert = require('assert'); 6 | 7 | function validate(output, result){ 8 | const lib = require('./bin/' + output); 9 | assert.strictEqual(result, lib(), 'Library standalone should work'); 10 | } 11 | 12 | describe('pixify', function(){ 13 | before(function(){ 14 | process.chdir(__dirname); 15 | }); 16 | 17 | after(function(){ 18 | rimraf.sync('./bin'); 19 | }); 20 | 21 | it('should be debug mode', function(done){ 22 | const output = 'test.js'; 23 | pixify({ 24 | output: output, 25 | name: 'test', 26 | compress: false 27 | }, function(){ 28 | validate(output, true); 29 | done(); 30 | }); 31 | }); 32 | 33 | it('should be build in release mode', function(done){ 34 | const output = 'test.min.js'; 35 | pixify(output, function(){ 36 | validate(output, false); 37 | done(); 38 | }); 39 | }); 40 | }); -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0" 4 | } -------------------------------------------------------------------------------- /test/src/index.js: -------------------------------------------------------------------------------- 1 | module.exports = function(){ 2 | var result; 3 | 4 | // @if DEBUG 5 | result = true; 6 | // @endif 7 | 8 | // @if RELEASE 9 | result = false; 10 | // @endif 11 | 12 | return result; 13 | }; --------------------------------------------------------------------------------