Configuring Next.js with Typescript, Tailwind CSS, ESLint, and Jest
Next.js might be the best way to set up a new React project in 2020 & 2021. I don’t even know if it’s worth to appraise it even more, but yeah the Next.js team did a great job!
It just stands out with all the needed features to build bulletproof web applications: hybrid approach with SSR, SSG, ISR, hosting can be done on the Vercel platform on a serverless runtime. Static assets are where they belong, hosted in a CDN edge network for fast delivery. 🏃🏃🏃
So let’s configure Next with our favorite tools: Typescript & Tailwind CSS, and we’ll use ESLint for lining and Jest to write tests.
Setup Next.js with TS
Go to a terminal and run (replace next-ts-tailwind with your desired app name):
npx create-next-app next-ts-tailwind
< "compilerOptions": < "allowJs": true, "alwaysStrict": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "isolatedModules": true, "jsx": "preserve", "lib": ["dom", "ES2020"], "module": "esnext", "moduleResolution": "node", "noEmit": true, "noFallthroughCasesInSwitch": true, "noUnusedLocals": true, "noUnusedParameters": true, "resolveJsonModule": true, "skipLibCheck": true, "strict": true, "target": "esnext" >, "exclude": ["node_modules"], "include": ["**/*.ts", "**/*.tsx"] >
yarn add —dev typescript @types/react @types/node
- Go to /pages/index.js and change it to index.tsx
- Run yarn dev
- all good and running on http://localhost:3000/
Setting up Tailwind CSS
The Tailwind team already put together an excellent tutorial to set this up with Next.js, but there are just a few changes needed for it to work with TS files.
yarn add tailwindcss postcss autoprefixer
yarn add tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
This makes sure that when we build for production only the classes that we use from the tailwind framework will remain in the final production css file. It’s called tree shaking if you need a more fancy term to impress your grandma. 👵
@tailwind base; @tailwind components; @tailwind utilities;
- Go to your pages/_app.js (that you should rename to _app.tsx) component and make sure it looks like this:
import "../styles/globals.css"; import type < AppProps >from "next/app"; function MyApp(< Component, pageProps >: AppProps) < return />; > export default MyApp;
import Head from "next/head"; import styles from "../styles/Home.module.css"; export default function Home() < return ( > Be Warned
You are using Tailwind CSS!
); >
Running the app with yarn dev you should see:
Setting up ESLint
Go to package.json and in the scripts section, add:
Now, if you try yarn lint , you will see a bunch of errors. Go to eslintrc.json and modify it to:
< "env": < "browser": true, "es2021": true, "node": true, "jest": true >, "extends": [ "eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended" ], "parser": "@typescript-eslint/parser", "settings": < "react": < "version": "detect" // Automatically detect the react version >>, "parserOptions": < "ecmaFeatures": < "jsx": true >, "ecmaVersion": 12, "sourceType": "module" >, "plugins": [ "react", "@typescript-eslint" ], "rules": < "react/react-in-jsx-scope": "off", "@typescript-eslint/explicit-module-boundary-types": "off" >>
Note that I also disabled the explicit-module-boundary-types because I like TS to do its job and infer the return types for me, but you can remove that if you like to always add return types to your functions. There will be other lint warnings that you will probably not like and turn off, that’s totally fine.
Running yarn lint now should result in no warnings and errors.
Note that you should probably use the ESLint VSCode extension if you use VSCode. This way you can see errors and fix them as they pop-up while you code.
Adding Jest
yarn add —dev babel-jest jest @types/jest @types/babel-generator
- in package.json scripts section — add «test»: «jest —watch»
- create a .babelrc file in the root and add in it:
module.exports = < setupFilesAfterEnv: ["/jest.setup.ts"], testPathIgnorePatterns: ["/.next/", "/node_modules/"], >;
import "@testing-library/jest-dom";
Next, let’s add the React testing packages:
yarn add —dev @testing-library/react @testing-library/dom @testing-library/jest-dom @testing-library/user-event
Create in the components folder a file SomeComp.test.tsx with:
import < render >from "@testing-library/react"; function SomeComp() < return Hello; > describe("SomeComp", () => < it("renders Hello", () => < const < getByText >= render(); expect(getByText("Hello")).toBeInTheDocument(); >); >);
Run yarn test : PASS components/SomeComp.test.tsx SomeComp √ renders Hello (24 ms)
Conclusions
If you got this far congrats — you have a Next.js app configured with TS, Tailwind CSS, ESLint, and the testing is set up with Jest and RTL. 🥳
If you got stuck or prefer to see the working solution directly you can check it out on Github.
I post more cool content on Twitter 🔥🔥.
Встроенная поддержка CSS
Next.js позволяет импортировать файлы CSS из файла JavaScript. Это возможно, потому что Next.js расширяет концепцию importJavaScript.
Добавление глобальной таблицы стилей
Например, рассмотрим следующую таблицу стилей с именем styles.css :
import '../styles.css' // This default export is required in a new 'pages/_app.js' file. export default function MyApp(< Component, pageProps >) < return /> >
Эти стили ( styles.css ) будут применяться ко всем страницам и компонентам вашего приложения. Из-за глобального характера таблиц стилей и во избежание конфликтов вы можете импортировать их только внутри pages/_app.js .
В процессе разработки такое представление таблиц стилей позволяет загружать стили в горячем режиме по мере их редактирования, что означает, что вы можете сохранить состояние приложения.
В процессе производства все файлы CSS будут автоматически объединены в один минифицированный .css файл.
Импортировать стили из node_modules
Начиная с Next.js 9.5.4, импорт файла CSS из node_modules разрешен в любом месте вашего приложения.
Для глобальных таблиц стилей, таких как bootstrap или nprogress , вы должны импортировать файл внутри pages/_app.js . Например:
// pages/_app.js import 'bootstrap/dist/css/bootstrap.css' export default function MyApp(< Component, pageProps >) < return /> >
Для импорта CSS, необходимого для стороннего компонента, вы можете сделать это в своем компоненте. Например:
// components/ExampleDialog.js import < useState >from 'react' import < Dialog >from '@reach/dialog' import '@reach/dialog/styles.css' function ExampleDialog(props) < const [showDialog, setShowDialog] = useState(false) const open = () =>setShowDialog(true) const close = () => setShowDialog(false) return ( ) >
Добавление CSS на уровне компонентов
Next.js поддерживает модули CSS, используя [name].module.css соглашение об именах файлов.
Модули CSS локально охватывают CSS, автоматически создавая уникальное имя класса. Это позволяет использовать одно и то же имя класса CSS в разных файлах, не беспокоясь об противоречиях.
Такое поведение делает модули CSS идеальным способом включения CSS на уровне компонентов. Файлы модуля CSS можно импортировать в любое место вашего приложения.
Например, рассмотрим повторно используемый Button компонент в папке components/ :
Сначала создайте components/Button.module.css со следующим содержимым:
/* You do not need to worry about .error <> colliding with any other '.css' or '.module.css' files! */ .error
import styles from './Button.module.css' export function Button() < return ( ) >
Модули CSS являются дополнительной функцией и доступны только для файлов с расширением .module.css . Стандартные таблицы стилей и глобальные файлы CSS по-прежнему поддерживаются.
При производстве все файлы модуля CSS будут автоматически объединены во множество минифицированных файлов и .css файлов с разделением кода. Эти .css файлы представляют собой горячие пути выполнения в вашем приложении, обеспечивая загрузку минимального количества CSS для отрисовки вашего приложения.
Поддержка Sass
Next.js позволяет импортировать Sass с использованием .scss и .sass расширений. Вы можете использовать Sass на уровне компонентов через модули CSS и расширение .module.scss или .module.sass .
Прежде чем вы сможете использовать встроенную поддержку Sass в Next.js, обязательно установите sass :
Поддержка Sass имеет те же преимущества и ограничения, что и встроенная поддержка CSS, описанная выше.
Примечание: Sass поддерживает два разных синтаксиса, каждый со своим расширением. .scss расширение требует использовать синтаксис SCSS, в то время как .sass расширение требует использовать углубленный синтаксис ( «Sass»).
Если вы не уверены, что выбрать, начните с .scss расширения, которое является надмножеством CSS и не требует изучения синтаксиса с отступом («Sass»).
Настройка параметров Sass
Если вы хотите настроить компилятор Sass, вы можете сделать это с помощью sassOptions в next.config.js .
Например, чтобы добавить includePaths :
const path = require('path') module.exports = < sassOptions: < includePaths: [path.join(__dirname, 'styles')], >, >
Less и Stylus поддержка
Для поддержки импорта .less или .styl файлов, вы можете использовать следующие плагины:
Если вы используете плагин less, не забудьте добавить зависимость и от less, иначе вы увидите сообщение об ошибке:
Error: Cannot find module 'less'
CSS-in-JS
function HiThere() < return >>hi there
> export default HiThere
Мы связываем styled-jsx , чтобы обеспечить поддержку CSS с изолированной областью видимости. Цель состоит в том, чтобы поддерживать «теневой CSS», аналогичный веб-компонентам, которые, к сожалению, не поддерживают рендеринг на сервере и предназначены только для JS.
См. Приведенные выше примеры для других популярных решений CSS-in-JS (например, стилизованных компонентов).
Компонент с использованием styled-jsx выглядит так:
function HelloWorld() < return ( Hello world scoped!
) > export default HelloWorld
Вопросы-Ответы
Работает ли он с отключенным JavaScript? Да, если вы отключите JavaScript, CSS все равно будет загружен в производственную сборку ( next start ). Во время разработки мы требуем, чтобы JavaScript был включен, чтобы обеспечить максимальное удобство для разработчиков с помощью быстрого обновления.
Typed CSS/SCSS Modules With ReactJS and NextJS
Typescript has saved us from lots of spelling errors in javascript files.
But there is no built in support for CSS modules. Fortunately we can use plugins to fill that gap.
Same can be used for SCSS or SASS modules also. Without type safety I found myself making lots of spelling errors with css class names.
So we will add typed css modules in NextJS and ReactJS as follows.
To read rest of the article please Purchase Subscription
Before we get started with NextJS I would recommend to develop NextJS project inside development docker container.
So we no longer have the issue of «this works on my computer». And it will not mess with your existing workflow.
So checkout my blog post for detailed video explanation.
Let’s start with NextJS starter project with typescript enabled. Add dev dependency as follows.
npm i -D typescript-plugin-css-modules
Now we need to add the plugin in tsconfig.json as follows
prettier-ignore --> < "compilerOptions": < . "plugins": [< "name": "typescript-plugin-css-modules" >] >, . >
Then we need to add type definition file somewhere in the root. I have added in types->css.d.ts
prettier-ignore --> declare module "*.module.css" < const classes: < [key: string]: string> export default classes > declare module "*.module.scss" < const classes: < [key: string]: string> export default classes >
The process for ReactJS is the same except skip the above step in react.
Now the MOST IMPORTANT STEP making it work with VS Code editor.
If you are not using VSCode then you can just skip to the end.
Create a new file at the root .vscode->settings.json if it doesn’t exist already. And add the following setting.
prettier-ignore --> < "typescript.tsdk": "node_modules/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true >
So in order for plugin to take effect VSCode must use typescript that is installed in `node_modules` folder of the project.
By default VSCode uses its own copy of typescript for improved performance.
Now open only single NextJS project in your workspace so these settings will take effect.
There will be pop up after these settings take effect. If there is no pop up then something has gone wrong. Make sure you click on Allow.
This is main trick of making typed css modules work with VSCode.
Now you can use autocomplete css modules in NextJS as follows
prettier-ignore --> import styles from '../styles/Home.module.css' export default function Home() return ( div className=styles.container>>
If you need to use SASS then just install it as dev dependency npm i -D sass and rename files and use it as follows
prettier-ignore --> import styles from '../styles/Home.module.scss' export default function Home() return ( div className=styles.container>>
In ReactJS it works the same way. Just renames classes to camel case as follows.
prettier-ignore --> import styles from './App.module.css'; function App() return ( div className=styles.App>> header className=styles.AppHeader>>
Conclusion
I know its lot of headache to setup typed css modules.
That you can only have single project in workspace for settings to take effect.
But the amounts of stupid spelling mistakes that you can avoid are priceless.
Free users cannot comment below so if you have questions then tweet me @apoorvmote. I would really like to hear your brutally honest feedback.
If you like this article please consider purchasing paid Subscription
You have read this article already.
You are reading > of > free article this month.
To read without restrictions please