DEV Community

Jeldrik Hanschke
Jeldrik Hanschke

Posted on

Format Glimmer templates with Prettier

Prettier is an opinionated code formatter. It helps developers and teams to stop worry about coding style. Prettier allows developers to write code without manually formatting it for readability. Instead Prettier takes over after the developer has implemented the feature and rewrites the code with a set of opinionated rules tested by many applications in production.

Ember projects get a ready to be used Prettier configuration out of the box. Ember CLI v3.24, which was released in the first days of this year, include Prettier in the blueprints for applications and addons. New projects use it from day one. Existing projects can adopt prettier by updating the blueprints using Ember CLI Update.

By default Prettier is only enabled for JavaScript files. Prettier is not enabled for Glimmer templates. The glimmer parser included in Prettier is not yet officially released. It still includes some minor bugs. But many projects are already using it successfully nevertheless.

This blog post describes how Prettier can be configured to format Glimmer templates as well. Additionally it describes how VSCode needs to be configured to format Glimmer templates with Prettier on save.

Linting Glimmer templates with Prettier

Ember CLI configures Prettier to run as an ESLint plugin. But ESLint is not used for Glimmer templates. The Ember ecosystem has it's developed a dedicated linter for Glimmer templates: Ember Template Lint Both ESLint and Ember Template Lint are included, configured and enabled for Ember projects by default.

Similar to how Prettier is run as ESLint plugin for JavaScript files it could be run as a plugin for Ember Template Lint. Ember community provides an official plugin to do so: ember-template-lint-plugin-prettier.

The plugin adds Prettier as a template lint rule. The rule ensures that template linting fails if any Glimmer template (*.hbs) is not formatted with Prettier.

It is installed with as any other dependency with the package manager used by your project:

# if using yarn
yarn add -D prettier ember-template-lint-plugin-prettier

# if using NPM
npm install --save-dev ember-template-lint-plugin-prettier
Enter fullscreen mode Exit fullscreen mode

Additionally it needs to be configured in template lint configuration of your project:

diff --git a/.template-lintrc.js b/.template-lintrc.js
index 3b0b9af..73c6c78 100644
--- a/.template-lintrc.js
+++ b/.template-lintrc.js
@@ -1,5 +1,6 @@
 'use strict';

 module.exports = {
-  extends: 'octane',
+  plugins: ['ember-template-lint-plugin-prettier'],
+  extends: ['octane', 'ember-template-lint-plugin-prettier:recommended'],
 };
Enter fullscreen mode Exit fullscreen mode

Afterwards yarn lint:hbs will complain if any Glimmer template is not formatted with Prettier.

The application template created by Ember CLI is not formatted with Prettier. If you configured the Prettier plugin for Ember Template Lint successfully, you will see the following linting violation for a new application created with Ember CLI v3.24:

$ yarn lint:hbs
yarn run v1.22.5
$ ember-template-lint .
app/templates/application.hbs
  1:13  error  Replace `"EmberProjectUsingPrettierForTemplates"` with `'EmberProjectUsingPrettierForTemplates'`  prettier
  3:3  error  Replace `--·The·following·component·displays·Ember's·default·welcome·message.·--` with ` The following component displays Ember's default welcome message. `  prettier
  5:3  error  Replace `--·Feel·free·to·remove·this!·--` with ` Feel free to remove this! `  prettier

✖ 3 problems (3 errors, 0 warnings)
  3 errors and 0 warnings potentially fixable with the `--fix` option.
Enter fullscreen mode Exit fullscreen mode

Using double quotes in Glimmer templates but single quotes in JavaScript files

The Ember community has an informal convention to use single quotes in JavaScript files but double quotes in Glimmer templates. It is reflected in official guides and used by new projects.

Prettier is configured to use single quotes in a new Ember project. This is controlled by .prettierrc.js created by Ember CLI blueprints:

'use strict';

module.exports = {
  singleQuote: true,
};
Enter fullscreen mode Exit fullscreen mode

Prettier follows that configuration and also complains about double quotes used in Glimmer templates. We need to update the Prettier configuration to follow the Ember community convention and use single quotes in JavaScript files but double quotes in Glimmer templates.

We can do so adding an override of the default configuration for *.hbs files.

diff --git a/.prettierrc.js b/.prettierrc.js
index 534e6d3..09f6af7 100644
--- a/.prettierrc.js
+++ b/.prettierrc.js
@@ -2,4 +2,12 @@

 module.exports = {
   singleQuote: true,
+  overrides: [
+    {
+      files: '*.hbs',
+      options: {
+        singleQuote: false,
+      },
+    },
+  ],
 };
Enter fullscreen mode Exit fullscreen mode

Running yarn lint:hbs again on our new project it stops complaining about double quotes being used. 💪

But it still complains about using wrong comment style at two places:

$ yarn lint:hbs
yarn run v1.22.5
$ ember-template-lint .
app/templates/application.hbs
  3:3  error  Replace `--·The·following·component·displays·Ember's·default·welcome·message.·--` with ` The following component displays Ember's default welcome message. `  prettier
  5:3  error  Replace `--·Feel·free·to·remove·this!·--` with ` Feel free to remove this! `  prettier

✖ 2 problems (2 errors, 0 warnings)
  2 errors and 0 warnings potentially fixable with the `--fix` option.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Enter fullscreen mode Exit fullscreen mode

Let's find out how we can run Prettier to fix that violations automatically.

Formatting Glimmer templates with Prettier

JavaScript files can be formatted with Prettier running yarn lint:js:fix. This executes eslint with --fix flag. As described above ESLint runs Prettier as a plugin and formats the JavaScript files with it.

Similar Ember projects support yarn lint:hbs:fix command to fix linting errors in Glimmer templates. It executes ember-template-lint with --fix flag. And as thanks to Prettier plugin for Ember Template Lint, which we added earlier, that command tells Prettier to format the Glimmer templates.

$ yarn lint:hbs:fix
yarn run v1.22.5
$ ember-template-lint . --fix
Done in 0.43s.
Enter fullscreen mode Exit fullscreen mode

After running it the app/templates/application.hbs is formatted with Prettier. 🎉

$ git diff app/templates/application.hbs
diff --git a/app/templates/application.hbs b/app/templates/application.hbs
index 6f0ea67..298858c 100644
-------- a/app/templates/application.hbs
+++ b/app/templates/application.hbs
@@ -1,7 +1,7 @@
 {{page-title "EmberProjectUsingPrettierForTemplates"}}

-{{!-- The following component displays Ember's default welcome message. --}}
+{{! The following component displays Ember's default welcome message. }}
 <WelcomePage />
-{{!-- Feel free to remove this! --}}
+{{! Feel free to remove this! }}

 {{outlet}}
\ No newline at end of file
Enter fullscreen mode Exit fullscreen mode

Format JavaScript files with Prettier on save in VSCode

I'm lazy. I don't want to run yarn lint:js:fix manually. Therefore I configured VSCode to fix ESLint violations automatically when I save a file. I guess I'm not the only lazy developer. So let me explain you how that could be done.

First of all we need to install ESLint extension for VSCode. Out of the box that extension will show ESLint violates in VSCode while you are typing.

By default it does not fix linting errors on save automatically. To do so the configuration needs to be adjusted. To do so open the VSCode settings and add the following configuration:

"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
}
Enter fullscreen mode Exit fullscreen mode

Please refer to official documentation for ESLint extension for VSCode for details.

How to do the same for Glimmer Templates?

Format Glimmer templates with Prettier in VSCode

There is no official VSCode extension for Ember Template Lint as far as I know. But we can use Prettier for VSCode to achieve the same.

After installing the extension it needs to be configured to format Glimmer templates. As the Glimmer parser is not officially released yet, Prettier disables it by default. Therefore we need to tell Prettier explicitly to use it for Glimmer templates. To do so we need to update the Prettier configuration:

diff --git a/.prettierrc.js b/.prettierrc.js
index 09f6af7..919bd65 100644
-------- a/.prettierrc.js
+++ b/.prettierrc.js
@@ -6,6 +6,7 @@ module.exports = {
     {
       files: '*.hbs',
       options: {
+        parser: 'glimmer',
         singleQuote: false,
       },
     },
Enter fullscreen mode Exit fullscreen mode

Additionally we need to configure the VSCode extension for Prettier to be active for .hbs files. We can do so by setting prettier.documentSelectors configuration option in VSCode settings.

{
  "prettier.documentSelectors": ["**/*.hbs"],
}
Enter fullscreen mode Exit fullscreen mode

Afterwards Prettier is available as a formatter for Glimmer templates in VSCode.

Alt Text

But we need to trigger the formatting manually. We also need to select Prettier formatter explicitly. These are way more manually steps than I want to do as the lazy developer that I am.

Let's configure VSCode to format Glimmer templates with Prettier on save as we already have it for JavaScript files. As a first step we tell VSCode to use Prettier as default formatter for Glimmer templates. To do so we need to add another line to VSCode settings:

"[handlebars]": {
   "editor.defaultFormatter": "esbenp.prettier-vscode",
},
Enter fullscreen mode Exit fullscreen mode

Alt Text

We don't need to select Prettier formatter explicitly anymore. But we still need to run the formatting manually. Let's additonally enable format on save for Glimmer templates:

"[handlebars]": {
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true
},
Enter fullscreen mode Exit fullscreen mode

As JavaScript files are formatted by ESLint with a code action on save we don't want to enable editor.formatOnSave globally.

Summary

Glimmer templates of our project are now formatted with Prettier. We can run it manually with yarn lint:hbs:fix. But Prettier is also run automatically when saving a template in VSCode. Additionally Ember Template Lint complains if for whatever reason a template is not formatted with Prettier. 🎉

Alt Text

Thanks a lot to Georgii Dolzhykov (@thornO) who showed me how to configure Prettier and VSCode extension for Prettier to format Glimmer templates. And of course to all the great people both from Ember and Prettier community, who created the great tool and worked on adding Glimmer support over the last three years.

If you have any question, know a potential improvement or found an error please do not hesitate to reach out to me either via comment here or in #topic-editors channel on Ember Discord.

Top comments (3)

Collapse
 
jelhan profile image
Jeldrik Hanschke • Edited

I missed the required step to set prettier.documentSelectors configuration option of Prettier's VSCode extension in an earlier version of the post. Added it just now. Thanks a lot to Alon Bukai for reporting it on Ember Discord.

Collapse
 
jelhan profile image
Jeldrik Hanschke

Alon found another bug. The source.fixAll.eslint code action on save must be true of course. It is fixed in latest iteration of the post. Hopefully no one wasted to much time on debugging why it is not working as expected.

Collapse
 
lvegerano profile image
Luis Vegerano

Since Ember/Handlebars is officially supported there is no need to specify the parser in prettierrc.js