{"id":16185774,"url":"https://github.com/forbeslindesay/browserify-middleware","last_synced_at":"2025-05-15T13:08:30.154Z","repository":{"id":7461208,"uuid":"8806972","full_name":"ForbesLindesay/browserify-middleware","owner":"ForbesLindesay","description":"express middleware for browserify, done right","archived":false,"fork":false,"pushed_at":"2022-01-27T21:50:26.000Z","size":247,"stargazers_count":380,"open_issues_count":21,"forks_count":60,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-15T13:08:24.261Z","etag":null,"topics":["browserify","express","gzip"],"latest_commit_sha":null,"homepage":"http://browserify.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ForbesLindesay.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-03-15T19:10:45.000Z","updated_at":"2024-12-18T02:30:49.000Z","dependencies_parsed_at":"2022-09-01T12:12:23.963Z","dependency_job_id":null,"html_url":"https://github.com/ForbesLindesay/browserify-middleware","commit_stats":null,"previous_names":[],"tags_count":54,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ForbesLindesay%2Fbrowserify-middleware","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ForbesLindesay%2Fbrowserify-middleware/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ForbesLindesay%2Fbrowserify-middleware/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ForbesLindesay%2Fbrowserify-middleware/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ForbesLindesay","download_url":"https://codeload.github.com/ForbesLindesay/browserify-middleware/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254346624,"owners_count":22055808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browserify","express","gzip"],"created_at":"2024-10-10T07:15:15.408Z","updated_at":"2025-05-15T13:08:25.145Z","avatar_url":"https://github.com/ForbesLindesay.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# browserify-middleware\n\n\u003cimg src=\"http://i.imgur.com/6cyfaYS.png\" align=\"right\" /\u003e\n\n**middleware for browserify v2 with sensible defaults for the ultimate in ease of use**\n\nIn addition to the basics, browserify-middleware has the following features out of the box:\n\n - source-maps are automatically enabled for debugging\n - automatically rebuilds whenever files change in development\n - minification automatically enabled for production\n - gzip automatically enabled for production\n - etags for caching automatically enabled for production\n\nWith the exception of serving up directories (which requires `req.path` from express) everything is entirely framework independent.  Simply pass in `req` `res`, and a `callback` that will only be called in the event of an error.\n\nIf you think I've missed something, be sure to open an issue or submit a pull request.\n\n[![Build Status](https://img.shields.io/travis/ForbesLindesay/browserify-middleware/master.svg)](https://travis-ci.org/ForbesLindesay/browserify-middleware)\n [![Coverage Status](https://img.shields.io/coveralls/ForbesLindesay/browserify-middleware/master.svg?style=flat)](https://coveralls.io/r/ForbesLindesay/browserify-middleware?branch=master)\n[![Dependency Status](https://img.shields.io/david/ForbesLindesay/browserify-middleware.svg)](https://david-dm.org/ForbesLindesay/browserify-middleware)\n[![NPM version](https://img.shields.io/npm/v/browserify-middleware.svg)](https://www.npmjs.com/package/browserify-middleware)\n\n\u003ca target='_blank' rel='nofollow' href='https://app.codesponsor.io/link/gg9sZwctSLxyov1sJwW6pfyS/ForbesLindesay/browserify-middleware'\u003e\n  \u003cimg alt='Sponsor' width='888' height='68' src='https://app.codesponsor.io/embed/gg9sZwctSLxyov1sJwW6pfyS/ForbesLindesay/browserify-middleware.svg' /\u003e\n\u003c/a\u003e\n\n## Usage\n\nSee `example` directory for a complete server\n\n```javascript\nvar browserify = require('browserify-middleware');\nvar express = require('express');\nvar app = express();\n\n//provide browserified versions of all the files in a directory\napp.use('/js', browserify(__dirname + '/client/dir'));\n\n//provide a browserified file at a path\napp.get('/js/file.js', browserify(__dirname + '/client/file.js'));\n\n//provide a bundle exposing `require` for a few npm packages.\napp.get('/js/bundle.js', browserify(['hyperquest', 'concat-stream']));\n\n//provide a bundle for a few npm packages plus run main.js\napp.get('/js/bundle.js', browserify(['hyperquest', 'concat-stream', {__dirname + '/client/main.js': {run: true}}]));\n\napp.listen(3000);\n```\n## Multiple Bundles Example\n\nMultiple bundles can sometimes lead to better caching performance.  If you had multiple different JavaScript modules in `./client` that all depended on `hyperquest` and `concat-stream` and were used on different pages, you may want to split those two modules into separate files so that they are only loaded once for someone browsing arround the site:\n\n```javascript\nvar shared = ['hyperquest', 'concat-stream'];\napp.get('/js/bundle.js', browserify(shared));\napp.use('/js', browserify('./client', {external: shared}))\n```\n\nThen on your HTML pages you can just have:\n\npage1.html\n```html\n\u003cscript src=\"/js/bundle.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"/js/beep.js\"\u003e\u003c/script\u003e\n```\n\npage2.html\n```html\n\u003cscript src=\"/js/bundle.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"/js/boop.js\"\u003e\u003c/script\u003e\n```\n\nThis way, booth `beep.js` and `boop.js` can `require` the shared modules (`hyperquest` and `concat-stream`) but they aren't actually contained within that file.\n\n## API\n\n### `browserify('./path/to/file.js'[, options])`\n\nReturn the middleware to serve a browserified version of the file.  The file path is relative to the calling module, not to `process.cwd()`.\n\n### `browserify('./path/to/directory/'[, options])`\n\nReturn the middleware to serve a browserified version of all the files in a directory.  The directory path is relative to the calling module, not to `process.cwd()`.\n\n### `browserify(['module-a', 'module-b'][, options])`\n\nReturn middleware that will expose `require` for each of the modules in the array.  This will work even if those modules are also in the `external` array.\n\n#### `browserify([{'module-d': {expose: 'dee'}}][, options])`\n\nRequire `module-d` with custom options (to be passed on to browserify).  In this case `module-d` will be exposed as `dee`.  This can be mixed and matched with plain strings.  Note that these modules must not appear in the `external` array.\n\n### `options` / `settings`\n\nThe `options` passed to each middleware function override the defaults specified in `settings`.\n\nSetings has two properties `settings.production` and `settings.development` which specify the default settings for each environment.  The current environment is specified by `settings.mode` and defaults to `process.env.NODE_ENV || 'development'`\n\nProduction defaults:\n\n```javascript\nproduction.cache = true; // equivalent to \"public, max-age=60\"\nproduction.precompile = true;\nproduction.minify = true;\nproduction.gzip = true;\nproduction.debug = false;\n```\n\nTo update:\n\n```javascript\nbrowserify.settings.production('cache', '7 days');\n```\n\nDevelopment defaults:\n\n```javascript\ndevelopment.cache = 'dynamic';\ndevelopment.precompile = false;\ndevelopment.minify = false;\ndevelopment.gzip = false;\ndevelopment.debug = true;\n```\n\nTo update:\n\n```javascript\nbrowserify.settings.development('gzip', true);\n```\n\nThe following defaults are the same for production and development:\n\n```javascript\nexternal = [];\nignore = [];\nignoreMissing = false;\ntransform = [];\ninsertGlobals = false;\ndetectGlobals = true;\nstandalone = false;\ngrep = /\\.js$/\n```\n\nTo update:\n\n```javascript\nbrowserify.settings('external', ['hyperquest']);\n//or\nbrowserify.settings({\n  ignoreMissing: true,\n  insertGlobals: true,\n  transform: ['rfileify']\n});\n```\n\nCustom Environments:\n\nYou can also create a new custom environment:\n\n```javascript\nvar test = browserify.settings.env('test');\ntest('minify', true);\n//or\ntest({\n  debug: true\n});\n```\n\n#### cache\n\nThe cache setting determines how long content can be cached in the client's web browsers (and any caching proxies) and whether or not to cache bundles server side.  Any value other than `false` will result in them being cached server side.  The `'dynamic'` cache option is special.  It works like watchify and only re-compiles the files that have changed.  This is the fastest option for development.  It does not enable any client side caching.\n\nIf cache is `true` the client will recieve Cache Control of `\"public, max-age=60\"`, which caches for 60 seconds.\n\nIf cache is a `string` in the form accepted by [ms](https://npmjs.org/package/ms) it becomes: `\"public, max-age=\" + (ms(cache)/1000)`\n\nIf cache is a `number`, it is treated as being in milliseconds so becomes: `\"public, max-age=\" + (cache/1000)`\n\nIf cache is an `object` of the form `{private: true || false, maxAge: '10 minutes'}` it becomes the apropriate string.\n\nIf cache is any other `string` it will be sent directly to the client.\n\n**N.B.** that if caching is enabled, the server never times out its cache, no matter what the timeout set for the client.\n\n#### precompile\n\nThe precompile setting enables bundles to be precompiled/built and readily cached immediately on server startup. This option is not available when using browserify with a directory.  If `precompile` is set to `true`, the bundle will be compiled \u0026 cached at server start.\n\n```javascript\n// Precompile a browserified file at a path\napp.get('/js/file.js', browserify('./client/file.js', {\n  cache: true,\n  precompile: true\n}));\n\n// Precompile a bundle exposing `require` for a few npm packages.\napp.get('/js/bundle.js', browserify(['hyperquest', 'concat-stream'], {\n  cache: true,\n  precompile: true\n}));\n```\n\n**N.B.**  It only makes sense to use precompiling when caching is enabled. If caching is disabled, no precompiling will happen.\n\n#### minify\n\nIf `minify` is `true`, UglifyJS will be used to minify the resulting code.  This is `true` by default in production.  If you set it to an object, the object will be passed to uglify-js as [options](https://github.com/mishoo/UglifyJS2#the-simple-way):\n\n - `warnings` (default `false`) - pass `true` to display compressor warnings\n - `mangle` (default `true`) - pass `false` to skip mangling names\n - `output` (default `null`) - pass an object to specify additional [output options](http://lisperator.net/uglifyjs/codegen). The defaults are optimized for best compression.\n - `compress` (default `{}`) - pass `false` to skip compressing entirely.  Pass an object to specify custom [compressor options](http://lisperator.net/uglifyjs/compress).\n\n#### gzip\n\nIf `gzip` is `true`, GZip will be enabled when clients support it.  This increases the memory required for caching by aproximately 50% but the speed boost can be considerable.  It is `true` by default in production.\n\n#### debug\n\nIf `debug` is `true`, a source map will be added to the code.  This is very useful when debugging.  `debug` is `false` in production.\n\n#### basedir\n\nIf `debug` is `true` you can provide a `string` pathname for basedir and the paths of your files in the source-map will be displayed relative to that file.  This is great for hiding the details of your local file system or tidying up the debugging of a large app.\n\n#### plugins\n\nAn array of objects of the form `{plugin: 'name', options: {object}}`.\n\n#### grep\n\nThe regular expression, something like [`/\\.(?:js|coffee|ls)$/`](http://tinyurl.com/pawk7cu), that a filename must pass to be served using browserify from a directory.\n\n#### hooks\n\nThere are a number of hooks that you can implement to modify the source at a few stages of processing.\n\ne.g.\n\n```js\napp.get('/index.js', browserify('/index.js', {\n  preminify: function (source) {\n    return angularJsMinifier(source);\n  }\n}));\n```\n\nThe available hooks are currently:\n\n - postcompile - fires after compilation, but before any minfication/gzipping\n - preminify - fires before minfication (but only if minify is enabled)\n - postminify - fires after minfication (but only if minify is enabled)\n\nThe main use case you might have for this would be adding extra minfication steps that are able to make additional assumptions about your code.  These hooks can return either a string or a Promise for a string.\n\n#### Others\n\nThe remaining settings are all passed through to browserify, you should look at [the browserify readme](https://github.com/substack/node-browserify) if you want to know more:\n\n- `options.external` - an array of module names that will be required from external bundles (see [browserify/multiple bundles](https://github.com/substack/node-browserify#multiple-bundles)) (default: `[]`)\n- `options.ignore` - an aray of module names that are prevented from showing up in the output bundle (default: `[]`)\n- `options.ignoreMissing` - set to `true` to ignore errors when a module can't be found (default: `false`).\n- `options.transform` - an array of transforms to transform top level modules (default: `[]`). Each item can be:\n    - `\"transform-name\"` - the npm name of the transform\n    - `transformFunction` - the transform function\n    - `[\"transform-name\" | tranformFunction, {option1: true, ...}]` - the transform and some options\n- `options.insertGlobals` - set to true to always insert `process`, `global` etc. without analysing the AST for faster builds but larger bundles (Note that `options.minify` may cause the globals to be removed again anyway) (default: false)\n- `options.detectGlobals` - set to false to skip adding `process`, `global` etc.  Setting this to false may break more npm modules (default: true).\n- `options.noParse` - an array of module names that should not be parsed for `require` statements of node.js style globals, can speed up loading things like jQuery that are huge but never use `require`.\n- `options.standalone` - generate a standalone build (in a [umd](https://github.com/ForbesLindesay/umd) wrapper) with this name, you probably don't want this.\n- `options.extensions` - an array of optional extra extensions for the module lookup machinery to use when the extension has not been specified. By default browserify considers only `.js` and `.json` files in such cases.\n- `options.resolve` - lets you override the default resolution algorithm (e.g. use browserify to compile component modules)\n- `options.basedir` - this shouldn't be needed as browserify-middleware already resolves to absolute paths.\n\nYou can optionally pass a single item instead of an array to any of the options that take an array.\n\n## License\n\n  MIT\n\n  If you find it useful, a donation via [gittip](https://www.gittip.com/ForbesLindesay) would be appreciated.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fforbeslindesay%2Fbrowserify-middleware","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fforbeslindesay%2Fbrowserify-middleware","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fforbeslindesay%2Fbrowserify-middleware/lists"}