23 |
24 |
25 |
60 |
61 |
105 |
--------------------------------------------------------------------------------
/test/module.test.js:
--------------------------------------------------------------------------------
1 | import { Nuxt, Builder, Generator } from 'nuxt-edge'
2 | import { waitFor } from '@nuxt/utils-edge'
3 | import consola from 'consola'
4 | import getPort from 'get-port'
5 | import { createBrowser } from 'tib'
6 |
7 | jest.setTimeout(30000)
8 | consola.mockTypes(() => jest.fn())
9 |
10 | describe('basic', () => {
11 | let browser
12 |
13 | afterAll(async () => {
14 | await browser.close()
15 | })
16 |
17 | test('build fixture', async () => {
18 | const config = await import('../example/nuxt.config').then(m => m.default || m)
19 | config.dev = false
20 |
21 | const nuxt = new Nuxt(config)
22 | await nuxt.ready()
23 |
24 | const builder = await new Builder(nuxt)
25 | const generator = await new Generator(nuxt, builder)
26 | await generator.generate({ init: true, build: true })
27 |
28 | browser = await createBrowser('jsdom', {
29 | staticServer: {
30 | port: await getPort(),
31 | folder: nuxt.options.generate.dir
32 | }
33 | })
34 | browser.setLogLevel(['warn', 'error', 'log', 'info'])
35 |
36 | expect(consola.warn).toHaveBeenCalledTimes(2)
37 | expect(consola.warn).toHaveBeenCalledWith(expect.stringContaining('Unable to index document'), expect.anything())
38 | expect(consola.warn).toHaveBeenCalledWith(expect.stringContaining('locale \'fr\' not supported'))
39 | })
40 |
41 | test('search /en/', async () => {
42 | const url = browser.getUrl('/en/')
43 | const page = await browser.page(url)
44 |
45 | await waitFor(500)
46 |
47 | expect(await page.getText('h1')).toBe('Moonwalkers (en)')
48 | expect(await page.getAttribute('.lunr-input', 'placeholder')).toBe('search')
49 | expect(await page.getElementCount('.lunr-results li')).toBe(0)
50 |
51 | const input = page.document.querySelector('input')
52 | input.value = 'test'
53 | const event = new page.window.Event('input')
54 | input.dispatchEvent(event)
55 |
56 | await waitFor(500)
57 |
58 | expect(await page.getElementCount('.lunr-results li')).toBe(3)
59 | })
60 |
61 | test('search /af/', async () => {
62 | const url = browser.getUrl('/af/')
63 | const page = await browser.page(url)
64 |
65 | await waitFor(500)
66 |
67 | expect(await page.getText('h1')).toBe('Moonwalkers (af)')
68 | expect(await page.getAttribute('.lunr-input', 'placeholder')).toBe('zoek')
69 | expect(await page.getElementCount('.lunr-results li')).toBe(0)
70 |
71 | const input = page.document.querySelector('input')
72 | input.value = 'test'
73 | const event = new page.window.Event('input')
74 | input.dispatchEvent(event)
75 |
76 | await waitFor(500)
77 |
78 | expect(await page.getElementCount('.lunr-results li')).toBe(1)
79 | })
80 | })
81 |
--------------------------------------------------------------------------------
/example/nuxt.config.js:
--------------------------------------------------------------------------------
1 | import { resolve } from 'path'
2 | import docs from './docs'
3 |
4 | export default {
5 | rootDir: resolve(__dirname, '..'),
6 | buildDir: resolve(__dirname, '.nuxt'),
7 | srcDir: __dirname,
8 | render: {
9 | resourceHints: false
10 | },
11 | modules: [
12 | 'nuxt-i18n',
13 | {
14 | handler: require('../'),
15 | options: {
16 | globalComponent: 'GlobalLunr',
17 | css: false,
18 | path: 'my-crazy-search-index-path',
19 | defaultLanguage: 'french',
20 | languages: ['en'],
21 | languageStemmerMap: {
22 | af: 'nl'
23 | },
24 | fields: ['name', 'body']
25 | }
26 | }
27 | ],
28 | i18n: {
29 | detectBrowserLanguage: false,
30 | locales: ['en', 'fr', 'af'],
31 | defaultLocale: 'en',
32 | strategy: 'prefix_and_default',
33 | vueI18n: {
34 | messages: {
35 | en: {
36 | 'lunr-module': {
37 | placeholderText: 'search'
38 | }
39 | },
40 | fr: {
41 | 'lunr-module': {
42 | placeholderText: 'chercher'
43 | }
44 | },
45 | af: {
46 | 'lunr-module': {
47 | placeholderText: 'zoek'
48 | }
49 | }
50 | }
51 | }
52 | },
53 | hooks: {
54 | ready (nuxt) {
55 | let documentIndex = 1
56 |
57 | // this call is just for increasing coverage
58 | // (the example is also just as test fixture)
59 | nuxt.callHook('lunr:document')
60 |
61 | // trigger 'not adding doc' warning to increase coverage
62 | nuxt.callHook('lunr:document', {
63 | document: true
64 | })
65 |
66 | for (const doc of docs) {
67 | nuxt.callHook('lunr:document', {
68 | locale: documentIndex === 1 ? 'fr' : (documentIndex % 2 ? 'en' : 'af'),
69 | document: {
70 | id: documentIndex,
71 | ...doc
72 | },
73 | /* !! WARNING: Do NOT copy this blindly !!
74 | *
75 | * When adding the full document as meta the json of your
76 | * search index will become very large very quickly. Parsing that
77 | * json on the client (especially mobile clients) could become a
78 | * performance issue
79 | *
80 | * Normally you'd only need to include 'enough' meta info to properly
81 | * recognise the document and to display your search results.
82 | * E.g. The path and title of the page the document refers to, but
83 | * _not_ the full text that was used for indexing
84 | */
85 | meta: doc
86 | })
87 | documentIndex++
88 | }
89 | }
90 | },
91 | build: {
92 | terser: false
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/lib/module.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import fs from 'fs'
3 | import util from 'util'
4 | import consola from 'consola'
5 | import lunr from 'lunr'
6 | import lunrStemmer from 'lunr-languages/lunr.stemmer.support'
7 | import { placeholderText, statusMessages } from './constants'
8 |
9 | const readDir = util.promisify(fs.readdir)
10 | const logger = process.env.NODE_ENV === 'test' ? consola : consola.withScope('lunr-module')
11 | const normalizeLanguage = locale => (locale || '').substr(0, 2).toLowerCase()
12 |
13 | const defaultOptions = {
14 | includeComponent: true,
15 | globalComponent: false,
16 | css: true,
17 | defaultLanguage: 'en',
18 | languages: undefined,
19 | languageStemmerMap: {},
20 | path: 'search-index',
21 | placeholderText,
22 | statusMessages,
23 | ref: 'id',
24 | fields: [
25 | 'title',
26 | 'body'
27 | ]
28 | }
29 |
30 | module.exports = async function LunrModule (options = {}) {
31 | const nuxt = this.nuxt
32 |
33 | options = {
34 | ...defaultOptions,
35 | ...nuxt.options.lunr,
36 | ...options,
37 | supportedLanguages: []
38 | }
39 |
40 | if (options.path !== defaultOptions.path) {
41 | options.path = options.path.replace(/^\/+|\/+$/g, '')
42 | }
43 |
44 | const useI18N = nuxt.options.i18n && nuxt.options.i18n.locales.length
45 | let usedLocales = []
46 | /* istanbul ignore next */
47 | if (typeof options.languages === 'string') {
48 | usedLocales = [options.languages]
49 | } else if (Array.isArray(options.languages)) {
50 | usedLocales = options.languages
51 | /* istanbul ignore next */
52 | } else if (useI18N) {
53 | usedLocales = nuxt.options.i18n.locales
54 | }
55 |
56 | if (Array.isArray(usedLocales)) {
57 | usedLocales = usedLocales.concat(Object.values(options.languageStemmerMap))
58 |
59 | const allSupportedLanguages = []
60 |
61 | const languagesPath = path.dirname(require.resolve('lunr-languages/package.json'))
62 | if (languagesPath) {
63 | const files = await readDir(languagesPath)
64 | for (const file of files) {
65 | if (!file.startsWith('lunr.') || !file.endsWith('.js')) {
66 | continue
67 | }
68 |
69 | const [, language] = file.toLowerCase().split('.')
70 |
71 | if (language && language.length === 2) {
72 | allSupportedLanguages.push(language)
73 | }
74 | }
75 | }
76 |
77 | options.supportedLanguages = usedLocales
78 | .map((locale) => {
79 | locale = typeof locale === 'string' ? locale : locale.code
80 |
81 | const language = normalizeLanguage(locale)
82 |
83 | if (allSupportedLanguages.includes(language)) {
84 | return language
85 | }
86 |
87 | return false
88 | })
89 | .filter(Boolean)
90 | }
91 |
92 | if (options.defaultLanguage !== 'en' && !options.supportedLanguages.includes(options.defaultLanguage)) {
93 | options.defaultLanguage = defaultOptions.defaultLanguage
94 | }
95 |
96 | if (options.supportedLanguages.length) {
97 | lunrStemmer(lunr)
98 | }
99 |
100 | let metas
101 | const documents = {}
102 | nuxt.hook('lunr:document', ({ locale = 'en', document, meta } = {}) => {
103 | if (!document) {
104 | return
105 | }
106 |
107 | const language = normalizeLanguage(locale)
108 | let stemmerLanguage = options.languageStemmerMap[language] || language
109 |
110 | if (stemmerLanguage !== 'en' && !options.supportedLanguages.includes(stemmerLanguage)) {
111 | logger.warn(`locale '${locale}' not supported, falling back to ${options.defaultLanguage} for stemming`)
112 | stemmerLanguage = options.defaultLanguage
113 |
114 | options.languageStemmerMap[language] = stemmerLanguage
115 | }
116 |
117 | if (!documents[language]) {
118 | documents[language] = []
119 | }
120 |
121 | if (meta && (!metas || !metas[language])) {
122 | metas = metas || {}
123 | metas[language] = {}
124 | }
125 |
126 | const documentRef = document[options.ref]
127 | if (!documentRef) {
128 | logger.warn(`Unable to index document, does not contain a ref '${options.ref}'. Document:`, document)
129 | return
130 | }
131 |
132 | documents[language].push(document)
133 |
134 | if (meta) {
135 | metas[language][documentRef] = meta
136 | }
137 | })
138 |
139 | const webpackPlugin = compilation => createSearchIndexAssets(compilation, documents)
140 | this.options.build.plugins.push({
141 | apply (compiler) {
142 | compiler.hooks.emit.tapPromise('LunrModulePlugin', webpackPlugin)
143 | }
144 | })
145 |
146 | this.extendBuild((config) => {
147 | config.resolve.alias['lunr-module'] = path.join(this.options.buildDir, 'lunr')
148 | })
149 |
150 | if (options.includeComponent || options.globalComponent) {
151 | this.addTemplate({
152 | src: path.resolve(__dirname, 'icon-search.svg'),
153 | fileName: 'lunr/icon-search.svg'
154 | })
155 |
156 | this.addTemplate({
157 | src: path.resolve(__dirname, 'search.vue'),
158 | fileName: 'lunr/search.vue',
159 | options: {
160 | ...options,
161 | useI18N,
162 | publicPath: nuxt.options.build.publicPath
163 | }
164 | })
165 | }
166 |
167 | if (options.globalComponent) {
168 | this.addPlugin({
169 | src: path.resolve(__dirname, 'plugin.js'),
170 | fileName: 'lunr/plugin.js',
171 | options
172 | })
173 | }
174 |
175 | async function createSearchIndex (language, documents) {
176 | // retrieve the mapped language we should use for stemming
177 | const stemmerLanguage = options.languageStemmerMap[language]
178 |
179 | // this will be set to false for en, but en is supported by default
180 | // and doesnt require any extra lunr modules
181 | const isSupportedLanguage = options.supportedLanguages.includes(stemmerLanguage)
182 |
183 | if (isSupportedLanguage && !lunr[stemmerLanguage]) {
184 | const lunrLanguage = await import('lunr-languages/lunr.' + stemmerLanguage).then(m => m.default || m)
185 | lunrLanguage(lunr)
186 | }
187 |
188 | let lunrBuilder
189 | lunr(builder => (lunrBuilder = builder))
190 | await nuxt.callHook('lunr:index:beforeCreate', {
191 | locale: language,
192 | stemmerLanguage,
193 | builder: lunrBuilder
194 | })
195 |
196 | if (isSupportedLanguage) {
197 | lunrBuilder.use(lunr[stemmerLanguage])
198 | }
199 |
200 | lunrBuilder.ref(options.ref)
201 | for (const field of options.fields) {
202 | lunrBuilder.field(field)
203 | }
204 |
205 | await nuxt.callHook('lunr:index:created', {
206 | locale: language,
207 | stemmerLanguage,
208 | builder: lunrBuilder
209 | })
210 |
211 | for (const document of documents) {
212 | lunrBuilder.add(document)
213 | }
214 |
215 | const searchIndex = lunrBuilder.build()
216 |
217 | await nuxt.callHook('lunr:index:done', {
218 | locale: language,
219 | stemmerLanguage,
220 | builder: lunrBuilder,
221 | index: searchIndex
222 | })
223 |
224 | return searchIndex.toJSON()
225 | }
226 |
227 | async function createSearchIndexAssets (compilation, documents) {
228 | for (const language in documents) {
229 | const searchJson = await createSearchIndex(language, documents[language])
230 |
231 | if (metas && metas[language]) {
232 | searchJson.metas = metas[language]
233 | }
234 |
235 | await nuxt.callHook('lunr:asset', {
236 | locale: language,
237 | json: searchJson
238 | })
239 |
240 | const jsonString = JSON.stringify(searchJson)
241 |
242 | compilation.assets[`${options.path}/${language}.json`] = {
243 | source: () => jsonString,
244 | size: () => jsonString.length
245 | }
246 | }
247 | }
248 | }
249 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # lunr.js module
2 |
3 | [![npm version][npm-version-src]][npm-version-href]
4 | [![npm downloads][npm-downloads-src]][npm-downloads-href]
5 | [![Circle CI][circle-ci-src]][circle-ci-href]
6 | [![Codecov][codecov-src]][codecov-href]
7 | [![License][license-src]][license-href]
8 |
9 | > Full-text search with pre-build indexes for Nuxt.js using [lunr.js](https://lunrjs.com/)
10 |
11 | During the build phase of Nuxt.js you can add documents to the search index builder by calling the nuxt hook `lunr:document`. If you have configured and pass a [supported][lunr-supported-lang] locale along the document, the index will be build using the lunr stemmer for the specified language. As the lunr search index only holds references to your documents, you can optionally pass a meta prop along with the document which will be added to the search index as well.
12 |
13 | [📖 **Release Notes**](./CHANGELOG.md)
14 |
15 | ## Setup
16 |
17 | 1. Add `@nuxtjs/lunr-module` dependency to your project
18 |
19 | ```bash
20 | $ yarn add @nuxtjs/lunr-module # or npm install @nuxtjs/lunr-module
21 | ```
22 |
23 | 2. Add `@nuxtjs/lunr-module` to the `modules` section of `nuxt.config.js`
24 |
25 | ```js
26 | {
27 | modules: [
28 | // Simple usage
29 | '@nuxtjs/lunr-module',
30 |
31 | // With options
32 | {
33 | src: '@nuxtjs/lunr-module',
34 | // These are the default options:
35 | /*
36 | options: {
37 | includeComponent: true,
38 | globalComponent: false,
39 | css: true,
40 | defaultLanguage: 'en',
41 | languages: false,
42 | path: 'search-index',
43 | ref: 'id',
44 | fields: [
45 | 'title',
46 | 'body'
47 | ]
48 | } */
49 | }
50 | ]
51 | }
52 | ```
53 |
54 | ## Documentation
55 |
56 | ### Adding documents to search index
57 |
58 | Add documents by calling the nuxt hook `lunr:documents` as follows:
59 |
60 | ```js
61 | const document = {
62 | id: 1,
63 | title: 'My Title',
64 | body: 'The body'
65 | }
66 |
67 | const meta = {
68 | href: '/link/to/page',
69 | title: document.title
70 | }
71 |
72 | nuxt.callHook('lunr:document', ({
73 | locale: 'af', // optional, default en
74 | document,
75 | meta // optional
76 | })
77 | ```
78 |
79 | #### Locale support
80 |
81 | By configuring the locales options you can indicate for which [supported][lunr-supported-lang] languages a search index should be created. If you pass any other locale with a document it will be added to the [`defaultLanguage`](#defaultlanguage) search index (and a warning will be printed).
82 |
83 | > Multiple languages equals multiple search indexes
84 |
85 | English is supported by default in Lunr, when you only have English documents you dont have to configure or pass any locale.
86 |
87 | ##### Language vs Locale
88 |
89 | A locale can consist of just a language or include a territory, you can use either of them. So both just the language (e.g. _nl_) as including the territory (e.g. _nl_NL_) will work
90 |
91 | ##### nuxt-i18n integration
92 |
93 | If this module detects your project uses [nuxt-i18n](https://github.com/nuxt-community/nuxt-i18n) then the configured locales for nuxt-i18n will be automatically added. You dont have to configure the locales you use twice unless you want to use different locales (e.g. only one) for the search index.
94 |
95 | ### Add a search component to your website
96 |
97 | This module includes a search component which you can use on your website. Use it's default slot to display your search results using the properties passed in the meta prop
98 |
99 | ```vue
100 |
101 |
102 |
103 |
104 | {{ meta.title }}
105 | score: {{ Math.round(100 * result.score / maxScore) }}%
106 |
107 |
108 |
109 |
110 |
111 |
120 | ```
121 |
122 | ## Performance considerations
123 |
124 | ### Use an integer as document reference
125 |
126 | The document reference (defined by [option.ref](#ref)) is used in the search index to link all stemmed word segments. If you would use e.g. the page path as the document reference, then for a page with path `/en/offices/emea/nl/contact` that string value will be used to link all the stemmed word segments. This could increases the size of the search index massively, therefor its recommended to create a numeric document reference and use the `meta` property to add the page path for that document reference only once to the search index.
127 |
128 | ### Load search component dynamically
129 | Lunr doesnt export ES6 modules and can't be tree-shaked. Using this module adds `~8.5KB` + `~2KB` for every other language then English to your bundle (gzipped). See example above for a dynamic import which makes sure the lunr imports are not included in your vendors bundle
130 |
131 | ### Keep an eye on the search index size in general
132 | The search index is saved as a json file and thus needs to be parsed on the client. If the json of your search index becomes very large it could be an issue on (mobile) clients. E.g. Safari on iOS limits each top-level entry-point to run for max 10 seconds. See [this](https://github.com/olivernn/lunr.js/issues/330) Lunr.js issue for a possible workaround.
133 |
134 | ## Reference
135 |
136 | ### Options
137 |
138 | #### includeComponent
139 | - type `Boolean`
140 | - default `true`
141 |
142 | If true then the default search component will be added to your Nuxt project
143 |
144 | > You can import the component using the webpack alias `lunr-module/search`
145 |
146 | #### globalComponent
147 | - type `Boolean`, `String`
148 | - default `false`
149 |
150 | If truthy then a plugin will be added to your project which installs the search component globally
151 |
152 | > Setting this option implies `includeComponent: true`
153 |
154 | By default the search component will be registered as `lunr-search`, if you wish this name you can set this option to a string with the name you wish to use
155 |
156 | ```js
157 | globalComponent: 'my-global-lunr-search'
158 | ...
159 |
160 |
161 |
162 | ```
163 |
164 | #### css
165 | - type `Boolean`
166 | - default `true`
167 |
168 | If the search component is included, this option determines if the default css styles should be included or not
169 |
170 | #### defaultLanguage
171 | - type `String`
172 | - default `'en'`
173 |
174 | The default language to use. This is also the fall-back language if you pass a document with a non-supported locale
175 |
176 | #### languages
177 | - type `String`, `Array`
178 | - default `undefined`
179 |
180 | A string or array of the languages for which a search index needs to be created.
181 |
182 | Although this option might look redundant (i.e. why not just create a search index for every language which is passed), it provides a check to prevent 'rogue' documents from being indexed into a separate index.
183 |
184 | #### languageStemmerMap
185 | - type `Object`
186 | - default `{}`
187 |
188 | An object which contains a map of unsupported languages to supported stemming languages (by lunr). Use this to specify which stemming language should be used if you want to build a search index for a language which is not supported by lunr (yet).
189 |
190 | #### path
191 | - type `String`
192 | - default `search-index`
193 |
194 | On build of your project the created search indexes will be emitted as webpack assets. This option determines the path under `nuxt.publicPath` should be used.
195 |
196 | > With default configurations for Nuxt.js and this module the English search index is available under `/_nuxt/search-index/en.json`
197 |
198 | #### ref
199 | - type `String`
200 | - default `id`
201 |
202 | The name of the property in your document which specifies what as reference should be used for this document in the search index
203 |
204 | #### fields
205 | - type `Array`
206 | - default `['title', 'body']`
207 |
208 | The property names in your document which will be indexed
209 |
210 | #### placeholderText
211 | - type `String`
212 | - default `Search`
213 |
214 | The text that is put in the placeholder of the search input field. If you are using nuxt-i18n, you can also provide a translation with key `lunr-module.placeholderText`
215 |
216 | #### statusMessages
217 | - type `Array`
218 | - default `{
219 | fetching: 'Fetching search index',
220 | loading: 'Loading search index',
221 | searching: 'Searching...',
222 | noresults: 'No results found'
223 | }`
224 |
225 | The status messages which are displayed during the search life cycle. If you are using nuxt-i18n, you can also provide a translation with key `lunr-module.${key}`. Eg use `lunr-module.noresults` to provide a translation for the no results found status.
226 |
227 | ### Hooks (Listening)
228 |
229 | > use `nuxt.callHook(, )` if you wish to use these hooks
230 |
231 | #### lunr:document
232 | - arg: `({ locale?, document, meta? })`
233 |
234 | The main hook which is used to add documents to the search index. You need to pass an object as described. Both locale as meta are optional. If no locale is passed the `defaultLanguage` will be used
235 |
236 | ### Hooks (Emitting)
237 |
238 | > use `nuxt.hook(, )` if you wish to use these hooks. The callback function receives the listed arguments
239 |
240 | #### lunr:index:beforeCreate
241 | - arg: `({ locale, builder })`
242 |
243 | > Use this hook if you e.g. want to register custom lunr plugins
244 |
245 | This hook is called after the lunr builder is instantiated but before language plugins have been added or any refs and fields are set
246 |
247 | #### lunr:index:created
248 | - arg: `({ locale, builder })`
249 |
250 | > Use this hook if you e.g. want to add extra documents to an index
251 |
252 | This hook is called when the lunr builder has been setup, just before the documents are added to the index.
253 |
254 | #### lunr:index:done
255 | - arg: `({ locale, builder, index })`
256 |
257 | > Use this hook if you wish to interact with the index before exporting it
258 |
259 | This hook is called just before the index is exported as an json object
260 |
261 | #### lunr:asset
262 | - arg: `({ locale, json })`
263 |
264 | > Use this hook if you wish to manipulate the json which is emitted as search index for the locale
265 |
266 | This hook is called during webpack compilation just before the search index is prepared to be emitted as asset
267 |
268 | ## Development
269 |
270 | 1. Clone this repository
271 | 2. Install dependencies using `yarn install` or `npm install`
272 | 3. Start development server using `npm run dev`
273 |
274 | ## License
275 |
276 | [MIT License](./LICENSE)
277 |
278 | Copyright (c) pimlie
279 |
280 |
281 | [npm-version-src]: https://img.shields.io/npm/v/@nuxtjs/lunr-module/latest.svg?style=flat-square
282 | [npm-version-href]: https://npmjs.com/package/@nuxtjs/lunr-module
283 |
284 | [npm-downloads-src]: https://img.shields.io/npm/dt/@nuxtjs/lunr-module.svg?style=flat-square
285 | [npm-downloads-href]: https://npmjs.com/package/@nuxtjs/lunr-module
286 |
287 | [circle-ci-src]: https://img.shields.io/circleci/project/github/nuxt-community/lunr-module.svg?style=flat-square
288 | [circle-ci-href]: https://circleci.com/gh/nuxt-community/lunr-module
289 |
290 | [codecov-src]: https://img.shields.io/codecov/c/github/nuxt-community/lunr-module.svg?style=flat-square
291 | [codecov-href]: https://codecov.io/gh/nuxt-community/lunr-module
292 |
293 | [license-src]: https://img.shields.io/npm/l/@nuxtjs/lunr-module.svg?style=flat-square
294 | [license-href]: https://npmjs.com/package/@nuxtjs/lunr-module
295 |
296 | [lunr-supported-lang]: https://lunrjs.com/guides/language_support.html
297 |
--------------------------------------------------------------------------------
/lib/search.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
57 |
58 |
59 |
60 |
373 | <% if (options.css) { %>
374 |
435 | <% } %>
436 |
--------------------------------------------------------------------------------
/example/docs.json:
--------------------------------------------------------------------------------
1 | [{"name":"alan bean","body":"Alan Bean was one of the third group of astronauts named by NASA in October 1963. He served as backup astronaut for the Gemini 10 and Apollo 9 missions. Captain Bean was lunar module pilot on Apollo 12, mans second lunar landing. In November 1969, Captain Bean and Captain Pete Conrad landed in the moons Ocean of Stormsafter a flight of some 250,000 miles. They explored the lunar surface, deployed several lunar surface experiments, and installed the first nuclear power generator station on the moon to provide the power source. Captain Richard Gordon remained in lunar orbit photographing landing sites for future missions. Captain Bean was spacecraft commander of Skylab Mission II (SL-3), July 29 to September 25, 1973. With him on the 59-day, 24,400,000 mile world record setting flight were scientist-astronaut Dr. Owen K. Garriott and Marine Corps Lieutenant Colonel Jack R. Lousma. Mission II accomplished 150% of its pre-mission forecast goals. On his next assignment, Captain Bean was backup spacecraft commander of the United States flight crew for the joint American-Russian Apollo-Soyuz Test Project. Captain Bean has logged 1,671 hours and 45 minutes in spaceof which 10 hours and 26 minutes were spent in EVAs on the moon and in earth orbit."},{"name":"alan shepard","body":"Rear Admiral Shepard was one of the Mercury astronauts named by NASA in April 1959, and he holds the distinction of being the first American to journey into space. On May 5, 1961, in the Freedom 7 spacecraft, he was launched by a Redstone vehicle on a ballistic trajectory suborbital flight--a flight which carried him to an altitude of 116 statute miles and to a landing point 302 statute miles down the Atlantic Missile Range. In 1963, he was designated Chief of the Astronaut Office with responsibility for monitoring the coordination, scheduling, and control of all activities involving NASA astronauts. This included monitoring the development and implementation of effective training programs to assure the flight readiness of available pilot/non-pilot personnel for assignment to crew positions on manned space flights; furnishing pilot evaluations applicable to the design, construction, and operations of spacecraft systems and related equipment; and providing qualitative scientific and engineering observations to facilitate overall mission planning, formulation of feasible operational procedures, and selection and conduct of specific experiments for each flight. He was restored to full flight status in May 1969, following corrective surgery for an inner ear disorder. Shepard made his second space flight as spacecraft commander on Apollo 14, January 31 - February 9, 1971. He was accompanied on man's third lunar landing mission by Stuart A. Roosa, command module pilot, and Edgar D. Mitchell, lunar module pilot. Maneuvering their lunar module, \"Antares,\" to a landing in the hilly upland Fra Mauro region of the moon, Shepard and Mitchell subsequently deployed and activated various scientific equipment and experiments and collected almost 100 pounds of lunar samples for return to earth. Other Apollo 14 achievements included: first use of Mobile Equipment Transporter (MET); largest payload placed in lunar orbit; longest distance traversed on the lunar surface; largest payload returned from the lunar surface; longest lunar surface stay time (33 hours); longest lunar surface EVA (9 hours and 17 minutes); first use of shortened lunar orbit rendezvous techniques; first use of colored TV with new vidicon tube on lunar surface; and first extensive orbital science period conducted during CSM solo operations."},{"name":"buzz aldrin","body":"Aldrin was one of the third group of astronauts named by NASA in October 1963. On November 11, 1966, he and command pilot James Lovell were launched into space in the Gemini 12 spacecraft on a 4-day flight, which brought the Gemini program to a successful close. Aldrin established a new record for extravehicular activity (EVA), spending 5-1/2 hours outside the spacecraft. He served as lunar module pilot for Apollo 11, July 16-24, 1969, the first manned lunar landing mission. Aldrin followed Neil Armstrong onto the lunar surface on July 20, 1969, completing a 2-hour and 15 minute lunar EVA. In July 1971, Aldrin resigned from NASA. Aldrin has logged 289 hours and 53 minutes in space, of which, 7 hours and 52 minutes were spent in EVA."},{"name":"charles duke","body":"Duke was one of the 19 astronauts selected by NASA in April 1966. He served as member of the astronaut support crew for the Apollo 10 flight. He was CAPCOM for Apollo 11, the first landing on the Moon and he served as backup lunar module pilot on Apollo 13. Duke served as lunar module pilot of Apollo 16, April 16-27, 1972. He was accompanied on the fifth manned lunar landing mission by John W. Young (spacecraft commander) and Thomas K. Mattingly II (command module pilot). Apollo 16 was the first scientific expedition to inspect, survey, and sample materials and surface features in the Descartes region of the rugged lunar highlands. Duke and Young commenced their record setting lunar surface stay of 71 hours and 14 minutes by maneuvering the lunar module \"Orion\" to a landing on the rough Cayley Plains. In three subsequent excursions onto the lunar surface, they each logged 20 hours and 15 minutes in extravehicular activities involving the emplacement and activation of scientific equipment and experiments, the collection of nearly 213 pounds of rock and soil samples, and the evaluation and use of Rover-2 over the roughest and blockiest surface yet encountered on the moon. Other Apollo 16 achievements included the largest payload placed in lunar orbit (76, 109 pounds); first cosmic ray detector deployed on lunar surface; first lunar observatory with the far UV camera; and longest in-flight EVA from a command module during transearth coast (1 hour and 13 minutes). The latter feat was accomplished by Mattingly when he ventured out to \"Casper's\" SIM-bay for the retrieval of vital film cassettes from the panoramic and mapping cameras. Apollo 16 concluded with a Pacific Ocean splashdown and subsequent recovery by the USS TICONDEROGA. With the completion of his first space flight, Duke has logged 265 hours in space and over 21 hours of extra vehicular activity. Duke also served as backup lunar module pilot for Apollo 17."},{"name":"david scott","body":"Scott was one of the third group of astronauts named by NASA in October 1963. On March 16, 1966, he and command pilot Neil Armstrong were launched into space on the Gemini 8 mission--a flight originally scheduled to last three days but terminated early due to a malfunctioning thruster. The crew performed the first successful docking of two vehicles in space and demonstrated great piloting skill in overcoming the thruster problem and bringing the spacecraft to a safe landing. Scott served as command module pilot for Apollo 9, March 3-13, 1969. This was the third manned flight in the Apollo series, the second to be launched by a Saturn V, and the first to complete a comprehensive earth-orbital qualification and verification test of a \"fully configured Apollo spacecraft.\" The ten-day flight provided vital information previously not available on the operational performance, stability, and reliability of lunar module propulsion and life support systems. Highlight of this evaluation was completion of a critical lunar-orbit rendezvous simulation and subsequent docking, initiated by James McDivitt and Russell Schweickart from within the lunar module at a separation distance which exceeded 100 miles from the command/service module piloted by Scott. The crew also demonstrated and confirmed the operational feasibility of crew transfer and extravehicular activity techniques and equipment, with Schweickart completing a 46-minute EVA outside the lunar module. During this period, Dave Scott completed a 1-hour stand-up EVA in the open command module hatch photographing Schweickart's activities and also retrieving thermal samples from the command module exterior. Apollo 9 splashed down less than four miles from the helicopter carrier USS GUADALCANAL. In his next assignment, Scott was designated backup spacecraft commander for Apollo 12. He made his third space flight as spacecraft commander of Apollo 15, July 26 - August 7, 1971. His companions on the flight were Alfred M. Worden (command module pilot) and James B. Irwin (lunar module pilot). Apollo 15 was the fourth manned lunar landing mission and the first to visit and explore the moon's Hadley Rille and Apennine Mountains which are located on the southeast edge of the Mare Imbrium (Sea of Rains). The lunar module, \"Falcon,\" remained on the lunar surface for 66 hours and 54 minutes (setting a new record for lunar surface stay time) and Scott and Irwin logged 18 hours and 35 minutes each in extravehicular activities conducted during three separate excursions onto the lunar surface. Using \"Rover-1\" to transport themselves and their equipment along portions of Hadley Rille and the Apennine Mountains, Scott and Irwin performed a selenological inspection and survey of the area and collected 180 pounds of lunar surface materials. They deployed an ALSEP package which involved the emplacement and activation of surface experiments, and their lunar surface activities were televised using a TV camera which was operated remotely by ground controllers stationed in the mission control center located at Houston, Texas. Other Apollo 15 achievements include: largest payloads ever placed into earth and lunar orbits; first scientific instrument module bay flown and operated on an Apollo spacecraft; longest distance traversed on lunar surface; first use of a lunar surface navigation device (mounted on Rover-1); first subsatellite launched in lunar orbit; and first extravehicular (EVA) from a command module during transearth coast. The latter feat performed by Worden during three excursions to \"Endeavour's\" SIM-bay where he retrieved film cassettes from the panoramic and mapping cameras and reported his personal observations of the general condition of equipment housed there. Apollo 15 concluded with a Pacific Ocean splashdown and subsequent recovery by the USS OKINAWA."},{"name":"edgar mitchell","body":"Mitchell was a member of Group 5, selected for astronaut training in April 1966. He served as a member of the astronaut support crew for Apollo 9 and as backup lunar module pilot for Apollo 10. On January 31, 1971, serving as lunar module pilot, Dr. Edgar Mitchell, then a U.S. Navy Captain, embarked on a journey through outer space of some 500,000 miles that resulted in becoming the sixth man to walk on the moon. That historic journey terminated safely nine days later on February 9, 1971 and was made in the company of two other men of valor Admiral Alan Shepard and Colonel Stuart Roosa. Maneuvering their lunar module, Antares, to a landing in the hilly upland Fra Mauro region of the moon, Shepard and Mitchell subsequently deployed and activated various scientific equipment and experiments and collected almost 100 pounds of lunar samples for return to Earth. Other Apollo 14 achievements included: first use of Mobile Equipment Transporter (MET); largest payload placed in lunar orbit; longest distance traversed on the lunar surface; largest payload returned from the lunar surface; longest lunar surface stay time (33 hours); longest lunar surface EVA (9 hours and 17 minutes); first use of shortened lunar orbit rendezvous techniques; first use of color TV with new vidicon tube on lunar surface; and first extensive orbital science period conducted during CSM solo operations. In completing his first space flight, Mitchell logged a total of 216 hours and 42 minutes in space. He was subsequently designated to serve as backup lunar module pilot for Apollo 16."},{"name":"eugene cernan","body":"Captain Cernan was one of fourteen astronauts selected by NASA in October 1963. He occupied the pilot seat alongside of command pilot Tom Stafford on the Gemini IX mission. During this 3-day flight which Began on June 3, 1966, the spacecraft achieved a circular orbit of 161 statute miles; the crew used three different techniques to effect rendezvous with the previously launched Augmented Target Docking Adapter; and Cernan, the second American to walk in space, logged two hours and ten minutes outside the spacecraft in extravehicular activities. The flight ended after 72 hours and 20 minutes with a perfect re-entry and recovery as Gemini IX landed within 1-1/2 miles of the prime recovery ship USS WASP and 3/8 of a mile from the predetermined target. Cernan subsequently served as backup pilot for Gemini 12 and as backup lunar module pilot for Apollo 7. On his second space flight, he was lunar module pilot of Apollo 10, May 18-26, 1969, the first comprehensive lunar-orbital qualification and verification flight test of an Apollo lunar module. He was accompanied on the 248,000 nautical sojourn to the moon by Thomas P. Stafford (spacecraft commander) and John W. Young (commander module pilot). In accomplishing all of the assigned objectives of this mission, Apollo 10 confirmed the operations performance, stability, and reliability of the command/service module and lunar module configuration during trans-lunar coast, lunar orbit insertion, and lunar module separation and descent to within 8 nautical miles of the lunar surface. The latter maneuver involved employing all but the final minutes of the technique prescribed for use in an actual lunar landing, and allowed critical evaluations of the lunar module propulsions systems and rendezvous of the landing radar devices in subsequent rendezvous and re-docking maneuvers. In addition to demonstrating that man could navigate safely and accurately in the moon's gravitational fields, Apollo 10 photographed and mapped tentative landing sites for future missions. Cernan's next assignment was backup spacecraft commander for Apollo 14. He made his third space flight as spacecraft commander of Apollo 17--the last scheduled manned mission to the moon for the United States--which commenced at 11:33 P.M. (CST), December 6, 1972, with the first manned nighttime launch, and concluded on December 19, 1972. With him on the voyage of the command module \"America\" and the lunar module \"Challenger\" were Ronald Evans (command module pilot) and Harrison H. (Jack) Schmitt (lunar module pilot). In maneuvering \"Challenger\" to a landing at Taurus-Littrow, located on the southeast edge of Mare Serenitatis, Cernan and Schmitt activated a base of operations from which they completed three highly successful excursions to the nearby craters and the Taurus mountains, making the Moon their home for over three days. This last mission to the moon established several new records for manned space flight that include: longest manned lunar landing flight (301 hours 51 minutes); longest lunar surface extravehicular activities (22 hours 6 minutes); largest lunar sample return (an estimated 115 kg (249 lbs.); and longest time in lunar orbit (147 hours 48 minutes). While Cernan and Schmitt conducted activities on the lunar surface, Evans remained in lunar orbit aboard the \"America\" completing assigned work tasks requiring geological observations, handheld photography of specific targets, and the control of cameras and other highly sophisticated scientific equipment carried in the command module SIM-bay. Evans also completed a 1-hour, 6-minute extravehicular activity on the transearth coast phase of the return flight, successfully retrieving three camera cassettes and completing a personal inspection of the equipment bay area. Apollo 17 ended with a splashdown in the Pacific Ocean approximately 0.4 miles from the target point and 4.3 miles form the prime recovery ship USS TICONDEROGA. Captain Cernan was the second American to have walked in space having spanned the circumference of the world twice in a little more than 2-1/2 hours. He was one of the two men to have flown to the moon on two occasions, and as commander of the last mission to the moon, Apollo 17, had the privilege and distinction of being the last man to have left his footprints on the surface of the moon."},{"name":"harrison schmitt","body":"Dr. Schmitt was selected as a scientist-astronaut by NASA in June 1965. He later completed a 53-week course in flight training at Williams Air Force Base, Arizona. In addition to training for future manned space flights. He was instrumental in providing Apollo flight crews with detailed instruction in lunar navigation, geology, and feature recognition. Schmitt also assisted in the integration of scientific activities into the Apollo lunar missions and participated in research activities requiring geologic, petrographic, and stratigraphic analyses of samples returned from the moon by Apollo missions. On his first journey into space, Dr. Schmitt occupied the lunar module pilot seat for Apollo 17 -- the last scheduled manned Apollo mission to the United States --which commenced at 11:33 p.m. (CST), December 6, 1972, and concluded on December 19, 1972. He was accompanied on the voyage of the command module \"America\" and the lunar module \"Challenger\" by Eugene Cernan (spacecraft commander) and Ronald Evans (command module pilot). In maneuvering \"Challenger\" to a landing at Taurus-Littrow, which is located on the southeast edge of Mare Serenitatis, Schmitt and Cernan activated a base of operations facilitating their completion of three days of exploration. This last Apollo mission to the moon for the United States broke several records set by previous flights and include: longest manned lunar landing flight (301 hours, 51 minutes); longest lunar surface extravehicular activities (22 hours, 4 minutes); largest lunar sample return (an estimated 115 Kg, 249 lbs); and longest time in lunar orbit (147 hours, 48 minutes). Apollo 17 ended with a splashdown in the Pacific Ocean approximately 0.4 mile from the target point and 4.3 miles from the prime recovery ship, USS TICONDEROGA."},{"name":"james irwin","body":"Colonel Irwin was one of the 19 astronauts selected by NASA in April 1966. He was crew commander of lunar module (LTA-8)-this vehicle finished the first series of thermal vacuum tests on June 1, 1968. He also served as a member of the astronaut support crew for Apollo 10 and as backup lunar module pilot for the Apollo 12 flight. Irwin served as lunar module pilot for Apollo, July 26 to August 7, 1971. His companions on the flight were David R. Scott, spacecraft commander and Alfred M. Worden, command module pilot. Apollo 15 was the fourth manned lunar landing mission and the first to visit and explore the moon's Hadley Rille and Apennine Mountains which are located on the southeast edge of the Mare Imbrium (Sea of Rains). The lunar module, \"Falcon\", remained on the lunar surface for 66 hours, 54 minutes-setting a new record for lunar surface stay time-and Scott and Irwin logged 18 hours and 35 minutes each in extravehicular activities conducted during three separate excursions onto the lunar surface. Using \"Rover-l\" to transport themselves and their equipment along portions of Hadley Rille and the Apinnine Mountains, Scott and Irwin performed a selenological inspection and survey of the area and collected approximately 180 pounds of lunar surface materials. They deployed an ALSEP package which involved the emplacement and activation of surface experiments, and their lunar surface activities were televised in color using a TV camera which was operated remotely by ground controllers stationed in the mission control center located at Houston, Texas. Other Apollo 15 achievements included: largest payloads ever placed in earth and lunar orbits; first scientific instrument module bay flown and operated on an Apollo spacecraft; longest distance traversed on lunar surface; first use of a lunar surface navigation device, mounted on Rover 1; first subsatellite launched in lunar orbit; and first extravehicular activity (EVA) from a command module during transearth coast. The latter feat was accomplished by Worden during three excursions to \"Endeavour's\" SIM bay where he retrieved film cassettes from the panoramic and mapping cameras and reported his personal observations of the general condition of equipment housed there. Apollo 15 concluded with a Pacific splashdown and subsequent recovery by the USS OKINAWA."},{"name":"john young","body":"In September 1962, Young was selected as an astronaut. He is the first person to fly in space six times from earth, and seven times counting his lunar liftoff. The first flight was with Gus Grissom in Gemini 3, the first manned Gemini mission, on March 23, 1965. This was a complete end-to-end test of the Gemini spacecraft, during which Gus accomplished the first manual change of orbit altitude and plane and the first lifting reentry, and Young operated the first computer on a manned spacecraft. On Gemini 10, July 18-21, 1966, Young, as Commander, and Mike Collins, as Pilot, completed a dual rendezvous with two separate Agena target vehicles. While Young flew close formation on the second Agena, Mike Collins did an extravehicular transfer to retrieve a micro meteorite detector from that Agena. On his third flight, May 18-26, 1969, Young was Command Module Pilot of Apollo 10. Tom Stafford and Gene Cernan were also on this mission which orbited the Moon, completed a lunar rendezvous, and tracked proposed lunar landing sites. His fourth space flight, Apollo 16, April 16-27, 1972, was a lunar exploration mission, with Young as Spacecraft Commander, and Ken Mattingly and Charlie Duke. Young and Duke set up scientific equipment and explored the lunar highlands at Descartes. They collected 200 pounds of rocks and drove over 16 miles in the lunar rover on three separate geology traverses. Young’s fifth flight was as Spacecraft Commander of STS-1, the first flight of the Space Shuttle, April 12-14, 1981, with Bob Crippen as Pilot. The 54-1/2 hour, 36-orbit mission verified Space Shuttle systems performance during launch, on orbit, and entry. Tests of the Orbiter Columbia included evaluation of mechanical systems including the payload bay doors, the attitude and maneuvering rocket thrusters, guidance and navigation systems, and Orbiter/crew compatibility. One hundred and thirty three of the mission’s flight test objectives were accomplished. The Orbiter Columbia was the first manned spaceship tested during ascent, on orbit, and entry without benefit of previous unmanned missions. Columbia was also the first winged reentry vehicle to return from space to a runway landing. It weighed about 98 tons as Young landed it on the dry lakebed at Edwards Air Force Base, California. Young’s sixth flight was as Spacecraft Commander of STS-9, the first Spacelab mission, November 28-December 8, 1983, with Pilot Brewster Shaw, Mission Specialists Bob Parker and Owen Garriott, and Payload Specialists Byron Lichtenberg of the USA and Ulf Merbold of West Germany. The mission successfully completed all 94 of its flight test objectives. For ten days the 6-man crew worked 12-hour shifts around-the-clock, performing more than 70 experiments in the fields of atmospheric physics, Earth observations, space plasma physics, astronomy and solar physics, materials processing and life sciences. The mission returned more scientific and technical data than all the previous Apollo and Skylab missions put together. The Spacelab was brought back for re-use, so that Columbia weighed over 110 tons as Young landed the spaceship at Edwards Air Force Base, California."},{"name":"neil armstrong","body":"As a research pilot at NASA’s Flight Research Center, Edwards, California, Armstrong was a project pilot on many pioneering high speed aircraft, including the well known, 4000-mph X-15. He flew more than 200 different models of aircraft, including jets, rockets, helicopters and gliders. Armstrong transferred to astronaut status in 1962. He was assigned as command pilot for the Gemini 8 mission. Gemini 8 was launched on March 16, 1966, and Armstrong performed the first successful docking of two vehicles in space. As spacecraft commander for Apollo 11, the first manned lunar landing mission, Armstrong gained the distinction of being the first man to land a craft on the moon and first to step on its surface. Armstrong subsequently held the position of Deputy Associate Administrator for Aeronautics, NASA Headquarters, Washington, D.C. In this position, he was responsible for the coordination and management of overall NASA research and technology work related to aeronautics."},{"name":"pete conrad","body":"In September of 1962, Mr. Conrad was selected as an astronaut by NASA. His first flight was Gemini V, which established the space endurance record and placed the United States in the lead for man-hours in space. As commander of Gemini XI, Mr. Conrad helped to set a world's altitude record. He then served as commander of Apollo XII, the second lunar landing. On Mr. Conrad's final mission, he served as commander of Skylab II, the first United States Space Station. In December 1973, after serving 20 years (11 of which were as an astronaut in the space program), Mr. Conrad retired from the U.S. Navy to accept a position as Vice President - Operations and Chief Operating Office of American Television and Communications Corporation (ATC). At ATC, he was responsible for both the operation of existing systems and the national development of new cable television systems. In 1976, he resigned from ATC to accept the position of Vice President and consultant to McDonnell Douglas Corporation. In 1978, he became Vice President of marketing and was responsible for all commercial and military sales for Douglas Aircraft Company. Mr. Conrad then became Senior Vice President-Marketing in 1980. He was appointed as Senior Vice President Marketing and Product Support in 1982 and 1984, was named Staff Vice President of International Business Development for McDonnell Douglas Corporation."}]
2 |
--------------------------------------------------------------------------------