substance / substance-legacy

Towards open digital publishing
http://substance.io
930 stars 74 forks source link

Browser bundle stuff #331

Closed michael closed 10 years ago

michael commented 11 years ago

Mabye this is relevant.

https://github.com/sstephenson/stitch

andreypopp commented 11 years ago

I suggest using browserify, it has much healthier ecosystem and more active development process.

obuchtala commented 11 years ago

Agreed. I just tried: it works out-of-the-box.

On 16.09.2013 11:30, Andrey Popp wrote:

I suggest using browserify, it has much healthier ecosystem and more active development process.

— Reply to this email directly or view it on GitHub https://github.com/substance/substance/issues/331#issuecomment-24498184.

andreypopp commented 11 years ago

Just a few thoughts related to browserify and CommonJS in the browser in general

Modular nature of browserify

Browserify is not a single package but an ecosystem of packages — module-deps, browser-pack, browser-resolve and so on. If browserify doesn't suite your needs it maybe worth just to use these modules directly and have more sophisticated setup for serving CommonJS modules into the browser.

CommonJS for assets

You might be interested in CommonJS asset spec which allows to require CSS and even images in your javascript code. That would enable to package UI widgets completely with styles and other assets and then have predictable interface to incorporate them into a bundle to serve to a browser.

Currently there's staticify transform for browserify which implement this spec but I think it could provide more robust implementation. Anyway the plan is to make a default "good for all" implementation of the spec and then to make the hooks available to implement custom bundling strategies which are deeply integrated with a view layer of an app. For example it could be nice to have CSS rules only be active if there's a corresponding widget is in the DOM.

As a building block for that — I have css-pack module which consumes output from module-deps or dgraph (a graph of dependencies between CSS files, which could be extracted by analysing @import statements via dgraph-css-import package) and produces a single CSS bundle.

Splitting bundles into multiple

It maybe worth it to split a single bundle into multiple chunks and serve them to browser as needed. I have done some preliminary work on that — it's not ready yet, but at least serves as a proof of concept.

It allows you to define splitting points in your app by requiring modules asynchronously:

require.async('./compose-view', function(err, composeView) {
  // render view
});

Bundler will detect such points and generate initial bundle (with runtime for async loading) and all possible deltas. This would allow reduce the size of the initial resource load.

Interesting challenge seems to be the task of identification of such splitting points automatically but that would require collecting some runtime information from an actual usage of an application.

Server side UI pre-rendering

Browserify can be used to execute client side rendering code on the server to pre-render UI which would allow to reduce so-called "time to first tweet".

You can see a demo of such functionality in react-app package where browserify is used along with contextify (to sandbox client code against leaking to global server state) to pre-prender React components on a server. It is just around 400LOC along with HTML5 and server-side routing mechanism.

obuchtala commented 11 years ago

Interesting! Thanx!

For the first we start vanilla... I will try to get more into those advanced techniques.

Cheers, Oliver

obuchtala commented 11 years ago

Andrey, do you have any good resources about browserify?

andreypopp commented 11 years ago

@oliver---- for me official docs were enough to get started.

Browserify.prototype.bundle() returns a stream so you can integrate with you plain http server or express/connect app just by piping it into the response object:

var b = require('browserify)('./app.js');
...
b.bundle().pipe(res);

For development there's also watchify which is an alternative front-end for browserify which does dependency watching and rebuilds bundle on changes. It also do some smart caching logic so rebuilds are quite quick.

If you use express or connect there's connect-browserify which wraps watchify as a connect middleware.

ColemanGariety commented 10 years ago

@andreypopp in your previous comment you mentioned using browserify alongside contextify, but I can't find any use of contextify in the react-app repo's history. Do you have an example somewhere?