Using Linters, Formatters, and Deployment Commands

Besides writing tests (whether they are end-to-end tests or unit tests), code linting and formatting also are parts of web development. All developers, whether you are a Java, Python, PHP, or JavaScript developer, should know the coding standards in their fields and comply with them to keep your code clean, readable, and formatted for better maintenance in the future. The tools that we commonly use for JavaScript, Vue, and Nuxt apps are ESLint, Prettier, and StandardJS. In this chapter, you will learn to install, configure, and use them with our apps. Finally, after building, testing, and linting your app, you will learn the Nuxt deployment commands to deploy your app to a host.

The topics we will cover in this chapter are the following:

  • Introducing Linters – Prettier, ESLint, and StandardJS
  • Integrating ESLint and Prettier
  • Using ESLint and Prettier for Vue and Nuxt apps
  • Deploying Nuxt apps

Introducing linters – Prettier, ESLint, and StandardJS

In a nutshell, a linter is a tool that analyzes source code and flags errors and bugs in the code and styles. The term originated in 1978 from a Unix utility called lint that evaluated source code written in C, and was developed by computer scientist Stephen C. Johnson at Bell Labs while debugging the Yacc grammar he was writing. Today, the tools we focus on in this book are Prettier, ESLint, and StandardJS. Let's look into each of them.

Prettier

Prettier is a code formatter that supports many languages such as JavaScript, Vue, JSX, CSS, HTML, JSON, GraphQL, and more. It improves the readability of your code and ensures your code conforms to the rules that it has set for you. It sets a length limit for your lines of code; for example, take a look at the single following line of code:

hello(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne())

The preceding code is considered lengthy on a single line and is difficult to read, so Prettier will reprint it into multiple lines for you as follows:

hello(
reallyLongArg(),
omgSoManyParameters(),
IShouldRefactorThis(),
isThereSeriouslyAnotherOne()
);

Also, any custom or messy styling is also parsed and reprinted, as in the following example:

fruits({ type: 'citrus' },
'orange', 'kiwi')

fruits(
{ type: 'citrus' },
'orange',
'kiwi'
)

Prettier will print and reformat this into the following, much neater format:

fruits({ type: 'citrus' }, 'orange', 'kiwi');

fruits({ type: 'citrus' }, 'orange', 'kiwi');

However, if Prettier finds no semicolons in your code, it will insert them for you, just as in the preceding example code. You can turn this feature off if you prefer no semicolons in your code, as is the case with all the code used in this book. Let's turn off this rule with the following steps:

  1. Install Prettier via npm to your project:
$ npm i prettier --save-dev --save-exact
  1. Parse a specific JavaScript file:
$ npx prettier --write src/index.js

Or, parse all files in the recursive folders:

$ npx prettier --write "src/**/*"

Or even try parsing the files in parallel folders:

$ npx prettier --write "{scripts,config,bin}/**/*"

Before committing any change in-place (beware!) with the --write option, you can use other output options such as the following:

  • Use -c or --check to check whether the given files are formatted and print a human-friendly summary message afterward with the paths to the unformatted files.
  • Use -l or --list-different to print the names of files that are different from Prettier's formatting.
For more information about this tool, visit https://prettier.io/.

Now let's take a look at how we can configure this tool in the next section.

Configuring Prettier

Prettier is built with many options for customization. You can configure Prettier via the following options:

  • A prettier.config.js or .prettierrc.js script in a JavaScript object
  • A package.json file using a prettier key
  • A .prettierrc file in YAML or JSON with optional extensions: .json, .yaml, or .yml
  • A .prettierrc.toml file in TOML

It is a good idea to customize Prettier even though you can choose not to. For example, Prettier enforces double quotes and prints semicolons at the ends of statements by default. If we don't want these defaults, we can create a prettier.config.js file in our project root directory. Let's use Prettier in the API we have created (we made a copy at /chapter-14/apps-to-fix/koa-api/ in our GitHub repository) with this configuration in the following steps:

  1. Create a prettier.config.js file in our project root directory with the following code:
// prettier.config.js
module.exports = {
semi: false,
singleQuote: true
}
  1. Parse all the JavaScript code in the /src/ directory with the following command:
$ npx prettier --write "src/**/*"

As you can see, all our files are listed on the terminal when you run npx prettier --write "src/**/*":

src/config/google.js 40ms
src/config/index.js 11ms
src/core/database/mysql.js 18ms
src/index.js 8ms
...

Prettier will highlight the files that have been reprinted and formatted.

For more format options, check out https://prettier.io/docs/en/options.html. You can find this example in /chapter-14/prettier/ in our GitHub repository.

It is pretty sweet when you see your code "prettified" so effortlessly, isn't it? Let's move on to the next linter, ESLint, to see how it helps to tidy up our code in the next section.

ESLint

ESLint is a pluggable linter for JavaScript. It is designed so that all of its rules are completely pluggable and allows developers to customize the linting rules. ESLint is shipped with some built-in rules to make it useful from the start, but you can dynamically load rules at any point in time. For example, ESLint disallows duplicate keys in object literals (no-dupe-keys), and you will get an error for the following code:

var message = {
text: "Hello World",
text: "qux"
}

The correct code under this rule will look like the following:

var message = {
text: "Hello World",
words: "Hello World"
}

ESLint will flag the preceding error and we will have to fix it manually. However, can use the --fix option on the command line to automatically fix problems that are more easily fixed without human intervention. Let's see how to do so in the following steps:

  1. Install ESLint via npm in your project:
$ npm i eslint --save-dev
  1. Set up a configuration file:
$ ./node_modules/.bin/eslint --init

You will be asked a list of questions similar to the following:

? How would you like to use ESLint? To check syntax, find problems,
and enforce code style
? What type of modules does your project use? JavaScript modules (import/export)
? Which framework does your project use? None of these
? Where does your code run? (Press <space> to select, <a> to
toggle all, <i> to invert selection)Browser
? How would you like to define a style for your project? Use
a popular style guide
? Which style guide do you want to follow? Standard (https://github.com/standard/standard)
? What format do you want your config file to be in? JavaScript
...

Successfully created .eslintrc.js file in /path/to/your/project

These questions might vary depending on the options/answers you choose for each question.

  1. Add the lint and lint-fix scripts to the package.json file:
"scripts": {
"lint": "eslint --ignore-path .gitignore .",
"lint-fix": "eslint --fix --ignore-path .gitignore ."
}
  1. Create a .gitignore file with the paths and files that we want ESLint to ignore:
// .gitignore
node_modules
build
backpack.config.js
  1. Launch ESLint to scan for errors:
$ npm run lint
  1. Use lint-fix to fix those errors:
$ npm run lint-fix

You can check out the list of ESLint rules at https://eslint.org/docs/rules/. Rules in ESLint are grouped by category: Possible Errors, Best Practices, Variables, Stylistic Issues, ECMAScript 6, and so on. No rules are enabled by default. You can use the "extends": "eslint:recommended" property in a configuration file to enable rules that report common problems, which have a checkmark (✓) in the list.

For more information about this tool, visit https://eslint.org/.

Now let's take a look at how we can configure this tool in the next section.

Configuring ESLint

As we mentioned before, ESLint is a pluggable linter. That means it is completely configurable and that you can switch off every rule, or some of them, or mix custom rules to make ESLint specifically suited for your project. Let's use ESLint in the API we have created with one of the following configurations. There are two methods to configure ESLint:

  • Use the JavaScript comments directly with the ESLint configuration information in a file, as in the following example:
// eslint-disable-next-line no-unused-vars
import authenticate from 'middlewares/authenticate'
  • Use a JavaScript, JSON, or YAML file to specify configuration information for an entire directory and all of its subdirectories.

Using the first method can be time-consuming because you may need to provide the ESLint configuration information in every .js file, while in the second method, you just need to configure it once in a .json file. So let's use the second method for our API in the following steps:

  1. Create a .eslintrc.js file or generate it with --init in the root directory with the following rules:
// .eslintrc.js
module.exports = {
'rules': {
'no-undef': ['off'],
'no-console': ['error']
'quotes': ['error', 'double']
}
}

In these rules, we want to make sure to do the following:

  • Allow undeclared variables (no-undef) by setting the no-undef option to off
  • Disallow the use of the console (no-consoleby setting the no-console option to error
  • Enforce the consistent use of either backticks, double quotes, or single quotes (quotes) by setting the quotes option to error and double
  1. Add the lint and lint-fix scripts to the package.json file:
// package.json
"scripts": {
"lint": "eslint --ignore-path .gitignore .",
"lint-fix": "eslint --fix --ignore-path .gitignore ."
}
  1. Launch ESLint to scan for errors:
$ npm run lint

You will get a report like the following if there are any errors:

/src/modules/public/login/_routes/google/me.js 
36:11 error A space is required after '{' object-
curly-spacing
36:18 error A space is required before '}' object-
curly-spacing

Even though ESLint can fix your code automatically with the --fix option, you still need to fix some manually, as in the following example:

/src/modules/public/user/_routes/fetch-user.js 
9:9 error 'id' is assigned a value but never used
no-unused-vars
For more information about the configuration, check out https://eslint.org/docs/user-guide/configuring. You can find this example in /chapter-14/eslint/ in our GitHub repository.

It is user-friendly, isn't it? It is indeed another awesome tool just like Prettier. Let's move on to the last linter, StandardJS, to see how it tidies up our code.

StandardJS

StandardJS or JavaScript Standard Style is a JavaScript style guide, linter, and formatter. It is completely opinionated, meaning that it is completely uncustomizable – no configuration is needed, hence there are no .eslintrc, .jshintrc, or .jscsrc files to manage. It is uncustomizable and unconfigurable. The easiest way to use StandardJS is to install it globally as a Node command-line program. Let's find out how you can use this tool in the following steps:

  1. Install StandardJS via npm globally:
$ npm i standard --global

You can also install it locally for a single project:

$ npm i standard --save-dev
  1. Navigate to the directory that you want to inspect and type the following command in the terminal:
$ standard
  1. If you install StandardJS locally, then run it with npx instead:
$ npx standard

You also can add it to the package.json file as follows:

// package.json
{
scripts": {
"jss": "standard",
"jss-fix": "standard --fix"
},
"devDependencies": {
"standard": "^12.0.1"
},
"standard": {
"ignore": [
"/node_modules/",
"/build/",
"backpack.config.js"
]
}
}
  1. Then the code of your JavaScript project is checked automatically when you run it with npm:
$ npm run jss

To fix any messy or inconsistent code, try the following command:

$ npm run jss-fix

Even though StandardJS is uncustomizable, it relies on ESLint. The ESLint packages used by StandardJS are as follows:

  • eslint
  • standard-engine
  • eslint-config-standard
  • eslint-config-standard-jsx
  • eslint-plugin-standard

While Prettier is a formatter, StandardJS is mostly a linter just like ESLint. If you use --fix on your code with StandardJS or ESLint and then run it again with Prettier, you will see that any long lines (which are ignored by StandardJS and ESLint) will be formatted by Prettier.

For more information about this tool, visit https://standardjs.com/. You should also check out the summary of the standard JavaScript rules at https://standardjs.com/rules.html. You can find an example that uses StandardJS in /chapter-14/standard/ in our GitHub repository.

However, if you are looking for a more flexible and customizable solution that sits in between these tools, you can combine Prettier and ESLint for your project. Let's take a look at how you can achieve that in the next section.

Integrating ESLint and Prettier

Prettier and ESLint complement each other. We can integrate Prettier into the workflow with ESLint. This allows you to use Prettier for formatting your code while letting ESLint focus on linting your code. So, to integrate them, first, we will need the eslint-plugin-prettier plugin from ESLint to use Prettier "under" ESLint. Then we can use Prettier to add rules for formatting the code as usual.

However, ESLint contains rules that are formatting-related that can conflict with Prettier, such as arrow-parens and space-before-function-paren, and that can cause some issues when using them together. To resolve these conflicting issues, we will need the eslint-config-prettier config for turning off the ESLint rules that conflict with Prettier. Let's take a look at how you can achieve that in the following steps:

  1. Install eslint-plugin-prettier and eslint-config-prettier via npm:
$ npm i eslint-plugin-prettier --save-dev
$ npm i eslint-config-prettier --save-dev
  1. Enable the plugin and rules of eslint-plugin-prettier in the .eslintrc.json file:
{
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error"
}
}
  1. Override ESLint's rules by extending Prettier's with eslint-config-prettier in the .eslintrc.json file:
{
"extends": ["prettier"]
}

Note that the value "prettier" should be put last in the extends array so that Prettier's configurations can override those of ESLint. Also, we can use an .eslintrc.js file instead of the JSON file for the preceding configurations because we can add comments in the JavaScript files that can be helpful. So, the following is our configuration for using Prettier under ESLint:

// .eslintrc.js
module.exports = {
//...
'extends': ['prettier']
'plugins': ['prettier'],
'rules': {
'prettier/prettier': 'error'
}
}
  1. Configure Prettier in the package.json file (or in a prettier.config.js file) so that Prettier does not print semicolons in our code and always uses single quotes:
{
"scripts": {
"lint": "eslint --ignore-path .gitignore .",
"lint-fix": "eslint --fix --ignore-path .gitignore ."
},
"prettier": {
"semi": false,
"singleQuote": true
}
}
  1. Run npm run lint-fix on the terminal to fix and format our code in one shot. After that, you can check the code again with Prettier alone using the npx prettier command as follows:
$ npx prettier --c "src/**/*"

Then you should get the following result on your terminal:

Checking formatting...
All matched files use Prettier code style!

That means our code has no formatting issues and complies successfully in Prettier code style. It is pretty cool to bring these two tools together to suit our needs and preferences, isn't it? But you are still only half-way through – let's apply these configurations for Vue and Nuxt apps in the next section.

 You can find this integration example in /chapter-14/eslint+prettier/ in our GitHub repository.

Using ESLint and Prettier for Vue and Nuxt apps

The eslint-plugin-vue plugin is an official ESLint plugin for Vue and Nuxt apps. It allows us to inspect the code in the <template> and <script> blocks in the .vue files with ESLint to find any syntax errors, the wrong use of Vue directives, and the Vue style violation against the Vue style guide. Also, we are using Prettier to enforce the code format, so install eslint-plugin-prettier and eslint-config-prettier just like we did in the previous section for the basic specific configurations that we prefer. Let's get all these sorted in the following steps:

  1. Install this eslint-plugin-vue plugin using npm:
$ npm i eslint-plugin-vue --save-dev

You may get some warning:

npm WARN [email protected] requires a peer of eslint@^5.0.0
but none is installed. You must install peer dependencies
yourself.
npm WARN [email protected] requires a peer of eslint@^5.0.0
but none is installed. You must install peer dependencies
yourself.

Ignore them because the minimum requirements for eslint-plugin-vue are ESLint v5.0.0 or later and Node.js v6.5.0 or later, and you should already have the latest versions. 

You can check out the minimum requirements at https://eslint.vuejs.org/user-guide/installation. Besides the Vue style guide, you should also check out the Vue rules at https://eslint.vuejs.org/rules/.
  1. Add the eslint-plugin-vue plugin with its generic rulesets in the ESLint config file:
// .eslintrc.js
module.exports = {
extends: [
'plugin:vue/recommended'
]
}
  1. Install eslint-plugin-prettier and eslint-config-prettier and add them to the ESLint config file as well:
// .eslintrc.js
module.exports = {
'extends': [
'plugin:vue/recommended',
'plugin:prettier/recommended'
],
'plugins': [
'prettier'
]
}

But these are still not enough. You may want to configure some Vue rules to suit your preference. Let's find out some default Vue key rules that we might want to configure in the next section.

For more information about this eslint-plugin-vue plugin, visit https://eslint.vuejs.org/. For Vue directives, please visit https://vuejs.org/v2/api/Directives, and for the Vue style guide, please visit https://vuejs.org/v2/style-guide/.

Configuring Vue rules

There are only four default Vue rules we want to override in this book. You only need to add the preferred rules in the 'rules' option in the .eslintrc.js file just like we did for the eslint-plugin-prettier plugin in the previous section. Let's get to it in the following steps:

  1. Configure the vue/v-on-style rule to "longform" as follows:
// .eslintrc.js
'rules': {
'vue/v-on-style': ['error', 'longform']
}

The vue/v-on-style rule enforces shorthand or longform on the v-on directive style. The default is set to shorthand, for example:

<template>
<!-- ✓ GOOD -->
<div @click="foo"/>

<!-- ✗ BAD -->
<div v-on:click="foo"/>
</template>

But in this book, longform is preferred, as in the following example:

<template>
<!-- ✓ GOOD -->
<div v-on:click="foo"/>

<!-- ✗ BAD -->
<div @click="foo"/>
</template>
For more information about this rule, visit https://eslint.vuejs.org/rules/v-on-style.htmlvue-v-on-style.
  1. Configure the vue/html-self-closing rule to allow self-closing signs on the void elements as follows:
// .eslintrc.js
'rules': {
'vue/html-self-closing': ['error', {
'html': {
'void': 'always'
}
}]
}

A void element is an HTML element that is not allowed to have contents in any circumstances, such as <br>, <hr>, <img>, <input>, <link>, and <meta>. In writing XHTML, it is mandatory to self-close these elements, such as <br/> and <img src="..." />. In this book, we want to allow that even though the / character is considered optional in HTML5.

Under the vue/html-self-closing rule, you will get errors as a result of self-closing these void elements, even though it aims to enforce the self-closing sign in HTML elements. That's rather confusing, right? In a Vue.js template, we can use either of the following two styles for elements that do not have content:

    • <YourComponent></YourComponent>
    • <YourComponent/> (self-closing)

Under this rule, the first option is rejected, as in the following example:

<template>
<!-- ✓ GOOD -->
<MyComponent/>

<!-- ✗ BAD -->
<MyComponent></MyComponent>
</template>

However, it also rejects the self-closing void elements:

<template>
<!-- ✓ GOOD -->
<img src="...">

<!-- ✗ BAD -->
<img src="..." />
</template>

In other words, void elements are not allowed to have self-closing signs in the Vue rules. So the value for the html.void option is set to 'never' by default. So if you want to allow self-closing signs on these void elements, as in this book, then set the value to 'always'.

  1. Configure the vue/max-attributes-per-line rule to turn off this rule as follows:
// .eslintrc.js
'rules': {
'vue/max-attributes-per-line': 'off'
}

The vue/max-attributes-per-line rule aims to enforce one attribute per line. By default, an attribute is considered to be in a new line when there is a line break between two attributes. The following is an example of how this looks under this rule:

<template>
<!-- ✓ GOOD -->
<MyComponent lorem="1"/>
<MyComponent
lorem="1"
ipsum="2"
/>
<MyComponent
lorem="1"
ipsum="2"
dolor="3"
/>

<!-- ✗ BAD -->
<MyComponent lorem="1" ipsum="2"/>
<MyComponent
lorem="1" ipsum="2"
/>
<MyComponent
lorem="1" ipsum="2"
dolor="3"
/>
</template>

However, this rule conflicts with Prettier. We should let Prettier handle cases like this, which is why we will turn this rule off.

  1. Configure the eslint/space-before-function-paren rule:
// .eslintrc.js
'rules': {
'space-before-function-paren': ['error', 'always']
}

The eslint/space-before-function-paren rule aims to enforce a space before a function declaration's parentheses. It is ESLint's default behavior to add the space and it is also a defined rule in StandardJS. See the following examples:

function message (text) { ... } // ✓ ok
function message(text) { ... } // ✗ avoid

message(function (text) { ... }) // ✓ ok
message(function(text) { ... }) // ✗ avoid

However, under the preceding rule, you will get errors like the following when you use Prettier:

/middleware/auth.js
1:24 error Delete · prettier/prettier

We will ignore the errors from Prettier because we want to follow the rule in Vue. But currently, there is no option from Prettier to disable that yet from https://prettier.io/docs/en/options.html. If you happen to remove that space because of Prettier, you can add it back by setting the value to 'always' under this Vue rule.

  1. Because ESLint targets only .js files by default, include the .vue extension with the --ext option (or a glob pattern) in the ESLint command to run ESLint with the preceding configurations on the terminal:
$ eslint --ext .js,.vue src
$ eslint "src/**/*.{js,vue}"

You also can run it with the custom commands in the scripts option with .gitignore in the package.json file as follows:

// package.json
"scripts": {
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"lint-fix": "eslint --fix --ext .js,.vue --ignore-path
.gitignore ."
}

// .gitignore
node_modules
build
nuxt.config.js
prettier.config.js

ESLint will ignore files defined in the preceding .gitignore snippet while linting all of the JavaScript and Vue files. It is a good idea to lint files on hot reloading via webpack. Just add the following snippet to the Nuxt config file to run ESLint whenever you save your code:

// nuxt.config.js
...
build: {
extend(config, ctx) {
if (ctx.isDev && ctx.isClient) {
config.module.rules.push({
enforce: "pre",
test: /.(js|vue)$/,
loader: "eslint-loader",
exclude: /(node_modules)/
})
}
}
}
You can find an example that uses this plugin with ESLint in /chapter-14/eslint-plugin-vue/integrate/ in our GitHub repository.

As you can see in this and the previous sections, mixing ESLint and Prettier in a single config file can be problematic. The hassle you get may not be worth the effort in making them work together "as a team." Why not try to run them separately without coupling them? Let's find out how you can do this for Nuxt apps in the next section.

Running ESLint and Prettier separately in Nuxt apps

Another possible solution to the conflict between ESLint and Prettier, especially on space-before-function-paren, is not to integrate them at all, but run them to format and lint our code separately. So let's get this working in the following steps:

  1. Create the scripts separately for Prettier and ESLint in the package.json file as follows:
// package.json
"scripts": {
"prettier": "prettier --check "
{components,layouts,pages,store,middleware,plugins}/**/*.{vue,js}
"", "prettier-fix": "prettier --write
{components,layouts,pages,store,middleware,plugins}
/**/*.{vue,js}"", "lint": "eslint --ext .js,.vue
--ignore-path .gitignore .",
"lint-fix": "eslint --fix --ext .js,.vue --ignore-path
.gitignore ."
}

So now we can completely forget about eslint-plugin-prettier and the eslint-config-prettier config in our workflow. We still keep eslint-plugin-vue and the rules that we have already configured in this chapter, but remove Prettier completely from the .eslintrc.js file:

// .eslintrc.js
module.exports = {
//...
'extends': [
'standard',
'plugin:vue/recommended',
// 'prettier' // <- removed this.
]
}
  1. Run Prettier first, then ESLint, when we want to analyze our code:
$ npm run prettier
$ npm run lint
  1. Again, run Prettier first, then ESLint, when we want to fix the format and to lint our code:
$ npm run prettier-fix
$ npm run lint-fix

You can see that this solution keeps our workflow clearer and cleaner in this way. No more conflict – it's a breeze. Sweet.

You can find an example that runs ESLint and Prettier separately in /chapter-14/eslint-plugin-vue/separate/ in our GitHub repository.

Well done. You have made it through the first major part of this chapter. We hope you will start, or have already started, writing beautiful and readable code for your Vue and Nuxt apps, and making use of these amazing formatters and linters. As your Nuxt learning in the book nears its end, we will walk you through how you can deploy the Nuxt app in the next section. So keep reading.

Deploying Nuxt apps

Besides the code linting and formatting, app deployment, too, is a part of the web development workflow. We need to deploy our apps to a server or a host somewhere remotely so that the public can access the app publicly. Nuxt comes with the built-in commands that we can use to deploy our app. They are as follows:

  • nuxt
  • nuxt build
  • nuxt start
  • nuxt generate

The nuxt command is one that you are now familiar with using on your terminal:

$ npm run dev

If you open the package.json file that is generated by Nuxt when installing the project with the create-nuxt-app scaffolding tool, you can see these commands are pre-configured in the "scripts" snippet, as follows:

// package.json
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate"
}

You can launch the command on your terminal with the following Node.js command line:

$ npm run <command>

The nuxt command is used for development with hot-reloading on the development server on localhost:3000, while the others are for production deployment. Let's take a look at how you can use them to deploy your Nuxt app in the next section.

You can also use common arguments such as --help with any of these commands. If you want to find out more, please visit https://nuxtjs.org/guide/commandslist-of-commands.

Deploying a Nuxt universal server-side rendered app

We hope that from working through all the previous chapters, you know that you have been developing Nuxt universal server-side rendered (SSR) apps. An SSR app is an app that renders your app content on the server side. This kind of app requires a specific server to run your apps, such as a Node.js and Apache server, while a universal SSR app like that you've been creating with Nuxt runs on both the server and client sides. This kind of apps requires a specific server too. A Nuxt universal SSR app can be deployed with just two commands on the terminal. Let's take a look at how you can do it in the following steps:

  1. Launch the nuxt build command via npm to build the app with webpack and minify the JavaScript and CSS:
$ npm run build

You should get the following build result:

> [your-app-name]@[your-app-name] start /var/path/to/your/app
> nuxt build
ℹ Production build
ℹ Bundling for server and client side
ℹ Target: server
✓ Builder initialized
✓ Nuxt files generated
...
...
  1. Launch the nuxt start command via npm to start the server in production mode:
$ npm run start

You should get the following start status:

> [your-app-name]@[your-app-name] start /var/path/to/your/app
> nuxt start

Nuxt.js @ v2.14.0

> Environment: production
> Rendering: server-side
> Target: server

Memory usage: 28.8 MB (RSS: 88.6 MB)

That's all it takes to deploy a Nuxt universal SSR app – just two command lines. It's a piece of cake, isn't it? However, if you don't have a Node.js server to host your app, or for any reason you just want to deploy your app as a static site, you can generate it from a Nuxt universal SSR app. Let's find out how you can achieve that in the next section.

Deploying a Nuxt static-generated (pre-rendered) app 

To generate a Nuxt static generated app from the Nuxt universal SSR app, we will use the sample website we created in the previous chapters for this exercise. You can find this sample in /chapter-14/deployment/sample-website/ in our GitHub repository. So let's get cracking with the following steps:

  1. Make sure you have the following "generate" run script in the package.json file as follows:

"scripts": {
"generate": "nuxt generate"
}
  1. Change the target project in the Nuxt config file to static:
// nuxt.config.js
export default {
target: 'static'
}
  1. Generate the 404 page by configuring the generate option in the Nuxt config file:
// nuxt.config.js
export default {
generate: {
fallback: true
}
}

Nuxt does not generate your custom 404 page, nor its default one. If you want to include this page in your static app, you can set fallback: true in the generate option in the config file.

  1. Launch the nuxt generate command via npm to build the app and generate an HTML file for each route:
$ npm run generate

Nuxt has a crawler that scans the links and generates dynamic routes and their async contents (the data rendered with the asyncData and fetch methods) automatically for you. So you should get every route of your app as follows:

ℹ Generating output directory: dist/
ℹ Generating pages with full static mode
✓ Generated route "/contact"
✓ Generated route "/work-nested"
✓ Generated route "/about"
✓ Generated route "/work"
✓ Generated route "/"
✓ Generated route "/work-nested/work-sample-4"
✓ Generated route "/work-nested/work-sample-1"
✓ Generated route "/work-nested/work-sample-3"
✓ Generated route "/work-nested/work-sample-2"
✓ Generated route "/work/work-sample-1"
✓ Generated route "/work/work-sample-4"
✓ Generated route "/work/work-sample-2"
✓ Generated route "/work/work-sample-3"
✓ Client-side fallback created: 404.html
i Ready to run nuxt serve or deploy dist/ directory
Note that you will still need to use generate.routes for generating routes that the crawler cannot detect.
  1. If you look inside your project root directory, you should find a /dist/ folder generated by Nuxt with everything ready inside that you need to deploy the app to the static hosting server. But before that, you can test your production static app from the /dist/ directory with the nuxt serve command on your terminal:
$ npm run start

You should get the following output on your terminal:

Nuxt.js @ v2.14.0 

> Environment: production
> Rendering: server-side
> Target: static
Listening: http://localhost:3000/

ℹ Serving static application from dist/
  1. Now you can point your browser to localhost:3000 and see that the app is running just like SSR, but in fact, it is a static-generated app.

We will come back to this configuration in the next chapter for deploying Nuxt single-page application (SPA) apps. You can see that it involves just a bit of work to go for this type of deployment and it is totally worth it because there are benefits in deploying your app "statically," such as you can get your static files hosted on static hosting servers, which are relatively cheaper than a Node.js server. We will show you how to serve your static site on this kind of server just like GitHub Pages in the next chapter. Even though there are benefits in deploying the Nuxt universal SSR app "statically," there are the following caveats that you must take into account:

  • The Nuxt context given to the asyncData and fetch methods will lose the HTTP req and res objects from Node.js.
  • The nuxtServerInit action will not be available in the store.

So if you have a Nuxt app that relies heavily on these items in the preceding list, then it is probably not a good idea to generate your Nuxt universal SSR app into static files because they are server-side features. However, we can imitate the nuxtServerInit action on the client side with the client-side cookies, which we will also show you in the next chapter. But for now, let's move on to the next section to find out what kind of hosting servers you can choose from to host your Nuxt apps.

If you want to find out more about the generate property/option and other options, such as the fallback and routes options, that you can configure with this property, please visit https://nuxtjs.org/api/configuration-generate.

Hosting the Nuxt universal SSR app on virtual private servers

When it comes to hosting Node.js apps, a virtual private server (VPS) and dedicated servers are better options because you will have the complete freedom to set up the Node.js environment for your apps. And whenever Node.js releases new versions, you should update your environment as well. Only with a VPS server can you upgrade and tweak your environment anytime you need to.

A VPS provider such as Linode or Vultr offers affordable VPS hosting pricing if you are looking for a Linux server and will install the infrastructure that you need from scratch. What these VPS providers give you is an empty virtual machine with your preferred Linux distribution, for example, Ubuntu. The process of building the infrastructure of your needs is the same as how you install Node.js, MongoDB, MySQL, and so on, when you just have a Linux distribution freshly installed on your local machine. For more about these VPS providers, please visit the following links:

After you have the Node.js environment and the infrastructure set up to meet your requirements, you can upload your Nuxt app to this kind of host, then build and start the app very easily on your terminal through the Secure Shell (SSH) function provided by these hosting providers:

$ npm run build
$ npm run start

What about a shared hosting server? Let's take a look at what you have to choose from in the next section.

Hosting the Nuxt universal SSR app on shared hosting servers

Bear in mind that not all hosts are Node.js-friendly and shared hosting servers for Node.js are relatively rare compared to the shared hosting servers for PHP. But all shared hosting servers are the same – what you can do is usually severely restricted and you must follow the strict rules set by the provider. You can check out the following shared hosting servers providers:

In a shared hosting server, for example, at Reclaim Hosting, most likely you cannot run the Nuxt commands to start your app. Instead, you will need to provide an application start file to the server and this file must be called app.js and placed in your project root directory.

If you would like to go for Reclaim Hosting, you can use their test environment at https://stateu.org/ to see how it works for you. But keep in mind that advanced setups are not possible. The good news is that Nuxt provides a Node.js module, nuxt-start, to start Nuxt apps in production mode in a shared hosting server like this. So let's find out how in the following steps:

  1. Install nuxt-start via npm locally:
$ npm i nuxt-start
  1. Create an app.js file in your project root directory with the following code to start the Nuxt app:
// app.js
const { Nuxt } = require('nuxt-start')
const config = require('./nuxt.config.js')

const nuxt = new Nuxt(config)
const { host, port } = nuxt.options.server

nuxt.listen(port, host)

Alternatively, you can use Express or Koa to start your Nuxt app. The following example assumes you are using Express:

// app.js
const express = require('express')
const { Nuxt } = require('nuxt')
const app = express()

let config = require('./nuxt.config.js')
const nuxt = new Nuxt(config)
const { host, port } = nuxt.options.server

app.use(nuxt.render)
app.listen(port, host)

In this code, we import the express and nuxt modules and the nuxt.config.js file, and then use the Nuxt app as the middleware. It is the same if you are using Koa – you only need to use Nuxt as the middleware.

  1. Upload the Nuxt app to the server with this app.js file in it and follow the instructions from the host to install the app dependencies via npm and then run app.js to start your app.

That's all you need to do. There are limitations in these shared hosting servers. You have less control with the Node.js environment in these servers. But you can get your universal SSR Nuxt apps up and running if you follow the strict rules that are set by server providers.

You can find the preceding sample code and others in /chapter-14/deployment/shared-hosting/reclaimhosting.com/ in our GitHub repository for hosting the Nuxt universal SSR app at Reclaim Hosting.

For more information about nuxt-start, please visit https://www.npmjs.com/package/nuxt-start.

You can see that it is not perfect and has its limitations, but it is reasonable if you are looking for shared hosting. If this is not ideal for you, then the last option is to go for the static site hosting servers, as we'll see in the next section.

Hosting the Nuxt static generated app on static site hosting servers

With this option, you will have to lose the server side of Nuxt. But the good news is that there are many popular hosts for hosting a static-generated Nuxt app and you can serve it on almost any host online, quickly. Let's find out how in the following steps:

  1. Change server to static as the target in the Nuxt config file, as follows:
// nuxt.config.js
export default {
target: 'static'
}
  1. Launch the nuxt generate commands locally via npm to generate the static files for your Nuxt app:
$ npm run generate
  1. Upload all the content in the /dist/ folder generated by Nuxt to the host.

The following list details the hosts you can choose from. The deployment processes for all of them are well documented on the Nuxt site. You should check out the Nuxt FAQ at https://nuxtjs.org/faq to check deployment examples and see how to deploy the static generated Nuxt app to any of these specific hosts:

We will guide you through the deployment of Nuxt SPA apps on GitHub Pages in the next chapter. But for now, this is the end of this chapter on formatting, linting, and deploying the Nuxt universal SSR app. Let's summarize what you have learned in this chapter.

Summary

Well done. You have made it this far. It is been quite a journey. In this chapter, we covered JavaScript linters and formatters, notably ESLint, Prettier, and StandardJS for Nuxt apps and also for JavaScript apps in general. You have learned how to install and configure them for your needs and preferences. We also covered the Nuxt commands to deploy Nuxt apps and the options available for hosting the Nuxt app, whether it is a universal SSR app or a static generated site.

In the coming chapter, we will learn how to create an SPA with Nuxt and deploy it to GitHub Pages. You will see the slight difference between traditional SPAs and the SPA in Nuxt (let's called it Nuxt SPA). We will guide you through the process of setting up the SPA development environment in Nuxt, refactoring the universal SSR Nuxt authentication app that you have created in the previous chapters, and turning it into a Nuxt SPA and a static-generated Nuxt SPA. Lastly, you will learn to deploy the static-generated SPA to GitHub Pages. So keep reading.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.8.34