Skip to content

Commit

Permalink
feat: support format config (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
zce authored Oct 12, 2024
1 parent 714fcac commit 7c15717
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 23 deletions.
2 changes: 2 additions & 0 deletions docs/guide/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ console.log(posts) // => [{ title: 'Hello world', slug: 'hello-world', ... }, ..
Velite is **Framework Agnostic**, you can use it output with any framework or library you like.
From version `0.2.0`, Velite will output the entry file in the format you specified in the config. so you can choose the format you like.
:::
For more information about using collections, see [Using Collections](using-collections.md).
7 changes: 7 additions & 0 deletions docs/reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ The extensions blacklist of the assets, such as `['.md', '.yml']`, will be ignor

Whether to clean the output directories before build.

### `output.format`

- Type: `'esm' | 'cjs'`
- Default: `'esm'`

The output format of the entry file.

## `collections`

- Type: `{ [name: string]: Collection }`
Expand Down
2 changes: 1 addition & 1 deletion src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ export const build = async (options: Options = {}): Promise<Record<string, unkno
await mkdir(output.data, { recursive: true })
await mkdir(output.assets, { recursive: true })

await outputEntry(output.data, configPath, collections)
await outputEntry(output.data, output.format, configPath, collections)

logger.log('initialized', begin)

Expand Down
3 changes: 2 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ export const resolveConfig = async (path?: string, options: { strict?: boolean;
assets: resolve(cwd, loadedConfig.output?.assets ?? 'public/static'),
base: loadedConfig.output?.base ?? '/static/',
name: loadedConfig.output?.name ?? '[name]-[hash:8].[ext]',
clean: options.clean ?? loadedConfig.output?.clean ?? false
clean: options.clean ?? loadedConfig.output?.clean ?? false,
format: loadedConfig.output?.format ?? 'esm'
},
loaders: [...(loadedConfig.loaders ?? []), ...loaders],
strict: options.strict ?? loadedConfig.strict ?? false
Expand Down
22 changes: 13 additions & 9 deletions src/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { join, relative } from 'node:path'

import { logger } from './logger'

import type { Collections } from './types'
import type { Collections, Output } from './types'

const isProduction = process.env.NODE_ENV === 'production'

const emitted = new Map<string, string>()

Expand All @@ -29,20 +31,21 @@ export const emit = async (path: string, content: string, log?: string): Promise
* @param configPath resolved config file path
* @param collections collection options
*/
export const outputEntry = async (dest: string, configPath: string, collections: Collections): Promise<void> => {
export const outputEntry = async (dest: string, format: Output['format'], configPath: string, collections: Collections): Promise<void> => {
const begin = performance.now()

// generate entry according to `config.collections`
const configModPath = relative(dest, configPath)
.replace(/\\/g, '/') // replace windows path separator
.replace(/\.[mc]?[jt]s$/i, '') // remove extension
const configModPath = relative(dest, configPath).replace(/\\/g, '/')

const entry: string[] = []
const dts: string[] = [`import config from '${configModPath}'\n`]
const dts: string[] = [`import type config from '${configModPath}'\n`]
dts.push('type Collections = typeof config.collections\n')

Object.entries(collections).map(([name, collection]) => {
entry.push(`export { default as ${name} } from './${name}.json'`)
if (format === 'cjs') {
entry.push(`exports.${name} = require('./${name}.json')`)
} else {
entry.push(`export { default as ${name} } from './${name}.json'`)
}
dts.push(`export type ${collection.name} = Collections['${name}']['schema']['_output']`)
dts.push(`export declare const ${name}: ${collection.name + (collection.single ? '' : '[]')}\n`)
})
Expand Down Expand Up @@ -71,7 +74,8 @@ export const outputData = async (dest: string, result: Record<string, any>): Pro
if (data == null) return
const target = join(dest, name + '.json')
// TODO: output each record separately to a single file to improve fast refresh performance in app
await emit(target, JSON.stringify(data, null, 2), `wrote '${target}' with ${data.length ?? 1} ${name}`)
const content = isProduction ? JSON.stringify(data) : JSON.stringify(data, null, 2)
await emit(target, content, `wrote '${target}' with ${data.length ?? 1} ${name}`)
logs.push(`${data.length ?? 1} ${name}`)
})
)
Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ export interface Output {
* @default false
*/
clean: boolean
/**
* Output entry file format
* @default 'esm'
*/
format: 'esm' | 'cjs'
}

/**
Expand Down
8 changes: 4 additions & 4 deletions test/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ test('standalone fixtures', async t => {
equal(entry.length, 288, 'entry output length should be 288')

const dts = await readFile('examples/basic/.velite/index.d.ts', 'utf8')
equal(dts.length, 628, 'dts output length should be 628')
equal(dts.length, 636, 'dts output length should be 636')

const options = await readFile('examples/basic/.velite/options.json', 'utf8')
equal(options.length, 1121, 'options output length should be 1121')

const categories = await readFile('examples/basic/.velite/categories.json', 'utf8')
equal(categories.length, 880, 'categories output length should be 880')

const tags = await readFile('examples/basic/.velite/tags.json', 'utf8')
equal(tags.length, 315, 'tags output length should be 315')

const pages = await readFile('examples/basic/.velite/pages.json', 'utf8')
equal(pages.length, 6182, 'pages output length should be 6182')

const posts = await readFile('examples/basic/.velite/posts.json', 'utf8')
equal(posts.length, 14165, 'posts output length should be 14165')

const tags = await readFile('examples/basic/.velite/tags.json', 'utf8')
equal(tags.length, 315, 'tags output length should be 315')

await rm('examples/basic/.velite', { recursive: true, force: true })
})
16 changes: 8 additions & 8 deletions test/nextjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ test('integration with nextjs fixtures', async t => {
equal(entry.length, 288, 'entry output length should be 288')

const dts = await readFile('examples/nextjs/.velite/index.d.ts', 'utf8')
equal(dts.length, 628, 'dts output length should be 628')
equal(dts.length, 636, 'dts output length should be 636')

const options = await readFile('examples/nextjs/.velite/options.json', 'utf8')
equal(options.length, 1121, 'options output length should be 1121')
equal(options.length, 775, 'options output length should be 775')

const categories = await readFile('examples/nextjs/.velite/categories.json', 'utf8')
equal(categories.length, 880, 'categories output length should be 880')

const tags = await readFile('examples/nextjs/.velite/tags.json', 'utf8')
equal(tags.length, 315, 'tags output length should be 315')
equal(categories.length, 649, 'categories output length should be 649')

const pages = await readFile('examples/nextjs/.velite/pages.json', 'utf8')
equal(pages.length, 5003, 'pages output length should be 5003')
equal(pages.length, 4942, 'pages output length should be 4942')

const posts = await readFile('examples/nextjs/.velite/posts.json', 'utf8')
equal(posts.length, 20171, 'posts output length should be 20171')
equal(posts.length, 17991, 'posts output length should be 17991')

const tags = await readFile('examples/nextjs/.velite/tags.json', 'utf8')
equal(tags.length, 212, 'tags output length should be 212')

await rm('examples/nextjs/.velite', { recursive: true, force: true })
})

0 comments on commit 7c15717

Please sign in to comment.