Skip to content

Commit

Permalink
migrate to nuxt3 (#96)
Browse files Browse the repository at this point in the history
Co-authored-by: Sébastien Chopin <seb@nuxtjs.com>
  • Loading branch information
antfu and atinux authored Aug 3, 2022
1 parent 8b4413e commit 7a37f90
Show file tree
Hide file tree
Showing 54 changed files with 7,040 additions and 10,946 deletions.
7 changes: 7 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "@nuxtjs/eslint-config-typescript",
"rules": {
"vue/no-v-html": "off",
"vue/no-multiple-template-root": "off"
}
}
5 changes: 0 additions & 5 deletions .eslintrc.js

This file was deleted.

7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ package-lock.json
*.iml
.nuxt
.vscode
.output

static/manifest*.json
static/sw.js
static/workbox-sw*.js*
public/manifest*.json
public/sw.js
public/workbox-sw*.js*
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shamefully-hoist=true
3 changes: 0 additions & 3 deletions .vercelignore

This file was deleted.

32 changes: 14 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,42 @@
# Nuxt.js Hacker News
# Nuxt3 Hacker News

HackerNews clone built with [Nuxt.js](https://nuxtjs.org).
Hacker News clone built with [Nuxt3](https://v3.nuxtjs.org).

<p align="center">
<a href="https://hn.nuxtjs.org" target="_blank">
<img width="1090" alt="Screenshot 2019-06-04 at 13 27 51" src="https://user-images.githubusercontent.com/904724/58875721-97382400-86cc-11e9-94c6-af21544817bb.png">
<img width="1090" src="https://user-images.githubusercontent.com/904724/58875721-97382400-86cc-11e9-94c6-af21544817bb.png">
<br>
Live Demo
</a>
</p>

## Modes
## Deploy

- Universal: https://hn.nuxtjs.org

> Hosted on [Now 2](https://zeit.co): `npm run build` + `now.json`
> Hosted on [Vercel](https://vercel.com/): `npm run build`
- Single Page: https://hn-spa.nuxtjs.org

> Hosted on [Netlify](https://www.netlify.com): `npm run build-spa` + `dist/` directory
> Hosted on [Netlify](https://www.netlify.com): `npm run build-spa`
## Performance

- Lighthouse [100/100](https://cdn.rawgit.com/Atinux/e2f424e6794babc00d2158406b0ab37d/raw/4de834145881697ea83292b381df5f591f1ed2f5/lighthouse-result-nuxt.html) - [Webpagetest](https://www.webpagetest.org/lighthouse.php?test=170620_PG_a2a9feaf4ace07a61b2c6c2a171b1c79&run=1)
- Interactive (Faster 3G) [3.5s](https://www.webpagetest.org/result/170620_PG_a2a9feaf4ace07a61b2c6c2a171b1c79)
- Interactive (Emerging Markets) [3.8s](https://www.webpagetest.org/result/170620_B1_0b83d61272c77c16c3f3f1f16fb72d2e)
- Lighthouse [100/100](https://pagespeed.web.dev/report?url=https%3A%2F%2Fhackernews-git-nuxt3-nuxt-js.vercel.app%2Fnews%2F1) (Slow 4G / Mobile Moto G4)
- Interactive: 1.4s
- Total Blocking Time: 30ms

## Features

- Server Side Rendering
- Vite-based hot module replacement (HMR) dev environment
- Deploys anywhere with zero config (Vercel, Netlify, Cloudflare, etc.) powered by [Nitro](https://github.com/unjs/nitro)
- Code Splitting
- Single-file Vue Components
- Prefetch/Preload JS + DNS + Data
- Critical Path CSS
- PWA experience using [PWA Module](https://pwa.nuxtjs.org) with almost _zero config_
- PRPL
- Hot reloading dev environment integrated with [ESLint](https://eslint.org/) and [Prettier](https://prettier.io/)
- Hosted on [Vercel](https://vercel.com)

## Build Setup

**Requires Node.js 8+**
**Requires Node.js 14+**

``` bash
# install dependencies
Expand All @@ -59,7 +55,7 @@ npm start
npm run build-spa

# serve in production mode (spa)
npm run start-spa # or upload dist/ directory
npm run start-spa # or upload .output/public/ directory

# validate code with ESLint (with Prettier)
npm run lint
Expand All @@ -70,7 +66,7 @@ npm run lintfix

## Links

For the communiy typescript fork please see [nuxt-community/hackernews-nuxt-ts](https://github.com/nuxt-community/hackernews-nuxt-ts)
For the Nuxt 2 version, check out the [`nuxt2` branch](https://github.com/nuxt/hackernews/tree/nuxt2)

## License

Expand Down
22 changes: 22 additions & 0 deletions app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script setup lang="ts">
useHead({
titleTemplate: 'Nuxt HN | %s',
meta: [
{ property: 'og:image', content: 'https://user-images.githubusercontent.com/11247099/169022756-cdb6ef6f-1299-4ce0-8f80-81fb6e86a2e1.png' },
{ name: 'description', content: 'Hacker News clone built with Nuxt 3' },
{ name: 'twitter:card', content: 'summary_large_image' },
{ name: 'twitter:site', content: '@nuxt_js' },
{ name: 'twitter:creator', content: '@nuxt_js' },
{ name: 'twitter:image', content: 'https://user-images.githubusercontent.com/11247099/169022756-cdb6ef6f-1299-4ce0-8f80-81fb6e86a2e1.png' }
],
link: [
{ rel: 'icon', type: 'image/png', href: '/icon.png' }
]
})
</script>

<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
8 changes: 0 additions & 8 deletions assets/logo.svg

This file was deleted.

19 changes: 0 additions & 19 deletions common/utils.js

This file was deleted.

45 changes: 21 additions & 24 deletions components/Comment.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
<script setup lang="ts">
import { timeAgo } from '~/composables/utils'
defineProps({
comment: {
type: Object,
required: true
}
})
const open = ref(true)
function pluralize (n: number) {
return n + (n === 1 ? ' reply' : ' replies')
}
</script>

<template>
<li v-if="comment && comment.user" class="comment">
<div class="by">
<router-link :to="'/user/' + comment.user">
<NuxtLink :to="'/user/' + comment.user">
{{ comment.user }}
</router-link>
{{ comment.time | timeAgo }} ago
</NuxtLink>
{{ timeAgo(comment.time) }} ago
</div>
<div class="text" v-html="comment.content" />
<div v-if="comment.comments && comment.comments.length" :class="{ open }" class="toggle">
Expand All @@ -17,27 +34,7 @@
</li>
</template>

<script>
export default {
name: 'Comment',
props: {
comment: {
type: Object,
required: true
}
},
data () {
return {
open: true
}
},
methods: {
pluralize: n => n + (n === 1 ? ' reply' : ' replies')
}
}
</script>

<style lang="stylus">
<style lang="postcss">
.comment-children {
.comment-children {
margin-left: 1.5em;
Expand Down
43 changes: 19 additions & 24 deletions components/Item.vue
Original file line number Diff line number Diff line change
@@ -1,50 +1,41 @@
<script setup lang="ts">
import { timeAgo, isAbsolute, host } from '~/composables/utils'
defineProps<{
item: any
}>()
</script>

<template>
<li class="news-item">
<span class="score">{{ item.points }}</span>
<span class="title">
<template v-if="isAbsolute(item.url)">
<a :href="item.url" target="_blank" rel="noopener">{{ item.title }}</a>
<span class="host"> ({{ item.url | host }})</span>
<span class="host"> ({{ host(item.url) }})</span>
</template>
<template v-else>
<router-link :to="'/item/' + item.id">{{ item.title }}</router-link>
<NuxtLink :to="'/item/' + item.id">{{ item.title }}</NuxtLink>
</template>
</span>
<br>
<span class="meta">
<span v-if="item.type !== 'job'" class="by">
by
<router-link :to="'/user/' + item.user">{{ item.user }}</router-link>
<NuxtLink :to="'/user/' + item.user">{{ item.user }}</NuxtLink>
</span>
<span class="time">
{{ item.time | timeAgo }} ago
{{ timeAgo(item.time) }} ago
</span>
|
<span v-if="item.type !== 'job'" class="comments-link">
|
<router-link :to="'/item/' + item.id">{{ item.comments_count }} comments</router-link>
<NuxtLink :to="'/item/' + item.id">{{ item.comments_count }} comments</NuxtLink>
</span>
</span>
</li>
</template>

<script>
export default {
name: 'NewsItem',
props: {
item: {
type: Object,
required: true
}
},
methods: {
isAbsolute (url) {
return /^https?:\/\//.test(url)
}
}
}
</script>

<style lang="stylus">
<style lang="postcss">
.news-item {
background-color: #fff;
padding: 20px 30px 20px 80px;
Expand All @@ -68,6 +59,10 @@ export default {
font-size: 0.85em;
color: #595959;
span {
margin: 0 0.2rem;
}
a {
color: #595959;
text-decoration: underline;
Expand Down
59 changes: 26 additions & 33 deletions components/ItemListNav.vue
Original file line number Diff line number Diff line change
@@ -1,42 +1,28 @@
<script setup lang="ts">
const props = defineProps<{
feed: string,
page: number,
maxPage: number
}>()
const hasMore = $computed(() => props.page < props.maxPage)
</script>

<template>
<div class="news-list-nav">
<router-link v-if="page > 1" :to="`/${feed}/${page - 1}`">
<NuxtLink v-if="page > 1" :to="`/${feed}/${page - 1}`">
&lt; prev
</router-link>
<a v-else class="disabled">&lt; prev</a>
<span>{{ page }}/{{ maxPage }}</span>
<router-link v-if="hasMore" :to="`/${feed}/${page + 1}`">
</NuxtLink>
<span v-else class="disabled">&lt; prev</span>
<span class="page">{{ page }}/{{ maxPage }}</span>
<NuxtLink v-if="hasMore" :to="`/${feed}/${page + 1}`">
more &gt;
</router-link>
<a v-else class="disabled">more &gt;</a>
</NuxtLink>
<span v-else class="disabled">more &gt;</span>
</div>
</template>

<script>
export default {
props: {
feed: {
type: String,
required: true
},
page: {
type: Number,
required: true
},
maxPage: {
type: Number,
required: true
}
},
computed: {
hasMore () {
return this.page < this.maxPage
}
}
}
</script>

<style lang="stylus">
<style lang="postcss">
.news-list-nav, .news-list {
background-color: #fff;
border-radius: 2px;
Expand All @@ -46,13 +32,20 @@ export default {
padding: 15px 30px;
text-align: center;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
user-select: none;
a {
margin: 0 1em;
}
.disabled {
opacity: 0.8;
opacity: 0.5;
}
.page {
width: 100px;
display: inline-block;
text-align: center;
}
}
</style>
Loading

1 comment on commit 7a37f90

@vercel
Copy link

@vercel vercel bot commented on 7a37f90 Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.