Skip to content

feat: improve package development experience #1064

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jan 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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