Quick and Dirty Formatting with ESLint, 11ty, and Prettier

Posted Tuesday, July 5, 2022 by Sri.Tagged MEMO
EDIT STATUS:new

I've extended Eleventy with my own custom template shortcodes, template filters, and transforms, which are loaded in the .eleventy.js configuration file and activated through the eleventyConfig API object.

To improve the experience, I want to add the following features to my Visual Studio Code editing experience:

  • live code linting with ESLint
  • live code reformatting through Prettier
  • live type checking through typescript

Ordinarily, the eslint, prettier, and typescript packages are universal command line tools that accept a list of files that are transformed or analyzed. Visual Studio Code can make use of them by running the contents of the current files in the workspace through these tools every timne we make a change. This bridge is done through VSCode extensions that rely upon these packages. However, the packages must first be configured correctly to work at the command line, otherwise nothing will happen.

.editorconfig

Note: set VSCode setting files.trimTrailingWhitespace to false to avoid conflict with trim_trailing_whitespace below.

root = true
# settings for our default files
[*.{js,jsx,ts,tsx,json,md,html,txt,css}]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
# settings for markdown
[*.md]
trim_trailing_whitespace = false

.eslintrc.js

module.exports = {
'env': {
'browser':true,
'node':true,
'commonjs': true,
'es2021': true
},
'extends': [
'eslint:recommended',
'prettier'
],
'parserOptions': {
'ecmaVersion': 'latest'
},
'rules': {}
};

.prettierrc.js

module.exports = {
semi: true,
printWidth: 82,
singleQuote: true,
quoteProps: 'preserve',
arrowParens: 'avoid',
trailingComma: 'none'
};

Add Live Linting with ESLint and Prettier

To ensure consistent editor settings across multiple projects, install EditorConfig plugin and add the config file (right sidebar).

Then install the ESLint and Prettier extensions:

  • ESLint Extension (dbaeumer.vscode-eslint)
  • Prettier Extension (esbenp.prettier-vscode)

Now install the underlying libraries from the command line:

  • npm install --save-dev eslint prettier
  • npm install --save-dev eslint-config-prettier

Finally, create the ESLint configuration file to make it work. Call it .eslintrc.js in your workspace root, and then copy the text into it (right sidebar).

At this point, your editor windows will now do the live linting and formatting!

  • if there is a linting error in your code, it will be highlighted, and the PROBLEMS tab in the terminal area will display the specific lint problems.
  • everytime you save a file, Pretttier will reformat it.
  • You can use a .prettierrc.js file to turn certain features on/off (see right sidebar)

Adding Typescript Support

If you want to use Typescript, you have to make also some changes to your Eleventy build system, because Typescript has to be transpiled before it can be run, which you don't have to do with "vanilla" Eleventy:

  • eleventy to just build the files once
  • eleventy --serve to build and serve files, and also rebuilt on change

What we want is to process our typescript files then run eleventy:

  • typescript then eleventy
  • typescript then eleventy --serve

So there are two parts to this:

  1. Adding Live Code Linting with Typescript
  2. Adding Typescript Support to Eleventy

Adding Live Code Linting with Typescript

[ insert eslint changes ]

Adding Typescript Support to Eleventy

[ insert webpack, babel changes ]


webpack.config.js

const path = require("path");
const ENTRY = 'src-ext';
const FILE = 'ext-load.ts';
module.exports = [
{
entry: path.join(__dirname,ENTRY,FILE),
output: {
path: path.join(__dirname,ENTRY),
filename: "ext-loader-built.js",
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
loader: "babel-loader",
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
target: "node"
}
];

.babelrc

{
"presets": [
"@babel/preset-env",
"@babel/preset-typescript"
]
}

tsconfig.json

{
"compilerOptions": {
"target": "es6",
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"allowJs": true,
"outDir": "build"
},
"exclude": ["node_modules"],
"files": [
"typings/index.d.ts",
"entry.ts"
]
}

I'm going to use the venerable webpack bundler, which is currently at version 5 at the time of this writing. Webpack can handle all kinds of asset types as well through a multitude of "loaders", which provides an alternative to relying on Eleventy to handle everything.

First install the package for typescript and webpack:

  • npm i -D typescript

We have two related goals: (1) compile typescript and (2) lint typescript. For case (1), we will need babel. For case (2), we will need some ESLint plugins so our Live Linting will also understand Typescript.

Lets install Babel and its typescript support:

  • npm i -D @babel/core @babel/preset-env babel-loader
  • npm i -D ts-node @babel/preset-typescript

Next install the packages for connecting Typescript to ESLint, documented here.

  • npm i -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

Now that the base packages are loaded, we can stitch everything together.

A. Configuring Webpack to work with Babel