Skip to content

Commit

Permalink
feat: improve package development experience (nextauthjs#1064)
Browse files Browse the repository at this point in the history
* chore(deps): add next and react to dev dependencies

* chore: move build configs to avoid crash with next dev

* chore: add next js dev app

* chore: remove .txt extension from LICENSE file

* chore: update CONTRIBUTING.md

* chore: watch css under development

* style(lint): run linter on index.css

* chore: fix some imports for dev server

* refactor: simplify client code

* chore: mention VSCode extension for linting

* docs: reword CONTRIBUTING.md

* chore: ignore linting pages and components
  • Loading branch information
balazsorban44 committed Feb 1, 2021
1 parent f6d6c43 commit 77de2ab
Show file tree
Hide file tree
Showing 32 changed files with 4,470 additions and 240 deletions.
69 changes: 23 additions & 46 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,70 +17,47 @@ Anyone can be a contributor. Either you found a typo, or you have an awesome fea
* Pull Requests should be raised for any change
* Pull Requests need approval of a [core contributor](https://next-auth.js.org/contributors#core-team) before merging
* Rebasing in Pull Requests is preferred to keep a clean commit history (see below)
* Running `npm run lint:fix` before committing can make resolving conflicts easier
* Run `npm run lint:fix` before committing to make resolving conflicts easier (VSCode users, check out [this extension](https://marketplace.visualstudio.com/items?itemName=chenxsan.vscode-standardjs) to fix lint issues in development)
* We encourage you to test your changes, and if you have the opportunity, please make those tests part of the Pull Request
* If you add new functionality, please provide the corresponding documentation as well and make it part of the Pull Request

### Setting up local environment

A quick and dirty guide on how to setup *next-auth* locally to work on it and test out any changes:
A quick guide on how to setup *next-auth* locally to work on it and test out any changes:

1. Clone the repo:
```sh
git clone [email protected]:nextauthjs/next-auth.git
cd next-auth
```

git clone [email protected]:nextauthjs/next-auth.git
cd next-auth/

2. Install packages and run the build command:

npm i
npm run build

3. Link your project back to your local copy of next auth:

cd ../your-application
npm link ../next-auth
2. Install packages:
```sh
npm i
```

4. Finally link React between the repo and the version installed in your project:
3. Populate `.env.local`:

Copy `.env.example` to `.env.local`, and add your env variables for each provider you want to test.

cd ../next-auth
npm link ../your-application/node_modules/react
>NOTE: You can configure providers of the dev app in `pages/api/auth/[...nextauth].js`
*This is an annoying step and not obvious, but is needed because of how React has been written (otherwise React crashes when you try to use the `useSession()` hook in your project).*
4. Start the dev application/server and CSS watching:
```sh
npm run dev
```

That's it!
Your dev application will be available on ```http://localhost:3000```

Notes: You may need to repeat both `npm link` steps if you install / update additional dependencies with `npm i`.
That's it! 🎉

If you need an example project to link to, you can use [next-auth-example](https://github.com/iaincollins/next-auth-example).

#### Hot reloading

You might find it helpful to use the `npm run watch` command in the next-auth project, which will automatically (and silently) rebuild JS and CSS files as you edit them.

cd next-auth/
npm run watch

If you are working on `next-auth/src/client/index.js` hot reloading will work as normal in your Next.js app.
When running `npm run dev`, you start a Next.js dev server on `http://localhost:3000`, which includes hot reloading out of the box. Make changes on any of the files in `src` and see the changes immediately.

However, if you are working on anything else (e.g. `next-auth/src/server/*` etc) then you will need to *stop and start* your app for changes to apply as **Next.js will not hot reload those changes by default**. To facilitate this, you can try [this webpack plugin](https://www.npmjs.com/package/webpack-clear-require-cache-plugin). Note that the `next.config.js` syntax in the plugin README may be out of date. It should look like this:

```
const clearRequireCachePlugin = require('webpack-clear-require-cache-plugin')
module.exports = {
webpack: (config, {
buildId, dev, isServer, defaultLoaders, webpack,
}) => {
config.plugins.push(clearRequireCachePlugin([
/\.next\/server\/static\/development\/pages/,
/\.next\/server\/ssr-module-cache.js/,
/next-auth/,
]))
return config
},
}
```
>NOTE: When working on CSS, you will need to manually refresh the page after changes. (Improving this through a PR is very welcome!)
#### Databases

Expand All @@ -90,7 +67,7 @@ It will use port `3306`, `5432`, and `27017` on localhost respectively; please m

You can start them with `npm run db:start` and stop them with `npm run db:stop`.

You will need Docker installed to be able to start / stop the databases.
You will need Docker and Docker Compose installed to be able to start / stop the databases.

When stopping the databases, it will reset their contents.

Expand Down
File renamed without changes.
12 changes: 0 additions & 12 deletions babel.config.json

This file was deleted.

16 changes: 16 additions & 0 deletions components/access-denied.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { signIn } from 'next-auth/client'

export default function AccessDenied () {
return (
<>
<h1>Access Denied</h1>
<p>
<a href="/api/auth/signin"
onClick={(e) => {
e.preventDefault()
signIn()
}}>You must be signed in to view this page</a>
</p>
</>
)
}
18 changes: 18 additions & 0 deletions components/footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Link from 'next/link'
import styles from './footer.module.css'
import { version } from 'package.json'

export default function Footer () {
return (
<footer className={styles.footer}>
<hr />
<ul className={styles.navItems}>
<li className={styles.navItem}><a href='https://next-auth.js.org'>Documentation</a></li>
<li className={styles.navItem}><a href='https://www.npmjs.com/package/next-auth'>NPM</a></li>
<li className={styles.navItem}><a href='https://github.com/nextauthjs/next-auth-example'>GitHub</a></li>
<li className={styles.navItem}><Link href='/policy'><a>Policy</a></Link></li>
<li className={styles.navItem}><em>{version}</em></li>
</ul>
</footer>
)
}
14 changes: 14 additions & 0 deletions components/footer.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.footer {
margin-top: 2rem;
}

.navItems {
margin-bottom: 1rem;
padding: 0;
list-style: none;
}

.navItem {
display: inline-block;
margin-right: 1rem;
}
103 changes: 103 additions & 0 deletions components/header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import Link from 'next/link'
import { signIn, signOut, useSession } from 'next-auth/client'
import * as client from 'next-auth/client'
import styles from './header.module.css'

// The approach used in this component shows how to built a sign in and sign out
// component that works on pages which support both client and server side
// rendering, and avoids any flash incorrect content on initial page load.
export default function Header () {
const [session, loading] = useSession()

return (
<header>
<noscript>
<style>{'.nojs-show { opacity: 1; top: 0; }'}</style>
</noscript>
<div className={styles.signedInStatus}>
<p
className={`nojs-show ${
!session && loading ? styles.loading : styles.loaded
}`}
>
{!session && (
<>
<span className={styles.notSignedInText}>
You are not signed in
</span>
<a
href="/api/auth/signin"
className={styles.buttonPrimary}
onClick={(e) => {
e.preventDefault()
signIn('github')
}}
>
Sign in
</a>
</>
)}
{session && (
<>
{session.user.image && (
<span
style={{ backgroundImage: `url(${session.user.image})` }}
className={styles.avatar}
/>
)}
<span className={styles.signedInText}>
<small>Signed in as</small>
<br />
<strong>{session.user.email || session.user.name}</strong>
</span>
<a
href="/api/auth/signout"
className={styles.button}
onClick={(e) => {
e.preventDefault()
signOut()
}}
>
Sign out
</a>
</>
)}
</p>
</div>
<nav>
<ul className={styles.navItems}>
<li className={styles.navItem}>
<Link href='/'>
<a>Home</a>
</Link>
</li>
<li className={styles.navItem}>
<Link href='/client'>
<a>Client</a>
</Link>
</li>
<li className={styles.navItem}>
<Link href='/server'>
<a>Server</a>
</Link>
</li>
<li className={styles.navItem}>
<Link href='/protected'>
<a>Protected</a>
</Link>
</li>
<li className={styles.navItem}>
<Link href='/protected-ssr'>
<a>Protected(SSR)</a>
</Link>
</li>
<li className={styles.navItem}>
<Link href='/api-example'>
<a>API</a>
</Link>
</li>
</ul>
</nav>
</header>
)
}
92 changes: 92 additions & 0 deletions components/header.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* Set min-height to avoid page reflow while session loading */
.signedInStatus {
display: block;
min-height: 4rem;
width: 100%;
}

.loading,
.loaded {
position: relative;
top: 0;
opacity: 1;
overflow: hidden;
border-radius: 0 0 .6rem .6rem;
padding: .6rem 1rem;
margin: 0;
background-color: rgba(0,0,0,.05);
transition: all 0.2s ease-in;
}

.loading {
top: -2rem;
opacity: 0;
}

.signedInText,
.notSignedInText {
position: absolute;
padding-top: .8rem;
left: 1rem;
right: 6.5rem;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
display: inherit;
z-index: 1;
line-height: 1.3rem;
}

.signedInText {
padding-top: 0rem;
left: 4.6rem;
}

.avatar {
border-radius: 2rem;
float: left;
height: 2.8rem;
width: 2.8rem;
background-color: white;
background-size: cover;
background-repeat: no-repeat;
}

.button,
.buttonPrimary {
float: right;
margin-right: -.4rem;
font-weight: 500;
border-radius: .3rem;
cursor: pointer;
font-size: 1rem;
line-height: 1.4rem;
padding: .7rem .8rem;
position: relative;
z-index: 10;
background-color: transparent;
color: #555;
}

.buttonPrimary {
background-color: #346df1;
border-color: #346df1;
color: #fff;
text-decoration: none;
padding: .7rem 1.4rem;
}

.buttonPrimary:hover {
box-shadow: inset 0 0 5rem rgba(0,0,0,0.2)
}

.navItems {
margin-bottom: 2rem;
padding: 0;
list-style: none;
}

.navItem {
display: inline-block;
margin-right: 1rem;
}
14 changes: 14 additions & 0 deletions components/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import Header from 'components/header'
import Footer from 'components/footer'

export default function Layout ({ children }) {
return (
<>
<Header />
<main>
{children}
</main>
<Footer />
</>
)
}
12 changes: 12 additions & 0 deletions config/babel.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"presets": [
["@babel/preset-env", { "targets": { "esmodules": true } }]
],
"comments": false,
"overrides": [
{
"test": ["../src/server/pages/**"],
"presets": ["preact"]
}
]
}
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 77de2ab

Please sign in to comment.