diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a8c6c11..7aa86aec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)) diff --git a/README.md b/README.md index c5c41f44..036e0333 100644 --- a/README.md +++ b/README.md @@ -621,9 +621,9 @@ This configuration will set the constructor option for Marp Core as specified: -### 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} */ @@ -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} */ @@ -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({ + 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). diff --git a/src/index.ts b/src/index.ts index 0e568c8e..7cbb2f18 100644 --- a/src/index.ts +++ b/src/index.ts @@ -33,3 +33,7 @@ export interface Config options?: ConstructorParameters[0] } > {} + +export const defineConfig = ( + config: Config +) => config diff --git a/test/__mocks__/cosmiconfig.ts b/test/__mocks__/cosmiconfig.ts index e052e3b7..40a99f27 100644 --- a/test/__mocks__/cosmiconfig.ts +++ b/test/__mocks__/cosmiconfig.ts @@ -17,6 +17,7 @@ cosmiconfig.cosmiconfig = jest.fn((moduleName, options) => { '.js': defaultLoadersSync['.js'], '.mjs': defaultLoadersSync['.js'], '.cjs': defaultLoadersSync['.js'], + '.ts': defaultLoadersSync['.ts'], }, ...(options ?? {}), }) diff --git a/test/_configs/typescript/marp.config.ts b/test/_configs/typescript/marp.config.ts new file mode 100644 index 00000000..156dc58c --- /dev/null +++ b/test/_configs/typescript/marp.config.ts @@ -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.') diff --git a/test/marp-cli.ts b/test/marp-cli.ts index 65b17e62..9c381c9b 100644 --- a/test/marp-cli.ts +++ b/test/marp-cli.ts @@ -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', () => {