기본 작업 목록 작성
40496 단어 tailwindcssreactmarkdownnextjs
ExamPro Markdown 랩 섹션 1
이것은 ExamPro 다음 단계의 일부분이다.그럼요.Preview of complete lab deployed on Vercel
이 랩에서는 다음 스택을 사용하여 ExamPro의 작업 목록 섹션을 작성합니다.
기술 창고
어플리케이션 캡처
localhost:3000/jobs/
모든 작업 목록 표시localhost:3000/jobs/[slug]
개별 작업 표시개시하다
새 저장소를 시작하거나 현재
exampro-nextjs
프로젝트를 계속할 수 있습니다.만약 당신이 0에서 시작한다면, 1단계를 계속 실행하십시오.
이제 시작이야.js
exampro-markdown
npx create-next-app@latest exampro-markdown
exampro-markdown
로 변경cd exampro-markdown
TailwindCSS 설정
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
npm install @headlessui/react @heroicons/react
npx tailwindcss init -p
@tailwind base;
@tailwind components;
@tailwind utilities;
./styles/globals.css
에서 파일 상단에 다음 줄을 추가하여 tailwind.config.js
색상에 추가const colors = require('tailwindcss/colors');
팔레트를 포함orange
까지 확장module.exports = {
content: ['./components/**/*.js', './pages/**/*.js'],
theme: {
extend: {
colors: {
orange: colors.orange,
},
},
},
variants: {
extend: {},
},
plugins: [],
};
더 예쁘고 튼튼한 갈고리 설정(옵션)
npm install --save-dev --save-exact prettier
npm install --save-dev husky lint-staged
npx husky install
npm set-script prepare "husky install"
npx husky add .husky/pre-commit "npx lint-staged"
orange
{
"arrowParens": "always",
"bracketSpacing": true,
"embeddedLanguageFormatting": "auto",
"endOfLine": "lf",
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"bracketSameLine": false,
"jsxSingleQuote": false,
"proseWrap": "preserve",
"quoteProps": "as-needed",
"requirePragma": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false,
"vueIndentScriptAndStyle": false,
"printWidth": 100
}
.prettierrc.json
package.json
package-lock.json
node_modules/
.cache
.next
.prettierignore
에 다음 스크립트와 lint staged를 추가합니다. "scripts": {
...
"prettier": "prettier --write \"./**/*.{md,json,html,css,js,yml}\"",
"prettier-check": "prettier --check \"./**/*.{md,json,html,css,js,yml}\"",
...
},
...
"lint-staged": {
"**/*": "prettier --write --ignore-unknown"
}
재질 설치 및 표시
npm install --save gray-matter
npm install marked
불필요한 파일 및 코드 삭제
package.json
파일styles/Home.module.css
및 <div>
행의 모든 항목 삭제import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
설정/페이지 / 인덱스js
이것은 baseUrl 옵션에 대해 계산할 경로를 지정합니다.
import
파일{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"baseUrl": ".",
"paths": {
"@/components/*": ["components/*"],
"@/config/*": ["config/*"],
"@/styles/*": ["styles/*"]
}
}
}
제공된 어셈블리 및 스타일시트 사용
jsconfig.json
가격 인하 내용jsconfig.json
Markdown.module.css
./components/Footer.js
로부터의 메인 파이프./components/Header.js
./components/Layout.js
파일import Main from '@/components/Main';
import Layout from '@/components/Layout';
export default function Home() {
return (
<Layout>
<Main />
</Layout>
);
}
./components/Main.js
서버 부팅가격 인하 실시
작업 포스터
./components/jobs/Job.js
파일의 작업 공고로 이 디렉터리를 채웁니다../components/jobs/JobsHeader.js
의 ./components/jobs/TypeLabel.js
파일을 복사하거나 Lorem Markdownum를 사용하여 자체 파일을 만들 수 있습니다.frontmatter를 가격 인하에 포함시키도록 하세요.Frontmatter는 다음과 같이 보입니다.---
title: 'Cloud Support Engineer'
type: 'Part-Time'
location: 'Remote'
category: 'Operations, IT and Support Engineering'
---
JobPostings 구성 요소(모든 작업 목록을 표시하는 페이지 구성 요소)
./components/jobs/TypeList.js
파일./styles/Markdown.module.css
및 ./pages/index.js
모듈npm run dev
수입/jobs
import { promises as fs } from 'fs';
import path from 'path';
import matter from 'gray-matter';
import Job from '@/components/jobs/Job';
import Layout from '@/components/Layout';
export async function getStaticProps() {
// Read from /jobs directory
const files = await fs.readdir(path.join('jobs'));
// Map through jobs directory
const jobs = files.map(async (filename) => {
// Set 'slug' to name of md file
const slug = filename.replace('.md', '');
// Read all markdown from file
const markdown = await fs.readFile(path.join('jobs', filename), 'utf-8');
// Extract data from markdown
const { data } = matter(markdown);
// return slug and data in an array
return {
slug,
data,
};
});
return {
props: {
jobs: await Promise.all(jobs),
},
};
}
.md
함수는 .md
함수에서 /jobs
도구를 가져오고 pages/jobs/index.js
의 모든 작업 태그 파일을 비추게 됩니다.// Takes the `jobs` prop from the getStaticProps() function
export default function JobPostings({ jobs }) {
return (
<Layout title="Jobs | ExamPro">
<div className="px-4 py-4 sm:px-6 md:flex md:items-center md:justify-between">
<div className="flex-1 min-w-0">
<h2 className="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate">
Job Postings
</h2>
</div>
</div>
<div className="bg-white my-4 shadow overflow-hidden divide-y divide-gray-200 sm:rounded-md">
<ul role="list" className="divide-y divide-gray-200">
{/* Maps through each job */}
{jobs.map((job, index) => (
<Job key={index} job={job} />
))}
</ul>
</div>
</Layout>
);
}
태그 구성 요소(태그 분석용)
이 구성 요소는 태그 내용을 html로 해석하는 과정을 처리하여 우리는 태그를 설정 스타일로 사용할 수 있다.모듈css
fs
파일import { marked } from 'marked';
import styles from '@/styles/Markdown.module.css';
// Takes content (for example from ./pages/jobs/[slug].js)
export default function Markdown({ content }) {
return (
// Uses marked to parse markdown to html
<div className={styles.markdown} dangerouslySetInnerHTML={{ __html: marked(content) }}></div>
);
}
JobPage 구성 요소(개별 직무 공지)
path
파일import { promises as fs } from 'fs';
import path from 'path';
import Link from 'next/link';
import matter from 'gray-matter';
import { BriefcaseIcon, LocationMarkerIcon, UsersIcon } from '@heroicons/react/solid';
import Markdown from '@/components/Markdown';
import Layout from '@/components/Layout';
export async function getStaticPaths() {
// Read from the /jobs directory
const files = await fs.readdir(path.join('jobs'));
// Map through the files
const paths = await Promise.all(
files.map(async (filename) => ({
params: {
// Create a slug using the name of the file without the .md extension at the end
slug: filename.replace('.md', ''),
},
}))
);
return {
paths,
fallback: false,
};
}
// This function takes the slug from getStaticPaths()
export async function getStaticProps({ params: { slug } }) {
// Read file with name of slug + .md extension in the /jobs directory
const markdown = await fs.readFile(path.join('jobs', slug + '.md'), 'utf-8');
// Use `matter` to extract the content and data from each file
// content is the body of the markdown file
// data is the frontmatter of the markdown file
const { content, data } = matter(markdown);
// Return content, data, and slug as props
return {
props: {
content,
data,
slug,
},
};
}
matter
와 gray-matter
를 getStaticProps()의 도구로 하고React 구성 요소로 표시합니다export default function JobPage({ content, data }) {
return (
<Layout title={`${data.title} | ExamPro`}>
<div className="px-4 py-4 sm:px-6 md:flex md:items-center md:justify-between lg:flex lg:items-center lg:justify-between">
<div className="flex-1 min-w-0">
<h2 className="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate">
{data.title}
</h2>
<div className="mt-1 flex flex-col sm:flex-row sm:flex-wrap sm:mt-0 sm:space-x-6">
<div className="mt-2 flex items-center text-sm text-gray-500">
<UsersIcon
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
aria-hidden="true"
/>
{data.category}
</div>
<div className="mt-2 flex items-center text-sm text-gray-500">
<LocationMarkerIcon
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
aria-hidden="true"
/>
{data.location}
</div>
<div className="mt-2 flex items-center text-sm text-gray-500">
<BriefcaseIcon
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-400"
aria-hidden="true"
/>
{data.type}
</div>
</div>
</div>
<div className="mt-5 flex lg:mt-0 lg:ml-4">
<span className="sm:ml-3">
<Link href="/jobs" passHref>
<button
type="button"
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-orange-500 hover:bg-orange-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-400"
>
Back to Jobs
</button>
</Link>
</span>
</div>
</div>
<div>
<Markdown content={content} />
</div>
</Layout>
);
}
Reference
이 문제에 관하여(기본 작업 목록 작성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/cindyledev/create-a-job-listing-using-nextjs-tailwindcss-and-markdown-4kf0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)