Active development of Apostrophe 3.0 is under way!
This week, Brian Gantick and I at P’unk Avenue had a three-day pair programming sprint to get the ball rolling on the most ambitious part of Apostrophe 3.0: gutting Apostrophe’s asset pipeline in favor of Webpack, and rebuilding Apostrophe’s admin UI with Vue.
For those not familiar with the Apostrophe 3.0 process, please do check out this earlier post on planning for Apostrophe 3.0.
Since then, we’ve firmed up the decision to go with Vue rather than React, because of its lightweight tooling, friendliness to inclusion in projects that aren’t 100% Vue on the front end, and general accessibility to new developers. Vue has also achieved significant popularity with enterprise customers who support Apostrophe development — a club which you are cordially invited to join.
So over the past three days, we’ve:
-
Replaced most of apostrophe-assets with an “build” task that leverages Webpack.
-
Arrived at a convention for loading Apostrophe’s Vue components and Vue apps. Vue components will be automatically loaded from the
src/apos/components
subdirectory of any Apostrophe module if a user is logged in, and they will be registered globally in Vue as named components such asApostrophePiecesManagerModal
; no need to callpushAsset
in 3.x. -
Demonstrated the ability to override which Vue components are used via server-side module configuration.
-
Completely eliminated “moog”, “apos.define”, “apos.create”, etc. on the frontend. Apostrophe’s Vue admin code will feel familiar to Vue developers and it won’t be hard to participate. Thanks to excellent Vue features like dynamic components we can keep the flexibility of our old system while adopting Vue’s patterns.
-
Broken down responsibility for different parts of the admin UI between the “admin bar” and “modals” apps. There will also be an app for page settings and an app that’s instantiated for each editable area on the page. We are doing it this way because Vue apps must completely “own” the part of the DOM where they are inserted into the page. And they don’t own most of the content of the page; see the next item:
-
Recommitted to keeping Nunjucks in the picture and vastly reducing the amount of JavaScript pushed to the browser for typical site visitors. By default, a logged-out user will receive almost no JavaScript from us, apart from a very lean library similar to the apostrophe-lean-frontend module we’ve already released for those who want a lighter frontend in Apostrophe 2.x. So by all means, just start using that module now. We’re taking this approach because Nunjucks has excellent performance and does a good job generating “plain old web pages,” which is still the first task of Apostrophe… that is, if you’re not using our apostrophe-headless module, which continues to be the right choice for those building single-page apps. However, we’re looking at changing Apostrophe’s approach to rendering so that it becomes possible to swap Nunjucks for something that works asynchronously… which means an all-Vue frontend is possible at a future date, as server-side rendering matures and proves fast enough for the job.
-
Chosen not to use Vuex… at least so far! Vue has several well-liked patterns for managing state, depending on the needs of your application. When state is shared between many components with changes coming thick and fast from every direction, and one master “store” of that state makes sense, Vuex is a great way to go. However, for Apostrophe, stores would have to be nested to support stacked modal experiences in several situations. And then the content would almost always turn out to “live” in a single parent modal component anyway. When the state belongs to a single component and child components can communicate their needs well just by passing events to the parent, Vuex is usually considered to be overkill. That’s why we don’t appear to need it so far.
-
We are, however, doing neat things like creating our own components that support two-way data binding with
@model
, just like regular form elements do. -
We also decided to create a global Apostrophe “bus” object,
apos.bus
, to dispatch a handful of events that are of interest to more than one Vue app. For instance, this is how we’ll handle it when the admin bar app (or something else!) wants the modal app to open the “Manage Products” modal. And, we’re using a headless Vue instance as thatbus
object.
Other 3.x news
In addition to these breakthroughs from the past few days, there are two more important steps toward 3.x that have already been taken this year:
-
Committed to the use of async/await throughout the server-side code of 3.x. This will drastically improve the accessibility of backend Apostrophe development. There will be no APIs based on the old callback convention. Promises will be used only where
async/await
does not cover the territory, for instance where parallelism is intended you might seePromise.all
or Bluebird’sPromise.map
applied to an array of promises returned byasync
functions. Since Apostrophe usually avoids parallel code when handling a single request, because multiple site visitors provide all the parallelism we need, you won’t see this very often. -
Created Apostrophe promise events. Promise events solve numerous challenges that face developers seeking to extend Apostrophe. Already in 2.x these are now the strongly preferred way to hook into the lifecycle of a web request in Apostrophe, and writing
callAll
methods has been deprecated. In 3.x promise events will be the only way to fly. -
Created apostrophe-lean-frontend, as I mentioned earlier. Optional in 2.x, this will be the standard approach on the front end in 3.x.
We still have lots of questions to answer and welcome your input. For instance, we are still deciding on the final approach to Apostrophe’s CSS assets — I suspect we’ll land on shared SASS rather than scoped CSS in Vue components, but that is still up in the air.
And of course we welcome your input on the code! You can find our commits to 3.0 so far here. During sprints, we work directly on the 3.0 branch. But now that the sprint is over, we’ll be working through pull requests to it.
There is also an extremely minimal test project here, although I should remind you that 3.x is not a usable CMS yet and won’t reach that maturity level for a while. Speaking of which:
2.x is the right version to start projects with now (and well into 2019)
This post wouldn’t be complete without a quick update on Apostrophe 2.x!
Apostrophe 2.x is not going away any time soon. We ourselves have over 50 clients with sites happily running on Apostrophe 2.x, a mature, long-term support platform on which we will be starting new projects ourselves at least through the first half of 2019. In order to plan our development pipeline sensibly, many features of 2.x won’t exist in 3.x right away, especially enterprise features like workflow, localization, and multisite.
The general patterns of frontend and even backend development you master with Apostrophe 2.x will translate easily to 3.x, and there will be a clear upgrade path for your existing projects.
So don’t hesitate to use 2.x and don’t “wait for 3.x.” We’re not waiting either!
Our next sprint
Our next sprint is scheduled for the end of October, after we get back from sponsoring JS Interactive in Vancouver — and if you’re thinking of attending, please do use our discount code for 20% off registration:
JSI18PUNK20
All we ask is that you stop by and talk Apostrophe!