Skip to content

Commit

Permalink
feat!: add support for nuxt 3/nuxt bridge (#52)
Browse files Browse the repository at this point in the history
* refactor: add support for nuxt 3/nuxt bridge

* test: disabled for now

* docs: typo

* refactor: update module

* test: enable

* chore: remove .ts

* chore: update script

* ci: update

* refactor: use config file to write rules

* feat: add `rules` option

* refactor: use `nitro.prerender`

* refactor: remove robots hooks

* test: update

* chore: update test command

* test: update
  • Loading branch information
ricardogobbosouza authored Jul 29, 2022
1 parent ce0c78c commit d950072
Show file tree
Hide file tree
Showing 53 changed files with 3,988 additions and 9,471 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ jobs:

strategy:
matrix:
# os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest]
node: [12]
os: [ubuntu-latest, macos-latest, windows-latest]
node: [14, 16, 18]

steps:
- uses: actions/setup-node@v3
Expand All @@ -33,9 +32,11 @@ jobs:
key: ${{ matrix.os }}-node-v${{ matrix.node }}-deps-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}

- name: Install dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: yarn

- name: Prepare TypeScript environment
run: yarn dev:prepare

- name: Lint
run: yarn lint

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ coverage
dist
sw.*
.env
.output
61 changes: 23 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@

> A Nuxt.js module that injects a middleware to generate a robots.txt file
[📖 **Release Notes**](./CHANGELOG.md)
- [📖 **Release Notes**](./CHANGELOG.md)

## Features

- Nuxt 3 and Nuxt Bridge support
- Generate `robots.txt` for static mode
- Add middleware for `robots.txt`

## Setup

Expand Down Expand Up @@ -47,45 +53,33 @@ export default {

## Options

The module option parameter can be:
### configPath

### `Object`

```js
export default {
robots: {
UserAgent: '*',
Disallow: '/'
}
}
```
- Type: `String`
- Default: `robots.config`

### `Array`
### rules

- Type: `Object|Array`
- Default:
```js
export default {
robots: [
{
UserAgent: 'Googlebot',
Disallow: () => '/users' // accepts function
}
]
{
UserAgent: '*',
Disallow: ''
}
```

### `Function`
## Robots config

If you need to use function in any rule, you need to create a config file through the `configPath` option

```js
export default {
robots: () => {
return {
UserAgent: '*',
Disallow: '/',
UserAgent: '*',
Disallow: '/',

// Be aware that this will NOT work on target: 'static' mode
Sitemap: (req) => `https://${req.headers.host}/sitemap.xml`
}
}
// Be aware that this will NOT work on target: 'static' mode
Sitemap: (req) => `https://${req.headers.host}/sitemap.xml`
}
```

Expand All @@ -110,15 +104,6 @@ Disallow: /admin

**Note:** Don't worry, keys are parsed with case insensitivity and special characters.

## Hooks

Hooks are listeners to Nuxt events. [Learn more](https://nuxtjs.org/docs/configuration-glossary/configuration-hooks/)

| Hook | Arguments | When |
| ---------------------- | --------------------- | ---------------------------------- |
| robots:generate:before | (nuxt, robotsOptions) | Hook on before site generation |
| robots:generate:done | (nuxt, robotsContent) | Hook on robots generation finished |

## License

[MIT License](./LICENSE)
Expand Down
4 changes: 0 additions & 4 deletions jest.config.js

This file was deleted.

44 changes: 26 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,40 @@
"Robert Reinhard",
"William DA SILVA <[email protected]>"
],
"main": "./dist/module.js",
"types": "./dist/module.d.ts",
"type": "module",
"sideEffects": false,
"exports": {
".": {
"require": "./dist/module.cjs",
"import": "./dist/module.mjs"
}
},
"main": "./dist/module.cjs",
"types": "./dist/types.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "siroc build",
"prepublishOnly": "yarn build",
"dev": "nuxt dev test/fixture/basic",
"lint": "eslint --ext .js,.ts,.vue .",
"release": "yarn test && yarn build && standard-version && git push --follow-tags && npm publish",
"test": "yarn lint && yarn jest"
"build": "nuxt-module-build",
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground",
"dev": "nuxt dev playground",
"lint": "eslint --ext .js,.ts,.vue",
"prepack": "yarn build",
"release": "yarn test && standard-version && git push --follow-tags && npm publish",
"test": "yarn lint && nuxi test --coverage"
},
"dependencies": {
"@nuxt/kit": "^3.0.0-rc.6"
},
"devDependencies": {
"@babel/preset-typescript": "latest",
"@nuxt/test-utils": "latest",
"@nuxt/types": "latest",
"@nuxt/module-builder": "latest",
"@nuxt/test-utils": "^3.0.0-rc.6",
"@nuxtjs/eslint-config-typescript": "latest",
"@types/jest": "latest",
"@types/node": "latest",
"del": "latest",
"c8": "latest",
"eslint": "latest",
"jest": "latest",
"nuxt": "latest",
"siroc": "latest",
"standard-version": "latest"
"nuxt": "^3.0.0-rc.6",
"standard-version": "latest",
"vitest": "latest"
},
"publishConfig": {
"access": "public"
Expand Down
3 changes: 3 additions & 0 deletions playground/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<NuxtWelcome />
</template>
9 changes: 9 additions & 0 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

import { defineNuxtConfig } from 'nuxt'
import RobotsModule from '..'

export default defineNuxtConfig({
modules: [
RobotsModule
]
})
3 changes: 3 additions & 0 deletions playground/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "@nuxtjs/robots-playground"
}
27 changes: 0 additions & 27 deletions src/build.ts

This file was deleted.

20 changes: 0 additions & 20 deletions src/generate.ts

This file was deleted.

19 changes: 0 additions & 19 deletions src/middleware.ts

This file was deleted.

106 changes: 55 additions & 51 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,60 @@
import type { Module } from '@nuxt/types'
import { existsSync } from 'node:fs'
import { defineNuxtModule, addServerHandler, createResolver, useLogger, isNuxt2, findPath, addTemplate } from '@nuxt/kit'
import { name, version } from '../package.json'
import { build } from './build'
import { generate } from './generate'
import { middleware } from './middleware'
import { Rule } from './types'

const CONFIG_KEY = 'robots'

export type { Rule }

export type ModuleOptions = Rule | Rule[] | (() => Rule | Rule[])

async function getOptions (moduleOptions: ModuleOptions): Promise<Rule[]> {
if (typeof moduleOptions === 'function') {
moduleOptions = await moduleOptions.call(this)
}

if (Array.isArray(moduleOptions)) {
return moduleOptions
}

let { robots } = this.options

if (typeof robots === 'function') {
robots = await robots.call(this)
}

if (Array.isArray(robots)) {
return robots
}

return [{
UserAgent: '*',
Disallow: '',
...robots,
...moduleOptions
}]
}

const nuxtModule: Module<ModuleOptions> = async function (moduleOptions) {
const options: Rule[] = await getOptions.call(this, moduleOptions)

build.bind(this)()
generate.bind(this)(options)
middleware.bind(this)(options)
export type ModuleOptions = {
configPath: string,
rules: Rule | Rule[]
}

;(nuxtModule as any).meta = { name, version }

declare module '@nuxt/types' {
interface NuxtConfig { [CONFIG_KEY]?: ModuleOptions } // Nuxt 2.14+
interface Configuration { [CONFIG_KEY]?: ModuleOptions } // Nuxt 2.9 - 2.13
}

export default nuxtModule
const ROBOTS_FILENAME = 'robots.txt'
const logger = useLogger('nuxt:robots')

export default defineNuxtModule<ModuleOptions>({
meta: {
name,
version,
configKey: 'robots'
},
defaults: {
configPath: 'robots.config',
rules: {
UserAgent: '*',
Disallow: ''
}
},
async setup (options, nuxt) {
const { resolve } = createResolver(import.meta.url)

const staticFilePath = resolve(
nuxt.options.srcDir,
isNuxt2() ? nuxt.options.dir.static : nuxt.options.dir.public,
ROBOTS_FILENAME
)

if (existsSync(staticFilePath)) {
logger.warn('To use `' + name + '` module, please remove public `robots.txt`')
return
}

nuxt.options.alias['#robots-config'] = await findPath(options.configPath) ?? resolve('./robots.config')
nuxt.options.alias['#robots-rules'] = addTemplate({
filename: 'robots-rules.mjs',
write: true,
getContents: () => `export const rules = ${JSON.stringify(options.rules, null, 2)}`
}).dst

nuxt.hook('nitro:build:before', (nitro) => {
nitro.options.prerender.routes.push(`/${ROBOTS_FILENAME}`)
})

const runtimeDir = resolve('./runtime')
nuxt.options.build.transpile.push(runtimeDir)

addServerHandler({
route: `/${ROBOTS_FILENAME}`,
handler: resolve(runtimeDir, 'server/middleware')
})
}
})
3 changes: 3 additions & 0 deletions src/robots.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { rules } from '#robots-rules'

export default rules
8 changes: 8 additions & 0 deletions src/runtime/server/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineHandler } from 'h3'
import { getRules, render } from '../../utils'
import config from '#robots-config'

export default defineHandler(async ({ req, res }) => {
res.setHeader('Content-Type', 'text/plain')
res.end(render(await getRules(config, req)))
})
Loading

0 comments on commit d950072

Please sign in to comment.