Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

marp.config.ts support and defineConfig helper #549

Merged
merged 4 commits into from
Sep 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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