기본 작업 목록 작성

ExamPro Markdown 랩 섹션 1


이것은 ExamPro 다음 단계의 일부분이다.그럼요.Preview of complete lab deployed on Vercel
이 랩에서는 다음 스택을 사용하여 ExamPro의 작업 목록 섹션을 작성합니다.

기술 창고

  • 노드js(12.22.0 이상)
  • 다음.js(12.0.4)
  • 반응(17.0.2)
  • 후풍 CSS(3.0.0)
  • 회색(4.0.3)
  • 태그(4.0.3)
  • 어플리케이션 캡처

    localhost:3000/jobs/ 모든 작업 목록 표시
    localhost:3000/jobs/[slug] 개별 작업 표시

    개시하다


    새 저장소를 시작하거나 현재exampro-nextjs 프로젝트를 계속할 수 있습니다.
    만약 당신이 0에서 시작한다면, 1단계를 계속 실행하십시오.

    이제 시작이야.js

  • 새 다음을 만듭니다.js 프로그램 호출 exampro-markdown
  • npx create-next-app@latest exampro-markdown
    
  • 디렉토리exampro-markdown로 변경
  • cd exampro-markdown
    

    TailwindCSS 설정

  • TailwindCSS, 피어 의존 항목, 플러그인 및 기타 Tailwind 실험실 도구 설치
  • npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
    
    npm install @headlessui/react @heroicons/react
    
  • 초기화 후풍 프로필
  • npx tailwindcss init -p
    
  • 파일의 다음 행으로 원래 내용을 대체하여 CSS에 Tailwind 포함
  • @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/*"]
        }
      }
    }
    

    제공된 어셈블리 및 스타일시트 사용

  • 다음 어셈블리와 스타일시트를 프로젝트에 복사합니다.TailwindCSS를 사용하여 설계된 React 어셈블리입니다.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';
    
  • getStaticProps() 함수 만들기
  • 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';
    
  • getStaticPaths 만들기() 함수
  • 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,
      };
    }
    
  • getStaticProps() 함수 만들기
  • // 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,
        },
      };
    }
    
  • JobPage() 함수는 mattergray-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>
      );
    }
    

    좋은 웹페이지 즐겨찾기