Skip to content

Commit f16dde5

Browse files
es lint configured
1 parent 062e581 commit f16dde5

File tree

11 files changed

+1144
-61
lines changed

11 files changed

+1144
-61
lines changed

.eslintrc.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module.exports = {
2+
root: true,
3+
env: {
4+
node: true,
5+
es6: true,
6+
},
7+
parserOptions: {
8+
ecmaVersion: 2020,
9+
sourceType: "module",
10+
},
11+
ignorePatterns: ["node_modules/*", ".next/*", ".out/*", "!.prettierrc.js"], // We don't want to lint generated files nor node_modules, but we want to lint .prettierrc.js (ignored by default by eslint)
12+
extends: ["eslint:recommended"],
13+
overrides: [
14+
// This configuration will apply only to TypeScript files
15+
{
16+
files: ["**/*.ts", "**/*.tsx"],
17+
parser: "@typescript-eslint/parser",
18+
settings: { react: { version: "detect" } },
19+
env: {
20+
browser: true,
21+
node: true,
22+
es6: true,
23+
},
24+
extends: [
25+
"eslint:recommended",
26+
"plugin:@typescript-eslint/recommended", // TypeScript rules
27+
"plugin:react/recommended", // React rules
28+
"plugin:react-hooks/recommended", // React hooks rules
29+
"plugin:jsx-a11y/recommended", // Accessibility rules
30+
],
31+
rules: {
32+
"react/prop-types": "off",
33+
"react/react-in-jsx-scope": "off",
34+
// This rule is not compatible with Next.js's <Link /> components
35+
"jsx-a11y/anchor-is-valid": "off",
36+
"@typescript-eslint/no-unused-vars": ["error"],
37+
"@typescript-eslint/explicit-module-boundary-types": "off",
38+
},
39+
},
40+
],
41+
};

components/date.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { parseISO, format } from "date-fns";
22

3-
export default function Date({ dateString }) {
4-
const date = parseISO(dateString);
5-
return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time>;
6-
}
3+
export const Date: React.FC<{ date: string }> = ({ date }) => (
4+
<time dateTime={date}>{format(parseISO(date), "LLLL d, yyyy")}</time>
5+
);

lib/posts.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import path from "path";
33
import matter from "gray-matter";
44
import remark from "remark";
55
import html from "remark-html";
6-
import { PostMeta } from "../models/post";
6+
import { Post, PostMeta } from "../models/post";
77

88
const postsDirectory = path.join(process.cwd(), "posts");
99

10-
export function getSortedPostsData(): PostMeta[] {
10+
export const getSortedPostsData = (): Post[] => {
1111
// Get file names under /posts
1212
const fileNames = fs.readdirSync(postsDirectory);
1313
const allPostsData = fileNames.map((fileName) => {
@@ -22,22 +22,25 @@ export function getSortedPostsData(): PostMeta[] {
2222
const matterResult = matter(fileContents);
2323

2424
// Combine the data with the id
25+
// const resul
2526
return {
2627
id,
27-
...matterResult.data,
28-
} as PostMeta;
28+
...(matterResult.data as PostMeta),
29+
};
2930
});
3031
// Sort posts by date
3132
return allPostsData.sort((a, b) => {
33+
if (!a.date || !b.date) return 0;
34+
3235
if (a.date < b.date) {
3336
return 1;
3437
} else {
3538
return -1;
3639
}
3740
});
38-
}
41+
};
3942

40-
export function getAllPostIds() {
43+
export const getAllPostIds = () => {
4144
const fileNames = fs.readdirSync(postsDirectory);
4245
return fileNames.map((fileName) => {
4346
return {
@@ -46,7 +49,7 @@ export function getAllPostIds() {
4649
},
4750
};
4851
});
49-
}
52+
};
5053

5154
export const getPostData = async (id: string) => {
5255
const fullPath = path.join(postsDirectory, `${id}.md`);

models/post.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
export interface PostMeta {
2-
id: string;
32
title?: string;
43
date?: string;
4+
contentHtml?: string;
5+
}
6+
7+
export interface Post extends PostMeta {
8+
id: string;
59
}

package.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
{
2-
"name": "my-app",
2+
"name": "blog",
33
"version": "0.1.0",
44
"private": true,
55
"scripts": {
66
"dev": "next dev",
77
"build": "next build",
8-
"start": "next start"
8+
"start": "next start",
9+
"lint": "eslint . --ext .ts"
910
},
1011
"dependencies": {
1112
"date-fns": "^2.11.1",
@@ -19,6 +20,12 @@
1920
"devDependencies": {
2021
"@types/node": "^15.6.0",
2122
"@types/react": "^17.0.6",
23+
"@typescript-eslint/eslint-plugin": "^4.24.0",
24+
"@typescript-eslint/parser": "^4.24.0",
25+
"eslint": "^7.27.0",
26+
"eslint-plugin-jsx-a11y": "^6.4.1",
27+
"eslint-plugin-react": "^7.23.2",
28+
"eslint-plugin-react-hooks": "^4.2.0",
2229
"typescript": "^4.2.4"
2330
}
2431
}

pages/_app.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import "../styles/global.css";
22

3-
export default function App({ Component, pageProps }) {
4-
return <Component {...pageProps} />;
3+
interface AppProps {
4+
Component: any;
5+
pageProps: any;
56
}
7+
8+
const App: React.FC<AppProps> = ({ Component, pageProps }) => {
9+
return <Component {...pageProps} />;
10+
};
11+
12+
export default App;

pages/api/hello.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
export default (req, res) => {
2-
res.status(200).json({ text: "Hello" });
1+
import type { NextApiRequest, NextApiResponse } from "next";
2+
3+
export default (req: NextApiRequest, res: NextApiResponse) => {
4+
res.status(200).json({ name: "John Doe" });
35
};

pages/index.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,16 @@ import { Layout, siteTitle } from "../components/layout";
33
import utilStyles from "../styles/utils.module.css";
44
import { getSortedPostsData } from "../lib/posts";
55
import Link from "next/link";
6-
import Date from "../components/date";
6+
import { Date } from "../components/date";
77
import { GetStaticProps } from "next";
8+
import React from "react";
9+
import { Post } from "../models/post";
810

9-
export default function Home({ allPostsData }) {
11+
interface HomeProps {
12+
allPostsData: Post[];
13+
}
14+
15+
export const Home: React.FC<HomeProps> = ({ allPostsData }) => {
1016
return (
1117
<Layout home>
1218
<Head>
@@ -28,22 +34,26 @@ export default function Home({ allPostsData }) {
2834
<a>{title}</a>
2935
</Link>
3036
<br />
31-
<small className={utilStyles.lightText}>
32-
<Date dateString={date} />
33-
</small>
37+
{date && (
38+
<small className={utilStyles.lightText}>
39+
<Date date={date} />
40+
</small>
41+
)}
3442
</li>
3543
))}
3644
</ul>
3745
</section>
3846
</Layout>
3947
);
40-
}
48+
};
4149

42-
export const getStaticProps: GetStaticProps = async () => {
50+
export const getStaticProps: GetStaticProps<HomeProps> = async () => {
4351
const allPostsData = getSortedPostsData();
4452
return {
4553
props: {
4654
allPostsData,
4755
},
4856
};
4957
};
58+
59+
export default Home;

pages/posts/[id].tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
11
import { Layout } from "../../components/layout";
22
import { getAllPostIds, getPostData } from "../../lib/posts";
33
import Head from "next/head";
4-
import Date from "../../components/date";
4+
import { Date } from "../../components/date";
55
import utilStyles from "../../styles/utils.module.css";
66
import { GetStaticPaths, GetStaticProps } from "next";
7+
import React from "react";
8+
import { Post } from "../../models/post";
79

8-
const Post = ({ postData }) => {
10+
interface PostPageProps {
11+
postData: Post;
12+
}
13+
14+
const PostPage: React.FC<PostPageProps> = ({ postData }) => {
915
return (
1016
<Layout>
1117
<Head>
1218
<title>{postData.title}</title>
1319
</Head>
1420
<article>
1521
<h1 className={utilStyles.headingXl}>{postData.title}</h1>
16-
<div className={utilStyles.lightText}>
17-
<Date dateString={postData.date} />
18-
</div>
19-
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
22+
{postData.date && (
23+
<div className={utilStyles.lightText}>
24+
<Date date={postData.date} />
25+
</div>
26+
)}
27+
{postData.contentHtml && (
28+
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
29+
)}
2030
</article>
2131
</Layout>
2232
);
@@ -31,14 +41,15 @@ export const getStaticPaths: GetStaticPaths = async () => {
3141
};
3242

3343
export const getStaticProps: GetStaticProps = async ({ params }) => {
34-
if (Array.isArray(params.id)) return undefined;
44+
if (!params || !params.id || Array.isArray(params.id)) return { props: {} };
3545

3646
const postData = await getPostData(params.id);
47+
3748
return {
3849
props: {
3950
postData,
4051
},
4152
};
4253
};
4354

44-
export default Post;
55+
export default PostPage;

tsconfig.json

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
{
22
"compilerOptions": {
33
"target": "es5",
4-
"lib": [
5-
"dom",
6-
"dom.iterable",
7-
"esnext"
8-
],
9-
"allowJs": true,
4+
"lib": ["dom", "dom.iterable", "esnext"],
5+
"allowJs": false,
106
"skipLibCheck": true,
11-
"strict": false,
7+
"strict": true,
8+
"noImplicitAny": true,
9+
"strictNullChecks": true,
1210
"forceConsistentCasingInFileNames": true,
1311
"noEmit": true,
1412
"esModuleInterop": true,
@@ -18,12 +16,6 @@
1816
"isolatedModules": true,
1917
"jsx": "preserve"
2018
},
21-
"include": [
22-
"next-env.d.ts",
23-
"**/*.ts",
24-
"**/*.tsx"
25-
],
26-
"exclude": [
27-
"node_modules"
28-
]
19+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
20+
"exclude": ["node_modules"]
2921
}

0 commit comments

Comments
 (0)