Skip to content

Commit

Permalink
feat!: support basepath config for staticPath
Browse files Browse the repository at this point in the history
  • Loading branch information
LumaKernel committed Jan 10, 2021
1 parent 10bda5e commit d8dddc0
Show file tree
Hide file tree
Showing 27 changed files with 8,822 additions and 5,992 deletions.
11 changes: 7 additions & 4 deletions __tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,23 @@ describe('cli test', () => {
for (const dir of fs.readdirSync('projects')) {
resetCache()

const basePath = path.join(process.cwd(), 'projects', dir)
const workingDir = path.join(process.cwd(), 'projects', dir)
const { type, input, staticDir, output, trailingSlash } = await getConfig(
dir !== 'nuxtjs-no-slash',
basePath
workingDir
)

const result = fs.readFileSync(`${output}/$path.ts`, 'utf8')
const { filePath, text } = build({ type, input, staticDir, output, trailingSlash })
const basepath = /-basepath$/.test(dir) ? '/foo/bar' : undefined
const { filePath, text } = build({ type, input, staticDir, output, trailingSlash, basepath })

expect(filePath).toBe(`${output}/$path.ts`)
expect(
text.replace(
new RegExp(
`${/\\/.test(basePath) ? `${basePath.replace(/\\/g, '\\\\')}(/src)?` : basePath}/`,
`${
/\\/.test(workingDir) ? `${workingDir.replace(/\\/g, '\\\\')}(/src)?` : workingDir
}/`,
'g'
),
''
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"types": "dist/cli.d.ts",
"bin": "bin/index.js",
"scripts": {
"dev": "npm run build && cd projects/nextjs && node ../../bin/index.js -s && cd ../nextjs-src && node ../../bin/index.js -s && cd ../nuxtjs && node ../../bin/index.js --enableStatic && cd ../nuxtjs-src && node ../../bin/index.js --enableStatic && cd ../nuxtjs-no-slash && node ../../bin/index.js",
"dev": "npm run build && cd projects/nextjs && node ../../bin/index.js -s && cd ../nextjs-src && node ../../bin/index.js -s && cd ../nuxtjs && node ../../bin/index.js --enableStatic && cd ../nuxtjs-src && node ../../bin/index.js --enableStatic && cd ../nuxtjs-no-slash && node ../../bin/index.js && cd ../nextjs-basepath && node ../../bin/index.js -s && cd ../nuxtjs-basepath && node ../../bin/index.js -s",
"build": "npm run rimraf && tsc",
"rimraf": "node -e \"require('fs').rmdirSync('dist', { recursive: true })\"",
"release": "standard-version --skip.tag",
Expand Down Expand Up @@ -87,7 +87,8 @@
"dependencies": {
"@nuxt/config": "^2.14.12",
"chokidar": "^3.4.3",
"minimist": "^1.2.5"
"minimist": "^1.2.5",
"next": "^10.0.5"
},
"devDependencies": {
"@types/jest": "^26.0.19",
Expand Down
44 changes: 44 additions & 0 deletions projects/nextjs-basepath/lib/$path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* eslint-disable */
import { Query as Query0 } from '../pages'
import { OptionalQuery as OptionalQuery1 } from '../pages/[pid]'
import { Query as Query2 } from '../pages/blog/[...slug]'

export const pagesPath = {
_pid: (pid: string | number) => ({
$url: (url?: { query?: OptionalQuery1, hash?: string }) => ({ pathname: '/[pid]' as const, query: { pid, ...url?.query }, hash: url?.hash })
}),
aaa: {
_bbb: (bbb: string[]) => ({
ccc: {
$url: (url?: { hash?: string }) => ({ pathname: '/aaa/[...bbb]/ccc' as const, query: { bbb }, hash: url?.hash })
}
}),
api: {
samples: {
$url: (url?: { hash?: string }) => ({ pathname: '/aaa/api/samples' as const, hash: url?.hash })
}
}
},
blog: {
_slug: (slug: string[]) => ({
$url: (url: { query: Query2, hash?: string }) => ({ pathname: '/blog/[...slug]' as const, query: { slug, ...url.query }, hash: url.hash })
}),
hoge: {
_fuga: (fuga?: string[]) => ({
$url: (url?: { hash?: string }) => ({ pathname: '/blog/hoge/[[...fuga]]' as const, query: { fuga }, hash: url?.hash })
})
}
},
$url: (url: { query: Query0, hash?: string }) => ({ pathname: '/' as const, query: url.query, hash: url.hash })
}

export type PagesPath = typeof pagesPath

export const staticPath = {
aa_json: '/foo/bar/aa.json',
bb: {
cc_png: '/foo/bar/bb/cc.png'
}
} as const

export type StaticPath = typeof staticPath
3 changes: 3 additions & 0 deletions projects/nextjs-basepath/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
basePath: '/foo/bar'
}
23 changes: 23 additions & 0 deletions projects/nextjs-basepath/pages/[pid].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Link from 'next/link'

export type OptionalQuery = { hoge: string }

// `onClick`, `href`, and `ref` need to be passed to the DOM element
// for proper handling
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
return (
<a href={href} onClick={onClick} ref={ref}>
Click Me
</a>
)
})

function Home() {
return (
<Link href="/about" passHref>
<MyButton />
</Link>
)
}

export default Home
8 changes: 8 additions & 0 deletions projects/nextjs-basepath/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { AppProps } from 'next/app'
import '../styles/globals.css'

function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}

export default MyApp
Empty file.
Empty file.
Empty file.
23 changes: 23 additions & 0 deletions projects/nextjs-basepath/pages/blog/[...slug].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Link from 'next/link'

export type Query = { hoge: string }

// `onClick`, `href`, and `ref` need to be passed to the DOM element
// for proper handling
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
return (
<a href={href} onClick={onClick} ref={ref}>
Click Me
</a>
)
})

function Home() {
return (
<Link href="/about" passHref>
<MyButton />
</Link>
)
}

export default Home
Empty file.
94 changes: 94 additions & 0 deletions projects/nextjs-basepath/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import Head from 'next/head'
import { useCallback, useState, FormEvent, ChangeEvent } from 'react'
import useAspidaSWR from '@aspida/swr'
import styles from '~/styles/Home.module.css'
import { apiClient } from '~/utils/apiClient'
import { Task } from '<%= orm === "prisma" ? "$prisma/client" : "$/types" %>'
import UserBanner from '~/components/UserBanner'

export type Query = { hoge: string }

const Home = () => {
const { data: tasks, error, revalidate } = useAspidaSWR(apiClient.tasks)
const [label, setLabel] = useState('')
const inputLabel = useCallback((e: ChangeEvent<HTMLInputElement>) => setLabel(e.target.value), [])

const createTask = useCallback(
async (e: FormEvent) => {
e.preventDefault()
if (!label) return

await apiClient.tasks.post({ body: { label } })
setLabel('')
revalidate()
},
[label]
)

const toggleDone = useCallback(async (task: Task) => {
await apiClient.tasks._taskId(task.id).patch({ body: { done: !task.done } })
revalidate()
}, [])

const deleteTask = useCallback(async (task: Task) => {
await apiClient.tasks._taskId(task.id).delete()
revalidate()
}, [])

if (error) return <div>failed to load</div>
if (!tasks) return <div>loading...</div>

return (
<div className={styles.container}>
<Head>
<title>frourio-todo-app</title>
<link rel="icon" href="/favicon.png" />
</Head>

<main className={styles.main}>
<UserBanner />

<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>

<p className={styles.description}>frourio-todo-app</p>

<div>
<form style={{ textAlign: 'center' }} onSubmit={createTask}>
<input value={label} type="text" onChange={inputLabel} />
<input type="submit" value="ADD" />
</form>
<ul className={styles.tasks}>
{tasks.map(task => (
<li key={task.id}>
<label>
<input type="checkbox" checked={task.done} onChange={() => toggleDone(task)} />
<span>{task.label}</span>
</label>
<input
type="button"
value="DELETE"
style={{ float: 'right' }}
onClick={() => deleteTask(task)}
/>
</li>
))}
</ul>
</div>
</main>

<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by <img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
</a>
</footer>
</div>
)
}

export default Home
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions projects/nuxtjs-basepath/nuxt.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
router: {
trailingSlash: true,
base: '/foo/bar'
}
}
23 changes: 23 additions & 0 deletions projects/nuxtjs-basepath/pages/_pid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Link from 'next/link'

export type OptionalQuery = { hoge: string }

// `onClick`, `href`, and `ref` need to be passed to the DOM element
// for proper handling
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
return (
<a href={href} onClick={onClick} ref={ref}>
Click Me
</a>
)
})

function Home() {
return (
<Link href="/about" passHref>
<MyButton />
</Link>
)
}

export default Home
Empty file.
Empty file.
23 changes: 23 additions & 0 deletions projects/nuxtjs-basepath/pages/blog/_slug.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Link from 'next/link'

export type Query = { hoge: string }

// `onClick`, `href`, and `ref` need to be passed to the DOM element
// for proper handling
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
return (
<a href={href} onClick={onClick} ref={ref}>
Click Me
</a>
)
})

function Home() {
return (
<Link href="/about" passHref>
<MyButton />
</Link>
)
}

export default Home
94 changes: 94 additions & 0 deletions projects/nuxtjs-basepath/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import Head from 'next/head'
import { useCallback, useState, FormEvent, ChangeEvent } from 'react'
import useAspidaSWR from '@aspida/swr'
import styles from '~/styles/Home.module.css'
import { apiClient } from '~/utils/apiClient'
import { Task } from '<%= orm === "prisma" ? "$prisma/client" : "$/types" %>'
import UserBanner from '~/components/UserBanner'

export type Query = { hoge: string }

const Home = () => {
const { data: tasks, error, revalidate } = useAspidaSWR(apiClient.tasks)
const [label, setLabel] = useState('')
const inputLabel = useCallback((e: ChangeEvent<HTMLInputElement>) => setLabel(e.target.value), [])

const createTask = useCallback(
async (e: FormEvent) => {
e.preventDefault()
if (!label) return

await apiClient.tasks.post({ body: { label } })
setLabel('')
revalidate()
},
[label]
)

const toggleDone = useCallback(async (task: Task) => {
await apiClient.tasks._taskId(task.id).patch({ body: { done: !task.done } })
revalidate()
}, [])

const deleteTask = useCallback(async (task: Task) => {
await apiClient.tasks._taskId(task.id).delete()
revalidate()
}, [])

if (error) return <div>failed to load</div>
if (!tasks) return <div>loading...</div>

return (
<div className={styles.container}>
<Head>
<title>frourio-todo-app</title>
<link rel="icon" href="/favicon.png" />
</Head>

<main className={styles.main}>
<UserBanner />

<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>

<p className={styles.description}>frourio-todo-app</p>

<div>
<form style={{ textAlign: 'center' }} onSubmit={createTask}>
<input value={label} type="text" onChange={inputLabel} />
<input type="submit" value="ADD" />
</form>
<ul className={styles.tasks}>
{tasks.map(task => (
<li key={task.id}>
<label>
<input type="checkbox" checked={task.done} onChange={() => toggleDone(task)} />
<span>{task.label}</span>
</label>
<input
type="button"
value="DELETE"
style={{ float: 'right' }}
onClick={() => deleteTask(task)}
/>
</li>
))}
</ul>
</div>
</main>

<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by <img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
</a>
</footer>
</div>
)
}

export default Home
Loading

0 comments on commit d8dddc0

Please sign in to comment.