11. Environment variables

There's no reason you should have to use ports 8080 and 8070 specifically, and in production we definitely won't use those values, so they shouldn't be hardcoded into our config.

Let's instead use environment variables in place of any hardcoded variables.

If you aren't aware, Vue CLI 3 will pass in any variables you specify in the file .env into your config file.

So let's create the .env file by going:

$ touch .env

And well add these two variables:

.env

PORT=8080
SERVER_PORT=8070

Another idiosynracy of Vue CLI 3 is that the app must use the variable PORT. You can't change that.

It would have been nice to disambuiate it and call it CLIENT_PORT, but we can't.

Vue config

Anyway, let's now go to our Vue config file and use those environment values in the dev server config.

By default, the client app will be on port 8080 but if you want to change that, you can specify a port property.

Let's assign the environment variable by putting process.env.PORT.

Next, we'll covert our proxy address string to a template, and replace the port with the SERVER_PORT environment variable.

vue.config.js

devServer: {
  port: process.env.PORT,
  proxy: `http://localhost:${process.env.SERVER_PORT}`
}

Server config

That won't quite work, though, because we still have the server port hardcoded into our server index file.

server/index.js

const port = 8070;
app.listen(port, () => {
  console.log(`Listening on port ${port}.`);
});

dotenv

Node scripts doesn't automatically load in an environment file; we need to install a Node package to do that. So let's add the dotenv package to our project.

Now we don't actually need to install this as Vue CLI uses the same package as a dependency. So all we need to do is put the following at the top of our index.js file:

server/index.js

require("dotenv").config();

By default, this will load the file .env and allow us to use those environment variables inside this file.

Now we can go...

const port = process.env.SERVER_PORT;

If we restart our server, we can see in the terminal that both the client and server are using the same ports as before, but those values are now configurable in the environment file.

Server config

Unfortunately, it's not quite as easy as that. When we later go to put this project into production, environment variables are going to be passed into the app through the operating system environment, as opposed to the .env file.

We're going to use Heroku in this course, and just like Vue CLI, it's not flexible when it comes to specifying the app's port, and it also demands to use the PORT environment variable.

This means using SERVER_PORT is not going to work!

To resolve this, we're going to have to use a separate environment file for the server. This is not a particularly neat solution as it means we're going to have to specify the server port in two separate files. But I think that's the best we can do given this tricky situation.

So let's create another file, .env.server.

In that file, we'll put the value PORT, and you must always make this the same value we specified for SERVER_PORT in the Vue environment file; in this case 8070.

.env.server

PORT=8070

Now this is not all bad, because we actually will need to specify other server environment variable later in the course, so we will be needing this dedicated server environment file anyway.

Oh and one more thing; unlike the Vue environment file, the server environment file shouldn't be committed to the code repo. So let's ensure we tell our git ignore file not to include it:

$ echo ".env.server" >> .gitignore

Server script

Lastly, we'll use the server environment file in our server script. To do this, we'll now need to specify the path of the environment file in the dotenv constructor, as by default it uses the .env file.

This is an absolute path, so we'll need to use Node's path module here, and we'll pass __dirname as the first argument, we'll go up a directory using the .. double dots, and we'll specify the file .env.server.

Finally, we'll change SERVER_PORT to just PORT.

const path = require("path");

require("dotenv").config({
  path: path.join(__dirname, "..", ".env.server")
});

const port = process.env.PORT;
app.listen(port, () => {
  console.log(`Listening on port ${port}.`);
});

With that done, if we restart our server, we should see that everything is still working.

Discussion

0 comments