This commit is theoretically independent of the route policy PR, but
had multiple merge conflicts with it. This PR branch thus is based on
the route policy PR. (That is you should only merge this PR if you've
already merged the route policy PR).
Adds an html attribute hook, used by the appcache package to insert the
manifest attribute into the app HTML.
However, to use the hook the appcache package needs to be able to
identify the browser (to decide whether to include the attribute or
not for that browser).
We now have multiple places that want to identify the browser: the
unsupported browser page, the appcache package, and, if we eventually
implement not delivering large polyfills to browsers that don't need
them, in app HTML generation code as well.
To avoid detecting the browser in multiple places ad-hoc, this commit
creates a Meteor "browser" object, intended to be a standard way of
identifying the browser server-side. It uses but does not expose the
npm useragent module (we could choose a different mechanism to
identify the browser in the future if we wanted to). The browser
object contains
* `name`: the name of the browser in camel case
* `major`, `minor`, `patch`: integers describing the browser version
In addition to the html attribute hook, the appcache package also
needs a way to get from the connect `req` object to the identified
browser (browsers *start* caching when they see the manifest
attribute, but only *stop* caching when they get a 404 for the
manifest...)
Eventually though we'd like smart packages to be able to serve content
without having to plug directly into connect.
This commit thus also introduces an early version of a Meteor
`request` object, intended to be a high-level description of the
request without exposing details of connect's low-level `req`.
Currently it contains:
* `browser`: browser identification object described above
* `url`: parsed url, including parsed query params
To get started, as a temporary measure I've added a
`categorizeRequest` function to __meteor_bootstrap__ which converts a
connect `req` to a Meteor `request`. (Suggestions for a better name
are welcome). This can go away once smart packages such as appcache
are being passed a `request` object directly when they serve content.
This allows `request` to be used uniformly: it is passed to the html
attributes hook, and the appcache package can use it when deciding
whether to generate a 404 for the manifest.
Allows packages such as stream and accounts to declare URL prefixes
such as /sockjs/ and /_oauth/ to be network routes.
Updates server to avoid serving app HTML on network routes.
Checks for conflict between files in public/ and network routes. For
example, the developer might not know that /sockjs/ is reserved, and
might create a file "public/sockjs/socks-are-great.png".
`__meteor_bootstrap__.bundler` => `__meteor_bootstrap__.bundle`
`bundle.bundle_dir` => `bundle.root`
Rather than placing app_info/appInfo containing the manifest in the
bundle object, instead I'm now placing the manifest directly in the
bundle object. A) no code currently uses bundle.appInfo.load; B) if
someday we expand the manifest to also include server side resources
than we'd be getting rid of `load` anyway; C) I think it reads better:
`bundle.appInfo.manifest` => `bundle.manifest`
cp_r now returns a list of os-specific relative file system paths as
strings, instead of paths as arrays.
I changed the normalized "path" field in the manifest to be a relative
path instead of an absolute path (`"/static/cat.jpg"` =>
`"static/cat.jpg"`). This felt better when looking at the manifest; I
think because the path is relative to the bundle root.
Creates a manifest of the static files delivered to the client, for use
by the app cache. The manifest is also designed to be usable to generate
etag's for issue #626.
In the original bundler code `self.css` and `self.js.client` starts
out as an array of os-specific file paths and later becomes an array
of URLs (including query parameters). While I tried to minimize code
changes to avoid creating extra work for the engine project, this
turned out to be too crazy to deal with. In this version `self.css`
and `self.js.client` stay as file paths, and _generate_app_html now
pulls the client URLs from the new manifest.
This PR is thus proposing a design where the bundler manifest becomes
the source of knowledge about client static resources included in the
bundle, and is then used to generate the app html, the app cache, and
perhaps etag's in the future. (If it made sense then the `load` list
of server Javascript files could also be folded into the manifest,
making the manifest the source of knowledge about all static
resources... but the code in this PR don't include any steps in that
direction).
Fixes#631.
Update the dev_bundle to use the Meteor version of gzippo which allows
clientMaxAge to be set to 0, and change server.js to set the
clientMaxAge to 0 for static.
The use of path.sep is incorrect because req.url is a URL, not a file
path, and so always contains forward slashes.
I verified that the original code does not work on Windows and that
the new code does.
This definitely won't "work" because both have API changes.
UglifyJS 1 was having issues minifying certain code (eg lodash). But UglifyJS 2
was occasionally segfaulting (as was other code using large regexps). See the
bottom of https://github.com/laverdet/node-fibers/issues/89
Hopefully this will fix it.
The 'exit' event on a ChildProcess doesn't necessarily occur before all the
'data' events on its stdio, so sometimes 'meteor mongo' didn't find the
process. We should have been using the 'close' event. Switch from
child_process.spawn to child_process.exec, which simplifies the code and uses
the right event.