Giter Site home page Giter Site logo

browserify-middleware's Introduction

browserify-middleware

middleware for browserify v2 with sensible defaults for the ultimate in ease of use

In addition to the basics, browserify-middleware has the following features out of the box:

  • source-maps are automatically enabled for debugging
  • automatically rebuilds whenever files change in development
  • minification automatically enabled for production
  • gzip automatically enabled for production
  • etags for caching automatically enabled for production

With 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.

If you think I've missed something, be sure to open an issue or submit a pull request.

Build Status Coverage Status Dependency Status NPM version

Sponsor

Usage

See example directory for a complete server

var browserify = require('browserify-middleware');
var express = require('express');
var app = express();

//provide browserified versions of all the files in a directory
app.use('/js', browserify(__dirname + '/client/dir'));

//provide a browserified file at a path
app.get('/js/file.js', browserify(__dirname + '/client/file.js'));

//provide a bundle exposing `require` for a few npm packages.
app.get('/js/bundle.js', browserify(['hyperquest', 'concat-stream']));

//provide a bundle for a few npm packages plus run main.js
app.get('/js/bundle.js', browserify(['hyperquest', 'concat-stream', {__dirname + '/client/main.js': {run: true}}]));

app.listen(3000);

Multiple Bundles Example

Multiple 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:

var shared = ['hyperquest', 'concat-stream'];
app.get('/js/bundle.js', browserify(shared));
app.use('/js', browserify('./client', {external: shared}))

Then on your HTML pages you can just have:

page1.html

<script src="/js/bundle.js"></script>
<script src="/js/beep.js"></script>

page2.html

<script src="/js/bundle.js"></script>
<script src="/js/boop.js"></script>

This 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.

API

browserify('./path/to/file.js'[, options])

Return the middleware to serve a browserified version of the file. The file path is relative to the calling module, not to process.cwd().

browserify('./path/to/directory/'[, options])

Return 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().

browserify(['module-a', 'module-b'][, options])

Return 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.

browserify([{'module-d': {expose: 'dee'}}][, options])

Require 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.

options / settings

The options passed to each middleware function override the defaults specified in settings.

Setings 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'

Production defaults:

production.cache = true; // equivalent to "public, max-age=60"
production.precompile = true;
production.minify = true;
production.gzip = true;
production.debug = false;

To update:

browserify.settings.production('cache', '7 days');

Development defaults:

development.cache = 'dynamic';
development.precompile = false;
development.minify = false;
development.gzip = false;
development.debug = true;

To update:

browserify.settings.development('gzip', true);

The following defaults are the same for production and development:

external = [];
ignore = [];
ignoreMissing = false;
transform = [];
insertGlobals = false;
detectGlobals = true;
standalone = false;
grep = /\.js$/

To update:

browserify.settings('external', ['hyperquest']);
//or
browserify.settings({
  ignoreMissing: true,
  insertGlobals: true,
  transform: ['rfileify']
});

Custom Environments:

You can also create a new custom environment:

var test = browserify.settings.env('test');
test('minify', true);
//or
test({
  debug: true
});

cache

The 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.

If cache is true the client will recieve Cache Control of "public, max-age=60", which caches for 60 seconds.

If cache is a string in the form accepted by ms it becomes: "public, max-age=" + (ms(cache)/1000)

If cache is a number, it is treated as being in milliseconds so becomes: "public, max-age=" + (cache/1000)

If cache is an object of the form {private: true || false, maxAge: '10 minutes'} it becomes the apropriate string.

If cache is any other string it will be sent directly to the client.

N.B. that if caching is enabled, the server never times out its cache, no matter what the timeout set for the client.

precompile

The 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 & cached at server start.

// Precompile a browserified file at a path
app.get('/js/file.js', browserify('./client/file.js', {
  cache: true,
  precompile: true
}));

// Precompile a bundle exposing `require` for a few npm packages.
app.get('/js/bundle.js', browserify(['hyperquest', 'concat-stream'], {
  cache: true,
  precompile: true
}));

N.B. It only makes sense to use precompiling when caching is enabled. If caching is disabled, no precompiling will happen.

minify

If 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:

  • warnings (default false) - pass true to display compressor warnings
  • mangle (default true) - pass false to skip mangling names
  • output (default null) - pass an object to specify additional output options. The defaults are optimized for best compression.
  • compress (default {}) - pass false to skip compressing entirely. Pass an object to specify custom compressor options.

gzip

If 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.

debug

If debug is true, a source map will be added to the code. This is very useful when debugging. debug is false in production.

basedir

If 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.

plugins

An array of objects of the form {plugin: 'name', options: {object}}.

grep

The regular expression, something like /\.(?:js|coffee|ls)$/, that a filename must pass to be served using browserify from a directory.

hooks

There are a number of hooks that you can implement to modify the source at a few stages of processing.

e.g.

app.get('/index.js', browserify('/index.js', {
  preminify: function (source) {
    return angularJsMinifier(source);
  }
}));

The available hooks are currently:

  • postcompile - fires after compilation, but before any minfication/gzipping
  • preminify - fires before minfication (but only if minify is enabled)
  • postminify - fires after minfication (but only if minify is enabled)

The 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.

Others

The remaining settings are all passed through to browserify, you should look at the browserify readme if you want to know more:

  • options.external - an array of module names that will be required from external bundles (see browserify/multiple bundles) (default: [])
  • options.ignore - an aray of module names that are prevented from showing up in the output bundle (default: [])
  • options.ignoreMissing - set to true to ignore errors when a module can't be found (default: false).
  • options.transform - an array of transforms to transform top level modules (default: []). Each item can be:
    • "transform-name" - the npm name of the transform
    • transformFunction - the transform function
    • ["transform-name" | tranformFunction, {option1: true, ...}] - the transform and some options
  • 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)
  • options.detectGlobals - set to false to skip adding process, global etc. Setting this to false may break more npm modules (default: true).
  • 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.
  • options.standalone - generate a standalone build (in a umd wrapper) with this name, you probably don't want this.
  • 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.
  • options.resolve - lets you override the default resolution algorithm (e.g. use browserify to compile component modules)
  • options.basedir - this shouldn't be needed as browserify-middleware already resolves to absolute paths.

You can optionally pass a single item instead of an array to any of the options that take an array.

License

MIT

If you find it useful, a donation via gittip would be appreciated.

browserify-middleware's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

browserify-middleware's Issues

Multiple bundles don't work with browserify-shim

Splitting up the bundles does not work with modules that are shimmed with browserify-shim.

I have a repo illustrating this at https://github.com/gabegorelick/browserify-shim-multiple. Note that everything works fine when done with browserify directly. It also works fine if only non-shimmed modules are included in the external bundle, e.g. if we only exclude jquery (the one from npm). It's only when you try to exclude shimmed modules, e.g. angular, and include them in a separate bundle that things break. And of course, everything works fine as a single bundle.

See thlorenz/browserify-shim#40 for more context.

Serving directories with transformations

I use browserify-middleware in conjunction with the liveify transformation to serve browserify LiveScript files. For individual files this works fine; however, when serving directories it is broken. My setup is as follows:

var browserify = require('browserify-middleware')

browserify.settings('grep', /\.[jl]s$/)
app.use(
  "/js",
  browserify(
    __dirname + "public/ls/",
    {transform: ['liveify']}
  )
)

Then for example I would like /js/effects.js to compile public/ls/effects.ls into JavaScript, and then run browserify on the result. However, the browserify directory middleware is written in such a way that I need the URL to be /js/effects.ls in order for this work.

"TypeError: undefined is not a function" with transform reactify and expose

'''
var browserify = require('browserify-middleware');
var reactify = require('reactify');
browserify.settings('transform', ['reactify']);

router.get('bundles/my_component.js', browserify([{'path-to-my-component': {expose: 'MyComponent'}}])
'''

yield the following error:

'''
./node_modules/browserify-middleware/node_modules/browserify/node_modules/browser-resolve/node_modules/resolve/lib/async.js:29
if (x.match(/^(?:..?/|/|([A-Za-z]:)?)/)) {
^
TypeError: undefined is not a function
'''

Note that there are no error when I don't specify an expose option.
'''
router.get('bundles/my_component.js', browserify (['path-to-my-component']))
'''

Support per-module options

The docs show bundling multiple modules like this:

app.get('/js/bundle.js', browserify(['hyperquest', 'concat-stream']));

The trouble is that I need to send per-module options so that I can give a target for remapped modules.

// we could support targets, like this:
app.get('/js/bundle.js', browserify([
  {'hyperquest':'hyperquest-browserify'},
  'concat-stream'
]));
// or, maybe any arbitrary options with something like this:
app.get('/js/bundle.js', browserify([
  {module:'hyperquest-browserify', options:{target:'hyperquest'}},
  'concat-stream'
]));

Thoughts?

Require coffeescript module doesn't work correctly after update from 2.6 to 3

Hi,

I have a node_modules dir with modules written in iced-coffeescript. And i do

require('module-written-in-coffee')

in the clientside code.
It worked perfectly fine before i have updated it to 3.0. Now it treats the required modules as js no matter what transformers i use.
My node config is

.use('/app.js', browserify(clientside_path + '/app.coffee', {transform : ['icsify']}))

Thats actually cost me about 4 hours of time to figure out.

Overhead of the middleware compared with fs

Hi,

I open this as an issue because I don't see any other means to ask my question.
What is the overhead of browserifying on the go, as a middleware? I assume that accessing the browserifyed file via file system is faster than browserifiying and then serving the file.
Do you have any benvhmarks in that regards?
Please let me know, also if there is a better place to ask the question I'm happy to post my question there as well.

Thanks

Support different basedir per browserify() call

NOTE: Created pull request #19 for this issue. Should have done that first... sorry.

I have an application structure where the express server is being instantiated in a different module from the handlers and the handlers are injected. Basically something like this:

+--app
    \
     +--http-server
     |  \
     |   +--express 
     +--handler
        \
         +--dependencies

Because the module search is relative to __dirname of the caller (which in fact is the module that creates the express-app) browserify-middleware isn't able to pull in the browser dependencies from the other branch.

A "basedir"-option on the browserify() call would solve that problem, e.g.:

app.use("/js/base.js", browserify(["dependency1", "dependency2"], {
    basedir : __dirname
  });

How to use non-commonjs library with browserify?

I want to use OpenLayers with borowserify-middleware, here are my code files app.js, main.js and index.html

I am able to display map properly, but there are few issues regarding the proper usage of browserify-middleware

  • when downloaded in browser, main.js file size is double of the original files (main.js + OpenLayers.js), so it takes too much time to load. Why the file size is double? there is some encoded text at end of the file.
  • how to define non-commonjs library as external? I followed the instructions as here but could not achieve it. I have added {module.exports = OpenLayers} in the end of OpenLayers.js

Converting DOM Element References as Global Variables

When I use browserify-middleware all DOM elements references are getting converted to global variables. If a div id is 'mydiv' that can be accessed as window.mydiv.

"DOM Element References as Global Variables" is part of html specification (http://tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/).

But if I don't use browserify-middleware then elements ids are not mapped as global variables.
So is there any solution so that we can avoid this mapping at browser.

Gagan

When will 6.0.0 be released? Precompile option in 5.0.1 is broken

Precompile doesn't seem to work in the browserify-middleware currently available on npm. I can specify a console.log in the cachedCompile method to see that it does try to precompile, but when you hit the middleware with the exact path, it calls compile again. It seems like the only place where the cache key is being set is in the response handler so calling cachedCompile beforehand would never have any effect. I tested 6.0.0 and it seems to be working, so maybe this is a better & quicker fix?

compile.js console.dir calls pollute stdout

console.dir(key);

These statements are showing up on my console for the configuration below. If these are not otherwise important, could you just remove them or comment them out?

var bmwOptions = null;

if (!config.browserifyDebug) {
  bmwOptions = {
    cache: 1000 * 60 * 60 * 24 * 7, //1 week in milliseconds
    //don't mangle due to angularjs Function.toString() dependency injection
    minify: {mangle: false}
  };
}

function setup(app) {
  app.get("/browser.js", bmw([
    {"app/browser/navigation": {"entry": true}},
    "app/browser/career",
    "app/browser/home",
    "app/browser/plusParty",
    "app/browser/post",
    "app/browser/viewGallery"
  ], bmwOptions));
}

Alias modules?

Hi :)
Is there a way to rename a bundled module? I see that the ability exists in the straight browserify command line docs like so:

browserify -r ./my-file.js:my-module > bundle.js

which (I am pretty sure) allows us to do this client side:

require('my-module')

I can't seem to find the equivalent via api that might work for browserify-middleware? Like something along the lines of

app.get('bundle.js', browserify('./path/to/some-module', {alias: 'newName'}))

allowing this client side:

require('newName')

Thanks for any advice,
Aaron

Cache munging causing failures with external

The following doesn't work:

app.use('/client/twbs.js', browserify(require.resolve('twbs'), {}));
app.use('/client', browserify('./client', {
  external: ['twbs']
}));

but the following does:

app.use('/client/twbs.js', browserify(require.resolve('twbs'), {
  cache: false
}));
app.use('/client', browserify('./client', {
  external: ['twbs']
}));

Support any env (not just `development` and `production`)

If you use any NODE_ENV besides development or production (eg test), then browserify-middleware crashes with a nasty message: Object.keys called on non-object from here:

https://github.com/ForbesLindesay/browserify-middleware/blob/master/lib/settings.js#L52

I think there should just be default settings, and then these can be overridden by env-specific settings if need be.

A workaround for now is:

if (process.env.NODE_ENV !== 'production')
  browserify.settings('mode', 'development')

Fingerprinting?

Has anyone implemented fingerprinting in order to cache resources longer / forever?

I'm going to take a peek in a few days likely, and could contribute back if there's interest.

Add support for array of paths

Would it be possible to add support for arrays of paths?
Like so:

var files = ['./client/app.js', './other/index.js'];
app.get('/js/app.min.js', browserify(files));

Should show error messages, not crash node.js

Currently if there's syntax error in file node.js will crash with error messages in console.

Maybe it would be better (at least in development) to show error messages in console and in http request for js file, but not crash the server.

TypeError when noParse is a boolean

What happens

browserifyMiddleware([/* array of libs */], {noparse: true});

throws a TypeError: Arguments to path.resolve must be strings.

What's supposed to happen

When noParse is true then nothing in the bundle is parsed. See https://github.com/substack/node-browserify/blob/89113a205307cae1232a12f8c183fbea83d21543/index.js#L437. Unfortunately, browserify-shim wraps noParse in an array, which browserify doesn't like, since true is not a filename.

Is there a reason this argument isn't passed straight through to browserify?

Maximum call stack size exceeded

On about every 2-5 reloads the server crashes with following error message:

(null):0
(null)

RangeError: Maximum call stack size exceeded

npm ERR! Darwin 14.3.0
npm ERR! argv "node" "/usr/local/bin/npm" "start"
npm ERR! node v0.12.2
npm ERR! npm  v2.7.6
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `cake start`
npm ERR! Exit status 7
npm ERR!
npm ERR! Failed at the [email protected] start script 'cake start'.
npm ERR! This is most likely a problem with the Lowfab package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     cake start
npm ERR! You can get their info via:
npm ERR!     npm owner ls Lowfab
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/adrian/Projects/lowfab/npm-debug.log

The npm-debug.log:

0 info it worked if it ends with ok
1 verbose cli [ 'node', '/usr/local/bin/npm', 'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose node symlink /usr/local/bin/node
5 verbose run-script [ 'prestart', 'start', 'poststart' ]
6 info prestart [email protected]
7 info start [email protected]
8 verbose unsafe-perm in lifecycle true
9 info [email protected] Failed to exec start script
10 verbose stack Error: [email protected] start: `cake start`
10 verbose stack Exit status 7
10 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:213:16)
10 verbose stack     at EventEmitter.emit (events.js:110:17)
10 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:14:12)
10 verbose stack     at ChildProcess.emit (events.js:110:17)
10 verbose stack     at maybeClose (child_process.js:1015:16)
10 verbose stack     at Process.ChildProcess._handle.onexit (child_process.js:1087:5)
11 verbose pkgid [email protected]
12 verbose cwd /Users/adrian/Projects/lowfab
13 error Darwin 14.3.0
14 error argv "node" "/usr/local/bin/npm" "start"
15 error node v0.12.2
16 error npm  v2.7.6
17 error code ELIFECYCLE
18 error [email protected] start: `cake start`
18 error Exit status 7
19 error Failed at the [email protected] start script 'cake start'.
19 error This is most likely a problem with the Lowfab package,
19 error not with npm itself.
19 error Tell the author that this fails on your system:
19 error     cake start
19 error You can get their info via:
19 error     npm owner ls Lowfab
19 error There is likely additional logging output above.
20 verbose exit [ 1, true ]

This error was just introduced recently.
With version ^4.0.0 it worked without any problems.

Any idea what's going on?

Using reactify with the --es6 flag

Hi sorry if it's an obvious question but I've been digging int he code that calls the transformers and can not see how to send this option to the transformer I'm using (reactify). Probable I need to configure the transformer in a different way but still not sure how to set the parameter.

This is my current code. How can I set options on that particular transformer?, is it possible the reactify API is not compatible for setting the option?.

The option I need to set is '--es6', which I guess will become {es6: true}

var browserify = require('browserify-middleware');
browserify.settings({
  transform: ['reactify'],
  extensions: ['.js', '.jsx'],
  grep: /\.jsx?$/
})

Thanks!

Syntax errors don't show details about actual error

Any syntax error will just re-throw the exception, which will be coming from esprima.js, and break the server:

/node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:3817
            throw e;
                  ^
Error: Line 17: Unexpected identifier
    at throwError (/node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:1456:21)
    at throwUnexpected (/node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:1500:13)
    at expect (/node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:1523:13)
    at parseObjectInitialiser (/node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:1740:17)
    at parsePrimaryExpression (/node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:1810:20)
    at /node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:3574:38
    at trackLeftHandSideExpressionAllowCall (/node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:3478:61)
    at parsePostfixExpression (/node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:1927:20)
    at /node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:3574:38
    at parseUnaryExpression (/node_modules/envify/node_modules/falafel/node_modules/esprima/esprima.js:1997:16)

See browserify/browserify#308, for example.

options.noParse is being ignored

in nodejs app.js I define:

app.get('/bundle.js', browserify('main.js', {noParse: ['jquery']}));

but noParse is being ignored

I debugged the code. I fount that in "send.js" file,
in function "bundleFile" there is a call to "browserify" function
but "browserify" do nothing with the second parameter given by "bundleFile"

I have changed the content of "bundleFile" to this:

var opts = { entries: [ path ], noParse: options.noParse };
return browserify(opts);

then it works. maybe more need to be changed in other places for other cases

{cache: 'dynamic'} no longer seems to work

With the following config, I get a full rebuild on every page load, even if no changes have been made:

var assert = require('assert');
assert(process.env.NODE_ENV === 'development');

app.use('/scripts/', browserify('src/app/scripts/', {
  cache: 'dynamic',
  noParse: ['jquery'],
  transform: [
    'reactify',
    'envify',
  ],
}));

Read package.json browserify.transform setting for default

I have my browserify transform array configured in my project's package.json under the browserify.transform property path. I currently have to add code to copy those settings into browserify-middleware. I also found it somewhat surprising that it seems like with NODE_ENV=production my transform array from package.json IS being processed (using "brfs" and "browserify-shim" and it's working fine), but if NODE_ENV=development the transform array is NOT being processed and thus my code is breaking. It seems like whether you think package.json should be consulted or not, either way it should be consistent regardless of NODE_ENV.

Passing options to transforms

Some transforms allow options to be passed to them, and this is supported in browserify command line and API, but not (yet anyway) in browserify-middlware.

Here's the line that's interesting: https://github.com/ForbesLindesay/browserify-middleware/blob/master/lib/compile.js#L96

Options can be a hash passed as the first argument to transform([options], transform). Question is, how should they be specified in the browserify-middleware API?

The obvious thing to do is supply an array, with the options and string/function, or just a string/function:

options.transforms = [[{relativeUrls: true}, 'lessify'], 'html2js']

Unless you have a better idea?

Happy to make a pull request, just wanted to check with you before I went ahead.

Module with relative sub-requires

Hi,

I'm trying to browserify the following library, which I have seen work well in Node and on the client-side before: https://github.com/evilstreak/markdown โ€” I essentially define the following mapping in my express app:

app.get('/public/markdown/markdown.js', browserify(['markdown']))

Now, when I trying to load another browserified file which depends upon the markdown module, the browser logs an error in the console pointing to line 2 of index.js โ€” the error message simply indicates the ./markdown module cannot be found.

Don't do the confusing relative-to-current-module thing

I know it's kind of nice, but this is the only package that does it, so it gets really confusing to use browserify-middleware alongside other packages. Node's default semantics, across basically everything that accepts a path, is to effectively do path.resolve(givenPath), i.e. resolve relative to the CWD. Breaking this pattern is very weird.

Accept a browserify bundle.

I think a more convenient method for supporting the full browserify API is to accept a builder function:

var bmid = require('browserify-middleware');
var browserify = require('browserify');
var express = require('express');
var app = express();

app.use('/js/bundle.js', bmid(function() {
  return browserify('beep');
}));

app.listen(3000);

Pre-compress hook?

I am currently using this project for an Angular.js app (Express on the back-end) and I would like to also use https://github.com/btford/ngmin for when the bundle file is minified for production.

I pre-minify function with the bundle contents as a parameter would be ideal but I am willing to explore other solutions.

Any other possible solutions would be greatly appreciated.

Thoughts?

example has typo

app.get('/js/bundle.js', browserify(['hyperquest', 'concat-stream', {'./client/main.js': {run: true}]}));

] closes before }

error with envify

I'm trying to use the envify transform as follows:

browserify('./client/index.js', {
  transform: [envify({
    SOME_ENV: process.env.SOME_ENV
  })]
})

but I get this error:

/myproject/node_modules/browserify-middleware/node_modules/browserify/node_modules/module-deps/node_modules/resolve/lib/async.js:29
    if (x.match(/^(?:\.\.?\/|\/|([A-Za-z]:)?\\)/)) {
          ^
TypeError: Object #<Stream> has no method 'match'
    at resolve (/myproject/node_modules/browserify-middleware/node_modules/browserify/node_modules/module-deps/node_modules/resolve/lib/async.js:29:11)
    at makeTransform (/myproject/node_modules/browserify-middleware/node_modules/browserify/node_modules/module-deps/index.js:283:9)
    at ap (/myproject/node_modules/browserify-middleware/node_modules/browserify/node_modules/module-deps/index.js:202:13)
    at applyTransforms (/myproject/node_modules/browserify-middleware/node_modules/browserify/node_modules/module-deps/index.js:219:11)
    at /myproject/node_modules/browserify-middleware/node_modules/browserify/node_modules/module-deps/index.js:171:17
    at fs.js:266:14
    at Object.oncomplete (fs.js:107:15)

Thanks!

Preheat cache?

Are there there any ways of having browserify middleware build and cache a bundle at deploy time?

We're having six different servers behind a load balancer. The first request that hits each servers bundle.js takes ~ 1 - 3 secs to build. Especially in times with frequent deploys this makes the site load quite slow until the bundle is built and cached on each server.

A possible workaround is to actually issue a http request to bundle.js deploy time, but that feels a little too hackish. Any suggestions?

crash with ReferenceError when options.precompile is true

When running with NODE_ENV=production with version 2.6.0, I get an uncaught ReferenceError with this stack trace:

node_modules/browserify-middleware/lib/modules.js:15
    cachedCompile(path, options, function () {});
              ^
ReferenceError: path is not defined
    at Function.modules         
(node_modules/browserify-middleware/lib/modules.js:15:19)
at browserify (node_modules/browserify-middleware/index.js:11:20)

Pretty clear bug here:

cachedCompile(path, options, function () {});

hooks should be async

Hooks really should be asynchronous. for example to use closure compiler in a postcompile hook. The additional code shouldn't be complex. I got it to work with something like:

if (!options.postcompile) options.postcompile = function(src, cb) { cb(null, src); };
options.postcompile(src, function(err, src) {

I might do a pull request later, but I figured all hooks should be converted then.

Cheers for this great tool!

watchify support?

How about integrating watchify (or similar) to detect fs changes during development, invalidate the cache, and trigger a rebuild and recache?

Before I found browserify-middleware, I had a snippet like this that did it for me:

function cache() {
  build().pipe(concat(function(buffer) {
    module.exports.prebuiltCache = buffer;
  }));
}

if (config.browserifyDebug) {
  bundle = require('watchify')();
  bundle.on('update', cache);
}

Usually by the time I switched from my text editor to my browser and reloaded the page, the new bundle has already been built and cached so it's still fast.

Uglifyjs options

Hi guys,

I'm using browserify with angular.js and in production faced bad issue - uglifyjs overwrite angularjs injecting modules definitions.
Simular issue is described here http://stackoverflow.com/questions/17238759/angular-module-minification-bug.
To avoid this issue we need to disable mungle in uglifyjs:

uglify: {
  options: {
    mangle: false
  }

At the moment I just disable minify in browserify-middleware, but this is not a good solution.

Could you please add the uglifyjs options to browserify-middleware options?

precompile does not seem to work

I am using browserify-middleware in production with NODE_ENV='production'.
According to the documentation, precompileshould be set to true.
However, my first request after server start up takes a lot of time (~30s to serve /bundles/shared.js).
Here is my code :

var browserify = require('browserify-middleware');
var reactify = require('reactify');
browserify.settings('transform', ['reactify']);

var shared = ['react', 'superagent'];
router.get('/bundles/shared.js', browserify(shared));

does it have something to do with requiring external libraries ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.