Reviving an ancient Meteor.js project in 10 minutes 🦖

jankapunkt

Jan Küster

Posted on October 10, 2023

Reviving an ancient Meteor.js project in 10 minutes 🦖

Just a few weeks ago I read this trending article on bun:

The author also mentioned my still to date favorite JavaScript framework development platform Meteor.js:

In 2023 I tried to run my 2014 Meteor project again and the version of the CLI that is compatible with the project doesn't exist any more and the project cannot be ran locally or deployed without completely re-writing the entire project to the latest version of Meteor. All documentation for the 2014 version is just gone.

I asked the author in the comments to provide me a link to the repository, which he generously did:

Sharibble

Sharibble is an anonymous chat website that allows users to post links to photos and videos and have them instantly visible to everyone in the chatroom.

Sharibble was created using Meteor.




So I cloned the repo and checked what's actually up with this one.

Photo by Daniil Silantev on Unsplash

Checking out the project

I cloned the project and at the very first examined the Meteor release used to build the project:



$ git clone git@github.com:TheJaredWilcurt/sharibble.git
$ cd sharibble
$ cat app/.meteor # 0.8.3


Enter fullscreen mode Exit fullscreen mode

So, I found this project to be at release 0.8.3, which is from June, 2014. The latest available documentation are the release 1.3 docs.
The related 1.3 release is tagged on GitHub from 2016, so there is basically a gap of two years in between this.

EDIT: one of the core maintainers pointed out, that the binary is also still available and the project is actually runnable on 0.8.3. Furthermore another community member linked a pre 1.0 documentation, which they hosted on their own.

What do we do now?

We could open an issue to revive old docs, since all the docs are still available and only need to be generated and published again.

However, I wondered how long it would take to make this project run again on Meteor's latest version (as of Today is release 2.13.3). I found this to be much simpler than expected and would like to show how it works.

By doing so I'd like to inspire people with older projects to try and check them out again. Furthermore I'd like to emphasize how well this platform has been designed by it's original team at MDG (nowadays running Apollo GraphQL) that it basically runs even 10 years old code without sacrificing modern tools and features.

Here we go.

Create a new Meteor.js project

The fastest way is to create a new project and copy the existing files into the "new" structure.

For the least barriers we should use Blaze using the --blaze option, because it's the original frontend engine that powered nearly all Meteor.js projects before the strategy of making Meteor.js frontend agnostic:



$ cd sharibble # if not already in the project root
$ meteor create --blaze newapp


Enter fullscreen mode Exit fullscreen mode

If you compare the app with the newapp you will realize the project structure is now slightly different and newapp/package.json differs a lot from package.json. Back in the days, Meteor.js was not entirely compatible with the broader ecosystem and mostly focused on their own package-environment.

Include server-side code

First of all, we should be able to run the meteor server again. In order to do that open another terminal and run the newapp via meteor:



$ cd newapp
$ meteor
[[[[[ ~/dev/github/sharibble/newapp ]]]]]     

=> Started proxy.                             
=> Started HMR server.                        
=> Started MongoDB.                           
=> Started your app.                          

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


Enter fullscreen mode Exit fullscreen mode

Now don't cancel the running process but use the other terminal to copy and link the files



$ cp -Rv app/server/* newapp/server/


Enter fullscreen mode Exit fullscreen mode

Now open the main entry point for the server, which is newapp/server/main.js and replace the boilerplate with an import of our copied server file:



import './server'


Enter fullscreen mode Exit fullscreen mode

The meteor server auto restarts and should report any issues. After a few seconds it actually reported this one:



I20231010-16:14:45.378(2)? Exception in setInterval callback: TypeError: (intermediate value).addSeconds is not a function
I20231010-16:14:45.408(2)?     at server/server.js:130:41
I20231010-16:14:45.409(2)?     at packages/meteor.js:365:18
I20231010-16:14:45.409(2)?     at Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1389:31)
I20231010-16:14:45.409(2)?     at packages/meteor.js:613:25
I20231010-16:14:45.409(2)?     at runWithEnvironment (packages/meteor.js:1486:24)


Enter fullscreen mode Exit fullscreen mode

I inspected the code in server.js and fortunately this was only due to a missing import. The Date class is missing a custom addSeconds function. It's actually defined in app/lib/prototypes.js, which we therefore copy and link, too:



$ mkdir -p newapp/lib 
$ cp -v app/lib/prototypes.js newapp/lib


Enter fullscreen mode Exit fullscreen mode

Now the error is gone. From here you can refactor things to get rid of extending the prototype of the builtin Date object, which is nowadays considered a code-smell but was back then a common concept.

Copy all client code

Let's try to migrate the client code, so we can finally attempt to run the app:



$ cp -Rv app/client/* newapp/client # client template files
$ cp -Rv app/public newapp # public folder contains static assets for the client


Enter fullscreen mode Exit fullscreen mode

In the main entry point for the clien (at newapp/client/main.js) we now need to link the files as we did on the server. Remove the boilerplate and replace it with this code:



import './sharibble.html'
import './client'
import './main.css'
import './scripts/main'
import './scripts/owl.carousel'


Enter fullscreen mode Exit fullscreen mode

Finally, open the app on http://localhost:3000 and open the browser console to detect any issues:



Uncaught ReferenceError: Session is not defined


Enter fullscreen mode Exit fullscreen mode

Add session to your newapp project via meteor add session and reload the browser. A new error arises:



Uncaught TypeError: Meteor.uuid is not a function


Enter fullscreen mode Exit fullscreen mode

It comes from the following code in newapp/client/client.js at line 5:



Session.set("userGuid", Meteor.uuid())


Enter fullscreen mode Exit fullscreen mode

Replace it with the following:



import { Random } from 'meteor/random'
Session.set("userGuid", Random.id())


Enter fullscreen mode Exit fullscreen mode

Finally, the browser renders, obviously a chat app.

sharibble app revived

Get the chat back running

However, when entering any input I get an error on the server:



Exception from sub userIcon id 6Bt6Txe39ZrFHcRcH ReferenceError: _ is not defined


Enter fullscreen mode Exit fullscreen mode

This is easily fixed by importing underscore on the server.js, which is available by default. Add to the very top of server/server.js the following line:



import { _ } from 'meteor/underscore'


Enter fullscreen mode Exit fullscreen mode

Now the chat is restored! It runs again! 🥳

Get image linking back running

As the banner says, "link images in the chat", I'm all in. However, this also throws an error but this time it's a client-side error. It's easily resolved by also importing the newapp/lib/prototypes.js file on the client. Insert before the imports at newapp/client/main.js the following line:



import '../lib/prototypes'


Enter fullscreen mode Exit fullscreen mode

The image is now linked but not displayed as the database update from the client is prevented (403 error). Back in the days one of Meteor's selling points was to enable clients to send DB updates but it turned out to be too insecure on it's own.
However, it's still a great feature for prototyping and therefore available via the insecure package:



meteor add insecure


Enter fullscreen mode Exit fullscreen mode

By adding this package the images are viewable and the app is fully restored. 🥳🥳🥳

fully restored app

You can find the result also on my fork of the original repository:

Sharibble

Sharibble is an anonymous chat website that allows users to post links to photos and videos and have them instantly visible to everyone in the chatroom.

Sharibble was created using Meteor.






How to go from here

Meteor.js comes with a vast amount of documentation and a comprehensive guide that covers nearly everything important, ranging from topics for bloody beginners to advanced users, as well as important security topics.

You may even want to move away from Blaze (😢) and pick on of the many modern frontends, like Vue3, React, Solid, Svelte etc. (see docs for available options).

Summary

The platform Meteor.js and the packages around it have evolved a lot, yet their core functionality remained backwards compatible for nearly 10 years. This is an impressive amount of time, considering the fast pacing and ever changing JavaScript ecosystem in general.

With the upcoming Meteor 3 release there will be one of the first bigger breaking changes that will not be backwards compatible. However, this step was good and necessary to keep up with the rest of the ecosystem. If you have any older applications you want or need to migrate, now is the best time to do it!


About me

I regularly publish articles here on dev.to about Meteor.js and JavaScript.

You can also find (and contact) me on GitHub, Twitter and LinkedIn.

If you like what you are reading and want to support me, you can sponsor me on GitHub or send me a tip via PayPal.

💖 💪 🙅 🚩
jankapunkt
Jan Küster

Posted on October 10, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related