Skip to content

Commit

Permalink
Expand the isobuild readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Slava committed Aug 6, 2015
1 parent 6e77ea4 commit 83ecb5e
Showing 1 changed file with 78 additions and 2 deletions.
80 changes: 78 additions & 2 deletions tools/isobuild/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,37 @@ concepts.

- `packageSource` - an abstract representation of a package/app source with metadata
- `isopack` - a compiled version of a package/app
- `unibuild` - a part of an isopack for a specific target (browser, server, tool, etc)
- `unibuild` - a part of an isopack for a specific target (browser, server,
tool, etc)
- `isopackCache` - an abstract representation of cached isopacks on disk
- `build plugin` - a part of an isopack that plugs into the build process
- `linked file` - a wrapped file by linker
- `project context` - an object that has lots of metadata, mostly about the
packages, catalogs, it is responsible for catalogs refreshes, pulling the
relevant packages, resolving dependencies, etc.
- `js-analyze` - some piece of software that implements a set of JS parser
features

## How an app is built

The app is built by Bundler, "bundling" is the most high-level process that
happens to the application code once it is loaded. Here is a more detailed
time-line:

1. Create the "Project Context" out of the app directory. Project Context makes
sure we know what package versions we need to use and prepares them for us.
2. The Bundler is given the Project Context and now it is Bundler's job to
create the Package Source for the app, compile app's parts as they were
packages, and then put everything together.
3. The Builder is ran to write the output files to disk.
4. While all the building was done, a WatchSet of the whole app is collected.
It's returned to the caller. Also, a `star.json` file is written.

### Compiler

Takes care of compiling an individual package and returning an Isopack.

XXX needs a new name not to be confused with Compiler Plugins


### Bundler

Expand All @@ -32,12 +53,67 @@ Bundler introduces additional terms:
- `ClientTarget` and `ServerTarget` are representations of two separate types of
"programs" in a built App.

There are commonly two important entry-points for Bundler:

- `buildJsImage` - build a build plugin
- `bundle` - the main function to bundle the application from a Project Context

For the actual compilation, Bundler often calls into Compiler. Other tasks that
Bundler performs include:

- initiate a Package Source for the app
- run linters on the app
- run the application files through Linker in a special mode that allows the use
of global variables
- add a special file called "global-imports" that explicitly puts all used
packages' symbols into the global namespace
- write compiled files to the right location with multiple Builder's
- write a `star.json` file with metadata for the "star" (the app)

### Builder

Manages the files written to the filesystem.

Since the rebuilds of an app is something that occurs over and over again (in
the development cycle), it makes sense to reuse the information about the files
that didn't change. Builder tries not to spend too much time writing files that
remained the same over and over again.

It is even OK to do when an app process serving these files is still running, on
Unix, the process can retain files by their inodes (not by file paths) and then
once the process release them, the FS will clean up unliked files.

### Linker

A Meteor-specific transform. Wraps every file into a closure, creates "package
local variables" and sets up the "global imports" to look like
`var Minimongo = Package.minimongo.Minimongo;`.

The process of linking is Meteor's substitute to other module loading solutions
like `r.js` or `require.js`, or ES2015-style modules. Eventually, Meteor wants
to transition to ES2015 modules for everything.

The way linker works for individual modules (packages in Meteor's case), is
several things. Roughly, it can be separated into two phases "prelink" and
"link" (both combined define "fullLink").

Prelink is something that can be done with a package in Isolation:

- create a closure around each file
- concatenate all files
- add comments of the original line number, file-headers - the metadata to be
read by humans when viewed in a browser that doesn't support source-maps
- run a JS parser and figure out all the global variables used, out of those,
pick the ones that are assigned in the package and form "Package-level" global
variables by adding a `var` for them.

In the second part "link", the linker caller already knows what versions of
linked module's dependencies are and what exports they provide for the module:

- create import strings for globals that come from dependencies' exports:
`var Minimongo = Package.minimongo.Minimongo;`, if the module references
`Minimongo`.

Historically, Meteor used to ship "prelinked" files in packages and then "link"
them in the bundle time. Starting with Meteor 1.2 and Batch Plugins API, Meteor
distributes source files, so they are "fullLinked" in bunlde time together.

0 comments on commit 83ecb5e

Please sign in to comment.