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-exampleChange 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 - prettierAnd 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.
