Woongjae Lee
Daangn - Frontend Core Team ex) NHN Dooray - Frontend Team Leader ex) ProtoPie - Studio Team
Lead Software Engineer @ProtoPie
Microsoft MVP
TypeScript Korea User Group Organizer
Marktube (Youtube)
이 웅재
npx create-next-app
~/fds17th
➜ npx create-next-app
npx: 1개의 패키지를 1.307초만에 설치했습니다.
✔ What is your project named? … start-with-create-next-app
Creating a new Next.js app in /Users/mark/fds17th/start-with-create-next-app.
Installing react, react-dom, and next using npm...
...
Initialized a git repository.
Success! Created start-with-create-next-app at /Users/mark/fds17th/start-with-create-next-app
Inside that directory, you can run several commands:
npm run dev
Starts the development server.
npm run build
Builds the app for production.
npm start
Runs the built app in production mode.
We suggest that you begin by typing:
cd start-with-create-next-app
npm run dev
{
"name": "start-with-create-next-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "10.0.5",
"react": "17.0.1",
"react-dom": "17.0.1"
}
}
mkdir start-with-manual-app
cd start-with-manual-app
npm init -y
npm i next react react-dom
{
"name": "start-with-manual-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"next": "^10.0.5",
"react": "^17.0.1",
"react-dom": "^17.0.1"
}
}
Runs next dev which starts Next.js in development mode
Runs next build which builds the application for production usage
Runs next start which starts a Next.js production server
next export allows you to export your app to static HTML,
which can be run standalone without the need of a Node.js server.
export default function Index() {
return (
<div>
<h1>Index</h1>
</div>
);
}
import React from "react";
export default class Index extends React.Component {
render() {
return (
<div>
<h1>Index</h1>
</div>
);
}
}
pages/index.js → /
pages/blog/index.js → /blog
pages/blog/first-post.js → /blog/first-post
pages/dashboard/settings/username.js → /dashboard/settings/username
pages/blog/[slug].js → /blog/:slug (/blog/hello-world)
pages/[username]/settings.js → /:username/settings (/foo/settings)
pages/post/[...all].js → /post/* (/post/2020/id/title)
import { useRouter } from "next/router";
const Book = () => {
const router = useRouter();
const { id } = router.query;
return (
<div>
<h1>Book: {id}</h1>
</div>
);
};
export default Book;
import { useRouter } from "next/router";
const Book = () => {
const router = useRouter();
return (
<div>
<h1>Book: {JSON.stringify(router.query)}</h1>
</div>
);
};
export default Book;
import { useRouter } from "next/router";
const Book = () => {
const router = useRouter();
return (
<div>
<h1>Book: {JSON.stringify(router.query)}</h1>
</div>
);
};
export default Book;
import { useRouter } from "next/router";
const Book = () => {
const router = useRouter();
return (
<div>
<h1>Book: {JSON.stringify(router.query)}</h1>
</div>
);
};
export default Book;
// /book => 404
// /book/a => {"slug":["a"]}
// /book/a/b => {"slug":["a","b"]}
import { useRouter } from "next/router";
const Book = () => {
const router = useRouter();
return (
<div>
<h1>Book: {JSON.stringify(router.query)}</h1>
</div>
);
};
export default Book;
// /book => {}
// /book/a => {"slug":["a"]}
// /book/a/b => {"slug":["a","b"]}
const About = () => {
return (
<div>
<h1>About</h1>
<p>
<a href="/">index</a>
</p>
</div>
);
};
export default About;
import Link from "next/link";
const About = () => {
return (
<div>
<h1>About</h1>
<p>
<Link href="/">
<a>index</a>
</Link>
</p>
</div>
);
};
export default About;
import Link from "next/link";
const About = () => {
return (
<div>
<h1>About</h1>
<p>
<Link href={`/book/${encodeURIComponent("slug")}`}>
<a>index</a>
</Link>
</p>
</div>
);
};
export default About;
import Link from "next/link";
const About = () => {
return (
<div>
<h1>About</h1>
<p>
<Link
href={{
pathname: '/book/[slug]',
query: { slug: "slug" },
}}
>
<a>index</a>
</Link>
</p>
</div>
);
};
export default About;
import Link from "next/link";
const About = () => {
return (
<div>
<h1>About</h1>
<p>
<Link href="/" replace>
<a>index</a>
</Link>
</p>
</div>
);
};
export default About;
import Link from "next/link";
const About = () => {
return (
<div>
<h1>About</h1>
<p>
<Link href="/" scroll={false}>
<a>index</a>
</Link>
</p>
</div>
);
};
export default About;
// 링크의 기본 동작은 페이지 상단으로 스크롤하는 것입니다.
// 정의 된 해시가 있으면 일반 <a> 태그와 같이 특정 id 로 스크롤됩니다.
// 위로 스크롤을 방지하려면 / hash scroll = {false}를 Link에 추가 할 수 있습니다.
import Link from "next/link";
import { withRouter } from "next/router";
const About = ({ router }) => {
return (
<div>
<h1>About</h1>
<p>
<a href="/" onClick={click}>
index
</a>
</p>
</div>
);
function click(e) {
e.preventDefault();
router.push(e.target.href);
}
};
export default withRouter(About);
import Link from "next/link";
import { withRouter } from "next/router";
const About = () => {
const router = useRouter();
return (
<div>
<h1>About</h1>
<p>
<a href="/" onClick={click}>
index
</a>
</p>
</div>
);
function click(e) {
e.preventDefault();
router.push(e.target.href);
}
};
export default About;
import Image from "next/image";
const Login = () => (
<div>
<Image src="/bg_signin.png" width="400" height="534" />
</div>
);
export default Login;
import "@styles/index.css";
const MyApp = ({ Component, props }) => {
return <Component {...props} />;
};
export default MyApp;
import 'antd/dist/antd.css';
import "@styles/index.css";
const MyApp = ({ Component, props }) => {
return <Component {...props} />;
};
export default MyApp;
import styles from "@styles/index.module.css";
const Index = () => {
console.log(styles);
return (
<div>...</div>
);
};
export default Index;
npm install scss
const path = require('path')
module.exports = {
sassOptions: {
includePaths: [path.join(__dirname, 'styles')],
},
}
function HelloWorld() {
return (
<div>
Hello world
<p>scoped!</p>
<style jsx>{`
p {
color: blue;
}
div {
background: red;
}
@media (max-width: 600px) {
div {
background: blue;
}
}
`}</style>
<style global jsx>{`
body {
background: black;
}
`}</style>
</div>
)
}
export default HelloWorld
npm install tailwindcss@latest postcss@latest autoprefixer@latest
npx tailwindcss init -p
~/fds17th/app-without-cna is 📦 v1.0.0 via ⬢ v14.15.1 took 8s
➜ npx tailwindcss init -p
tailwindcss 2.0.2
✅ Created Tailwind config file: tailwind.config.js
✅ Created PostCSS config file: postcss.config.js
module.exports = {
purge: ["./pages/**/*.js", "./components/**/*.js"],
darkMode: "media", // or 'media' or 'class'
theme: {
extend: {
colors: {
"accent-1": "orange",
},
},
},
variants: {
extend: {},
},
plugins: [],
};
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
@tailwind base;
/* Write your own custom base styles here */
/* Start purging... */
@tailwind components;
/* Stop purging. */
html,
body {
@apply bg-gray-50 dark:bg-gray-900;
}
/* Write your own custom component styles here */
.btn-blue {
@apply px-4 py-2 font-bold text-white bg-blue-500 rounded;
}
/* Start purging... */
@tailwind utilities;
/* Stop purging. */
/* Your own custom utilities */
import "@styles/index.css";
const MyApp = ({ Component, props }) => {
return <Component {...props} />;
};
export default MyApp;
import { useRouter } from "next/router";
import Link from "next/link";
const Index = () => {
const router = useRouter();
function click(e) {
e.preventDefault();
router.push(e.target.href);
}
return (
<div>
<nav>
<ul className="flex items-center justify-between p-8">
<Link href="/">
<a className="text-blue-500 no-underline text-accent-1 dark:text-blue-300">
Home
</a>
</Link>
<ul className="flex items-center justify-between space-x-4">
<li>
<a
className="no-underline btn-blue"
href="/about"
onClick={click}
>
Blog
</a>
</li>
<li>
<a
className="no-underline btn-blue"
href="/about"
onClick={click}
>
About
</a>
</li>
</ul>
</ul>
</nav>
<div className="py-20">
<h1 className="text-5xl text-center text-gray-700 dark:text-gray-100">
Index
</h1>
</div>
</div>
);
};
export default Index;
module.exports = {
env: {
customKey: 'my-value',
},
}
function Page() {
return <h1>The value of customKey is: {process.env.customKey}</h1>
}
export default Page
// <h1>The value of customKey is: {'my-value'}</h1>
const dotenv = require('dotenv');
dotenv.config();
module.exports = {
env: {
customKey: process.env.customKey,
},
}
customKey=my-value
const About = () => {
return (
<div>
<h1>About</h1>
<p>
<a href="/">index</a>
</p>
</div>
);
};
export default About;
By Woongjae Lee
Fast Campus Frontend Developer School 17th
Daangn - Frontend Core Team ex) NHN Dooray - Frontend Team Leader ex) ProtoPie - Studio Team