by Francesco Agnoletto
How to setup NextJS with TypeScript and ESLint + prettier
The best tools for full stack development with NextJS
May 18, 2020Sharing code on front-end and back-end has always been my dream. NextJS makes it easy with a simple framework including both, simple to run, simple to use.
NextJS makes it really easy to modify its setup, making compatibility a first class citizen.
To jumpstart a NextJS project you don’t need anything more than this command.
$ npm init next-app nextjs-example
Change nextjs-example
to whatever name you want the project to have.
$ cd nextjs-example
to get in the folder, and now we’re ready to start.
NextJS and TypeScript
NextJS comes with TypeScript just one click away, creates an empty tsconfig.json
file and run $ npm run dev
.
The tsconfig will be populated automatically and all .js
files are ready to be converted to .ts
.
Differently from the babel TypeScript presets (used by Gatsby, for example), NextJS will not compile on type errors. I don’t feel a great difference between the two options. At the end of the day, if you are using TypeScript you want your types to be correct, regardless of compilation.
NextJS + prettier
Adding prettier is easily achieved as well.
$ npm i - prettier
And next, create a .prettierrc
file.
// .prettierrc
{
"endOfLine": "lf",
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5"
}
And that’s pretty much it.
NextJS + ESLint
ESLint needs to be configured with both TypeScript and prettier, but also NextJS’s React implementation.
There are quite a few libraries that need to be added for this all to work properly.
npm i -D eslint eslint-loader eslint-plugin-react eslint-config-prettier eslint-plugin-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser
A basic .eslintrc.js
config will look like this.
// .eslintrc.js
module.exports = {
// Specifies the ESLint parser
parser: "@typescript-eslint/parser",
extends: [
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"prettier/@typescript-eslint",
"plugin:prettier/recommended",
],
settings: {
react: {
version: "detect",
},
},
env: {
browser: true,
node: true,
es6: true,
},
plugins: ["@typescript-eslint", "react", "prettier"],
parserOptions: {
ecmaFeatures: {
jsx: true,
},
// Allows for the parsing of modern ECMAScript features
ecmaVersion: 2018,
// Allows for the use of imports
sourceType: "module",
},
rules: {
// Disable prop-types as we use TypeScript for type checking
"react/prop-types": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"prettier/prettier": "error",
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-ignore": "off",
// needed for NextJS's jsx without react import
"react/react-in-jsx-scope": "off",
},
globals: { React: "writable" },
};
I’m not a fan of an overpersonalized linting config. It takes time away from development and introduces complexity to an accepted standard.
BONUS: NextJS and Jest
Testing makes apps more reliable and bug fixing easier. I prefer to have it and write tests as the app progresses.
Interviews go a lot better when you display testing skills. Being on the other side of the interview, I always appreciate candidates who can write tests.
Jest is the go-to testing library for React applications, adding it to a NextJS application is not too difficult but requires some changes.
First, the packages. jest
, @testing-library/jest-dom
and @testing-library/react
for testing, and babel-jest
for the config.
npm i -D jest @testing-library/jest-dom @testing-library/react babel-jest
We need to create a .babelrc
file to enable the testing environment.
// .babelrc
{
"presets": ["next/babel"]
}
The Jest config is pretty short as well, I removed the .css
transformations since NextJS includes a good css-in-js solution to handle styles.
// jest.config.js
module.exports = {
collectCoverageFrom: ["**/*.{ts,tsx}", "!**/*.d.ts", "!**/node_modules/**"],
// we need to create this file
setupFilesAfterEnv: ["<rootDir>/setupTests.js"],
testPathIgnorePatterns: ["/node_modules/", "/.next/",],
transform: {
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
},
transformIgnorePatterns: ["/node_modules/"],
};
Last, the setup file for Jest is just one line.
// setupTests.js
import "@testing-library/jest-dom/extend-expect";
BONUS 2: What about end-to-end tests?
It takes even less time to set up end-to-end testing, I wrote a small how-to here.
If you have any questions, feel free to leave a comment.