Meteor, Update, meteorjs, Meteor Website Development

How to Update Your Enterprise Meteor Application to 1.4

It's Monday morning and you're ready to get cracking on the next big feature of your Meteor app. You fire it up, anticipating that message that gives you the “green light” ...

=> App running at: http://localhost:3000/

Unfortunately this time, you also see this:

=> Meteor 1.4.1 is available. Update this project with 'meteor update'.

Ah, a friendly announcement that a shiny new Meteor release awaits you! As MDG has shifted to smaller releases more often, you’ve likely seen this more often, lately.

Most patch updates are quick and easy. But 1.x updates aren't always 'minor’ because they often involve breaking changes. It can’t ever be quite as simple as typing 'meteor update,’ can it?

Meteor has long been great for quickly building small apps or minimum viable products. But, since Meteor 1.2, MDG has focused on making it easier to build enterprise-level apps that have tighter integration with the greater Javascript ecosystem. This includes:

  • support for ES2015, NPM integration, React, and Angular
  • built in application testing
  • a more robust and performant mobile experience
  • updated Node and MongoDB support

Building large-scale Meteor apps is something we do here at Project Ricochet. So, we've eagerly anticipated these last few releases, and have updated several of our projects to Meteor 1.4. We hope that by sharing our experiences here, you can more easily take advantage of the latest Meteor release.

The Update Process

Our Meteor release update process follows these 5 basic steps:

  1. Create a branch for the update.
  2. Test and create a baseline.
  3. Update Meteor and related dependencies.
  4. Test and compare against the baseline.
  5. Merge and enjoy the latest and greatest Meteor release.

Create a Branch

If you already follow best practices, you'll know that every new task or feature should be implemented in its own git branch. This strategy is just as useful here. A Meteor update shouldn't inadvertently introduce new behaviors to your app. Here, the ability to toggle between your updated app and the former, pre-updated version to compare the two is useful. So, before doing anything else, create and switch to that new branch.

> git checkout -b meteor-update-branch-name

Test and Create a Baseline

Throughout your update process, you'll want to regression test to ensure the app still performs correctly. It's a good idea to create a baseline to compare against. If you've invested in creating a suite of automated acceptance tests for your app, this is where it pays off. With good tests you can update the code with confidence. Before starting the update, run those tests and take note of the results. After the update is complete, run the same tests. If the results match, then it's a good indicator the update was successful.

If you don't have automated tests, or your existing ones don't provide enough coverage, then conduct manual testing and record those results to use as your baseline.

There are several Javascript testing frameworks available. We use Chimp.js for automating acceptance tests, as recommended by the Meteor Guide. Running it yields the following results:

> chimp --ddp=http://localhost:3000 --watch --mocha --path=tests
...5 scenarios (5 passed)
40 steps (40 passed)

So … we've created our baseline. Let the update begin!

Update to Meteor 1.3

You can skip this section if you’re already on Meteor 1.3. While many of our projects were on 1.3, some were still clinging to 1.2. This is not uncommon, as Meteor 1.3 came with a few breaking changes that may have caused some folks to push back the update. With Meteor 1.4 here, now is the time to make the jump, but with an update to 1.3 first. Here are a few challenges we ran into when updating.

fourseven:scss

The fourseven:scss package is a popular Sass build plugin for Meteor. Truth told, it behaved a bit finicky in our road to Meteor 1.4. Updating this required us to first update to Meteor 1.3.4.1.

> meteor update --release 1.3.4.1

Meteor will update, along with your app's corresponding packages.

Changes to your project's package version selections from updating the release:

accounts-base upgraded from 1.2.2 to 1.2.8
accounts-password upgraded from 1.1.4 to 1.1.11

webapp upgraded from 1.2.3 to 1.2.9_1

Next, manually update fourseven:scss.

> meteor update fourseven:scss
fourseven:scss upgraded from 3.4.1 to 3.8.1

Finally, you can update to the final 1.3 release:

> meteor update --release 1.3.5.1

You should see something like the following:

Changes to your project's package version selections from updating the release:

accounts-password upgraded from 1.1.11 to 1.1.13
autoupdate upgraded from 1.2.10 to 1.2.11

webapp upgraded from 1.2.9_1 to 1.2.11

React

React was initially introduced as an Atmosphere package. As of Meteor 1.3, MDG recommends adding React via NPM. Enable ecmascript which ensures you can import modules, then replace the Atmosphere version with the NPM version using the following commands:

> meteor add ecmascript
> meteor remove react
> meteor add react-meteor-data
> npm install --save react react-dom react-addons-pure-render-mixin

Note that there is no longer a global React symbol. Now, wherever your app references React (eg. in your JSX files), you'll need to import it:

import React from 'react';

Adding this one by one to all your JSX files can get tedious. Here's a neat little OSX-only bash script that adds this import statement to every JSX file in the current directory and subdirectories (note the new lines):

> find . -name "*.jsx" -type f -exec sed -i '' "1s/^/import React from 'react';\
\\"$'\n'"\
/g" {} \;

Test and Compare Against the Baseline

It pays to test often along the way. This helps you see if a particular step in the update process introduces a bug. Running our tests now resulted in this:

> chimp --ddp=http://localhost:3000 --watch --mocha --path=tests

5 scenarios (4 passed, 1 failed)
40 steps (39 passed, 1 failed)

The bad news is we now have a regression bug. The good news is by knowing this as soon as possible, we are far better positioned to resolve the issue.

ES2015 modules

In this case, we were using the mrt:moment Atmosphere package and extended it with the moment business plugin. This plugin was no longer finding moment, so it was failing to initialize.

moment = (typeof require !== "undefined" && require !== null) && !require.amd ? require("moment") : this.moment;

In Meteor 1.2, CommonJS require wasn't available. So it found moment in global scope via this.moment. With our update to Meteor 1.3, ES2015 module support was now available. The above tried, and failed, to import the moment npm package instead.

MDG recommends using npm versions of Atmosphere packages. So instead of modifying the above code to avoid using require, let's install the npm version of moment instead.

> meteor remove mrt:moment
> npm install --save moment

The tests were clean once again!

> chimp --ddp=http://localhost:3000 --watch --mocha --path=tests

5 scenarios (5 passed)
40 steps (40 passed)

Following this cycle of applying an update, running your tests, then fixing any regressions, ensures bugs are identified and fixed as soon as they're introduced.

Meteor 1.4

Although Meteor 1.4 is still relatively new, it's been around long enough for many popular packages to support it. So, let's take the next step and update to 1.4.1:

> meteor update

aldeed:tabular: updating npm dependencies -- datatables...

Changes to your project's package version selections from updating the release:

accounts-base upgraded from 1.2.8 to 1.2.9
accounts-password upgraded from 1.1.13 to 1.2.12

webapp upgraded from 1.2.11 to 1.3.10

Binary npm Packages

Meteor 1.4 uses Node 4, a change that requires recompiling any binary npm packages. The Meteor Guide explains this well. You will need to install a basic compiler toolchain on your development machine.

  • OS X users should install the commandline tools (in short, run xcode-select --install).
  • Windows users should install the MS Build Tools.
  • Linux users should ensure they have Python 2.7, make, and a C compiler installed.

Then, recompile those binary npm packages:

> meteor npm rebuild

Collection Hooks

We leverage the very useful matb33:collection-hooks package in many of our applications. The package was updated for Meteor 1.4, but we found it caused issues if your collection used Mongo.ObjectIds. To be more precise, the doc._id parameter was set to a string value instead of the Mongo.ObjectId.

We reported and submitted a PR to fix this and it’s now been merged. So if you’re using this package and making use of Mongo.ObjectIds, make sure the version of collection-hooks is at 0.8.4 or higher.

To WiredTiger or Not?

Meteor 1.4 now supports MongoDB 3.2 with a new storage engine called WiredTiger. It delivers document-level concurrency control and native compression (among other new features). This can result in higher throughput and lower storage costs.

We can cover WiredTiger more in a future post. In the meantime, should you update your local development database to WiredTiger? We recommend it only if you'll be updating your Production database shortly thereafter. It's always good to match your Production environment as much as possible.

To update, if you don't care about the existing data in your development database, simply run

> meteor reset

and Meteor 1.4 will recreate your development database with a 3.2 WiredTiger engine.

Don't forget to run your tests one more time to confirm all is good!

Merge Your Changes

Now that you’ve made the necessary changes, run your tests, and confirmed everything is working as before, it’s time to merge it back into the parent branch. Depending on your branching strategy and development process, this means submitting a pull request to your project’s development or master branch. Whatever the case may be, this update triggered a relatively large amount of code to be updated. A teammate should review the changes, independently test the update, and validate everything works as before, just in case anything was missed.

One Point For You!

You made it. Score one for you! Your app is now taking advantage of all the goodness Meteor 1.4 brings. It should be easy 1.4.x patch updates for the next little bit. We hope we made your journey a little easier by sharing our Meteor 1.4 update experiences here at Project Ricochet.

Until 1.5!

A bit about Marty:

Marty has a B.S. in Computer Science and over 15 years of software architecture, development, and management experience - building everything from large scale, enterprise back end systems to innovative client side apps using Meteor.js. In his free time, he loves playing hockey and imbibing Tim Horton's coffee when he's not playing with his three kids.