Skip to content

Commit

Permalink
Merge pull request #549 from marp-team/typescript-configuration
Browse files Browse the repository at this point in the history
`marp.config.ts` support and `defineConfig` helper
  • Loading branch information
yhatt committed Sep 23, 2023
2 parents 944cb38 + 683ddca commit d72ae4f
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## [Unreleased]

### Added

- Support the project configuration file written in TypeScript `marp.config.ts` ([#548](https://github.com/marp-team/marp-cli/pull/548), [#549](https://github.com/marp-team/marp-cli/pull/549))
- `defineConfig` helper for writing typed configuration ([#549](https://github.com/marp-team/marp-cli/pull/549))

### Changed

- Upgrade Marpit to [v2.5.3](https://github.com/marp-team/marpit/releases/tag/v2.5.3) ([#548](https://github.com/marp-team/marp-cli/pull/548))
Expand Down
35 changes: 32 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -621,9 +621,9 @@ This configuration will set the constructor option for Marp Core as specified:
</details>

### Type annotation
### Auto completion

For getting better IDE support (such as [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense)) to write a config, you can annotate the config object through JSDoc, with Marp CLI's `Config` type.
For getting the power of auto completion for the config, such as [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense), you can annotate the config object through JSDoc, with Marp CLI's `Config` type.

```javascript
/** @type {import('@marp-team/marp-cli').Config} */
Expand All @@ -634,9 +634,19 @@ const config = {
export default config
```

Or you can use Vite-like `defineConfig` helper from Marp CLI instead.

```javascript
import { defineConfig } from '@marp-team/marp-cli'

export default defineConfig({
// ...
})
```

#### `Config` type with custom engine

If you've swapped the engine into another Marpit based engine, you also can provide better suggestion for `options` field by passing the engine type to generics.
If you've swapped the engine into another Marpit based engine, you can provide better suggestion for `options` field by passing the engine type to generics.

```javascript
/** @type {import('@marp-team/marp-cli').Config<typeof import('@marp-team/marpit').Marpit>} */
Expand All @@ -650,6 +660,25 @@ const config = {
export default config
```

#### TypeScript (`marp.config.ts`)

If you installed `typescript` into your local project together with Marp CLI, you can write a config by TypeScript `marp.config.ts`. Marp CLI will try to transpile `.ts` with the project configuration `tsconfig.json`.

In TypeScript configuration, you can specify the custom engine as the generics for `defineConfig` helper, like this:

```typescript
// marp.config.ts
import { Marpit } from '@marp-team/marpit'
import { defineConfig } from '@marp-team/marp-cli'

export default defineConfig<typeof Marpit>({
engine: Marpit,
options: {
// Suggest only Marpit constructor options
},
})
```

## API _(EXPERIMENTAL)_

You can use Marp CLI through Node.js [if installed Marp CLI into your local project](#local-installation).
Expand Down
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ export interface Config<Engine extends typeof Marpit = typeof Marp>
options?: ConstructorParameters<Engine>[0]
}
> {}

export const defineConfig = <Engine extends typeof Marpit = typeof Marp>(
config: Config<Engine>
) => config
1 change: 1 addition & 0 deletions test/__mocks__/cosmiconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ cosmiconfig.cosmiconfig = jest.fn((moduleName, options) => {
'.js': defaultLoadersSync['.js'],
'.mjs': defaultLoadersSync['.js'],
'.cjs': defaultLoadersSync['.js'],
'.ts': defaultLoadersSync['.ts'],
},
...(options ?? {}),
})
Expand Down
7 changes: 7 additions & 0 deletions test/_configs/typescript/marp.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from '../../../src/index'

export default defineConfig({
title: 'TypeScript configuration',
})

console.debug('A config file with .ts extension was loaded.')
24 changes: 24 additions & 0 deletions test/marp-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,30 @@ describe('Marp CLI', () => {
}
})
})

describe('with TypeScript', () => {
it('allows loading config with TypeScript', async () => {
const debug = jest.spyOn(console, 'debug').mockImplementation()
const log = jest.spyOn(console, 'log').mockImplementation()

try {
expect(
await marpCli([
'-v',
'-c',
assetFn('_configs/typescript/marp.config.ts'),
])
).toBe(0)

expect(debug).toHaveBeenCalledWith(
expect.stringContaining('loaded')
)
} finally {
debug.mockRestore()
log.mockRestore()
}
})
})
})

describe('with --preview / -p option', () => {
Expand Down

0 comments on commit d72ae4f

Please sign in to comment.