Upcoming and OnDemand Webinars View full list

Managing Front-End Assets in Vapor, Part 2: Using a Package Manager

Josh Justice

In part one of this series, we added some JavaScript (JS) and Cascading Style Sheet (CSS) files to our Vapor web app. We also manually downloaded some third-party front-end libraries. In this part, we’ll look at automating that download using a package manager.

If you’d like to follow along, you can get the complete part 1 project here.

Downloading with npm

The premiere JavaScript and CSS package manager is npm. You can install it by installing Node.js; we’ll need Node.js installed anyway to run a certain command-line tool a bit later.

npm tracks your dependencies in a package.json file. To set up a package.json file for your project, go to your Vapor project folder in the terminal and then run npm init. Hit enter at each of the prompts shown to accept the default values. You should see a package.json file created in your project folder.

Next, run the following commands to install the latest version of Bootstrap 3:

npm install --save-dev bootstrap@3

Typically installing a library (“package” in npm terminology) would install all its dependent packages as well. However, Bootstrap 3 isn’t configured to indicate that jQuery is a dependency, so you need to install it manually:

npm install --save-dev jquery

When you run these commands, several things will happen:

  • The packages will be downloaded into a new node_modules folder at the root of your project.
  • Because you added the --save-dev flag, an entry will also be added to your package.json file recording that dependency and a compatible version range. (For example, ^3.3.7 means “3.3.7 or any newer version before 4.x”.)
  • If you installed Node version 8 or later, a package-lock.json file will be created and an entry will be added for each dependency. This records exactly which version of the package was installed, so that other developers will get the identical version.

Now that we’ve downloaded dependencies, should we commit them to git? In the iOS development world, opinions about committing dependency source code are split. For front-end devs, the overwhelming practice is to not commit your node_modules folder to git, because you can usually rely on packages being available for you to re-download. Add node_modules to your .gitignore file:

 # End of https://www.gitignore.io/api/vapor
+ 
+# Generated by `npm install`
+/node_modules

All you need to commit is package.json and package-lock.json. If anyone wants to get your project up and running on a new machine, they can just run npm install with no arguments. npm will check package-lock.json and download the versions of the packages it specifies.

So now we have the CSS and JS files for Bootstrap and jQuery downloaded into node_modules/. But to make them accessible to the web browser, we need them to be in the Public/ folder instead. Do we need to manually copy them there?

Copying Files

Copying files is one of the many tasks usually automated by a front-end build tool. There have been a lot of front-end build tools in the last few years. Currently one of the most popular is Webpack. It provides a lot of power for complex JavaScript applications, but it’s also fairly complex to set up and it would likely be overkill for our simple server-rendered app. An easier option is to use laravel-mix, a lightweight wrapper around Webpack. It allows you to get started easily when your needs are simple, and then transition over to Webpack proper when you outgrow it. It’s part of the Laravel PHP framework, but it doesn’t have any PHP dependencies: it works just great for a Vapor app as well!

To get started using laravel-mix, install it into your project using npm:

npm install --save-dev laravel-mix

In your package.json, add an entry under "scripts" to make a simple command-line command to run it:

   "scripts": {
+    "build": "NODE_ENV=development webpack --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
     "test": "echo "Error: no test specified" && exit 1"
   },

Next, copy its config file, webpack.mix.js, into your project root:

cp -r node_modules/laravel-mix/setup/webpack.mix.js ./

Open the just-copied webpack.mix.js. We want to configure it to copy Bootstrap and jQuery into Public/ for us. To do this, we can remove the existing sample code and use the mix.copy() function:

-mix.js('src/app.js', 'dist/')
-  .sass('src/app.scss', 'dist/');
+mix.copy([
+  'node_modules/bootstrap/dist/css/bootstrap.min.css',
+  'node_modules/bootstrap/dist/js/bootstrap.min.js',
+], 'Public/vendor/bootstrap/');
+mix.copy([
+  'node_modules/jquery/dist/jquery.min.js',
+], 'Public/vendor/jquery/');

Now that the Public/vendor/ folder will be set up by laravel-mix, delete the folder and then add it to .gitignore:

 /node_modules
+
+# Generated by `npm run build`
+/Public/vendor

Now we’re ready to run our script:

npm run build

Check under the Public/ folder. You should see a vendor/ folder recreated, and the asset files copied where we intended them. Run your Vapor app from within Xcode and go to http://localhost:8080/hello in a browser. The Bootstrap tab control should appear and work just fine.

Just the Beginning

Setting up laravel-mix just to copy some files may feel a bit like overkill, but this is just the start of what you can do with a front-end build tool. In the next part of this series, we’ll look at using laravel-mix to concatenate our JS and CSS files to simplify our markup and improve site performance for end users.

If you want to learn more about CSS and JavaScipt, Big Nerd Ranch’s front-end training is a week-long intensive study that will help you to speed quickly. Our front-end web development guide will also help you get started.

Not Happy with Your Current App, or Digital Product?

Submit your event

Let's Discuss Your Project

Let's Discuss Your Project