visit
mkdir next-ts-starter
cd next-ts-starter
yarn init
Hit enter on everything if you don't want to configure your npm package yet.
This will create a package.json file for you. That's all we need to start adding the other packages.yarn add --dev typescript
Then, we will need to create a new file in the root directory called tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"sourceMap": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
],
"exclude": [
"node_modules"
]
}
yarn add react react-dom
yarn add --dev @types/node @types/react
yarn add next
Now let's go back to packages.json and add the Next JS scripts:
...
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
...
Then we'll need to create a next-env.d.ts file for the types:
/// <reference types="next" />
/// <reference types="next/types/global" />
And optionally, we can create the next.config.js file in which we can extend the webpack config, or add our environment variables:
module.exports = {
distDir: 'build',
publicRuntimeConfig: {
// add your public runtime environment variables here with NEXT_PUBLIC_*** prefix
},
webpack: (config) => {
// extend your webpack configuration here
return config;
},
}
Now let's create the initial page and test if it works. Create a new directory called pages in the root, and inside create an index.tsx file:
import { FC } from 'react';
const IndexPage: FC = () => {
return <h1>Hello, CodeChem!</h1>;
};
export default IndexPage;
Tip: as with React 17, you don't need to add "import React from 'react';" in your component files anymore!
Okay so now let's execute yarn dev and head to . You should see the "Hello, CodeChem!" heading. And that means everything works fine and we're ready to move on.yarn add tailwindcss
Optionally, we can create the empty tailwind.config.js file in the root directory:
module.exports = {
important: true,
purge: {
content: ['./pages/**/*.tsx']
},
theme: {},
variants: {},
plugins: [],
future: {
purgeLayersByDefault: true,
},
};
Tip: to completely utilize the purging functionality, add your new folders in the second line with the tsx postfix.
Next, we'll need to install the postcss-import package:yarn add postcss-import@^12.0.0
At the time of writing this article, postcss-import version 13.0.0 is breaking the tailwind implementation, therefore we will explicitly use the ^12.0.0 version.
Then create a new file postcss.config.js file:
module.exports = {
plugins: [
'postcss-import',
'tailwindcss',
'autoprefixer',
],
};
In order to include Tailwind into our app, first we'll need to create a new CSS file in the root directory that includes Tailwind CSS. You can name this as you wish. We'll name it global.css for now:
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
Now, in order to include it in our app, we'll need to override Next JS's _app.tsx page by creating a new file: pages/_app.tsx:
import { FC } from 'react';
import { AppProps } from 'next/app';
import '../global.css';
const App: FC<AppProps> = ({ Component, pageProps }: AppProps) => <Component {...pageProps} />;
export default App;
So to validate that everything works, let's head back to index.tsx and add a tailwind class to the
<h1>Hello, CodeChem!</h1>
like so:<h1 className="text-green-500">Hello, CodeChem!</h1>
Eslint
First, let's install Eslint and its React plugins:yarn add --dev eslint eslint-plugin-react eslint-plugin-react-hooks
yarn add --dev @typescript-eslint/eslint-plugin @typescript-eslint/parser
With that in place, let's create the Eslint config file .eslintrc.js in the root directory:
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],.
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
rules: {
},
settings: {
react: {
version: 'detect',
},
},
};
Also, since you don't need to import React since React 17, Eslint might still suggest you do. In order to fix that, head to .eslintrc.js and add the following line in the rules section:
'react/react-in-jsx-scope': 'off',
Prettier
To top it off, we'll add Prettier into the mix! Let's start by installing the Prettier package and the Eslint plugin:yarn add --dev prettier eslint-config-prettier eslint-plugin-prettier
Now let's create a .prettierrc.js file in the root directory:
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
tabWidth: 4,
quoteProps: 'preserve'
};
And to configure Eslint to work with Prettier, let's head back to .eslintrc.js to add the Prettier extensions in the extends array:
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
Your final .eslintrc.js should look like this:
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended',
],
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
rules: {},
settings: {
react: {
version: 'detect',
},
},
};
Previously published at