Skip to content

Commit

Permalink
MDX support (#1531)
Browse files Browse the repository at this point in the history
* WIP: MDX

* Replace fixture

* Add MDX support in webpack

* Update getFixtures.test.ts

* Update native.ts

* Update shared.ts

* Update createRawFixtureTree.ts

* Update fixtures.md

* Update fixtures.md

* Update fixtures.md
  • Loading branch information
ovidiuch committed Jun 11, 2023
1 parent 33698af commit f88e4e6
Show file tree
Hide file tree
Showing 14 changed files with 945 additions and 54 deletions.
2 changes: 1 addition & 1 deletion cypress/tests/native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('Native', () => {
});

it('has fixture paths', () => {
containsImport('src/__fixtures__/HelloWorld');
containsImport('src/__fixtures__/HelloWorld.mdx');
containsImport('src/Counter.fixture');
containsImport('src/WelcomeMessage/WelcomeMessage.fixture');
});
Expand Down
8 changes: 7 additions & 1 deletion docs/usage/fixtures.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,17 @@ The object property names will show up as fixture names in the Cosmos UI.

> [See this comment](https://github.com/react-cosmos/react-cosmos/issues/924#issuecomment-462082405) for the reasoning behind this solution (vs named exports).
## MDX Fixtures

Creating MDX fixtures is as easy as [configuring MDX for your bundler](https://mdxjs.com/docs/getting-started/#bundler) and using the `.mdx` (or `.md`) file extension for your fixture files.

> Both Vite and Webpack [examples](../../examples) feature MDX fixtures configured with `@mdx-js/rollup` and `@mdx-js/loader` respectively.
## File Conventions

Two options:

1. End fixture file names with `.fixture.{js,jsx,ts,tsx}`.
1. End fixture file names with `.fixture.{js,jsx,ts,tsx,md,mdx}`.
2. Put fixture files inside `__fixtures__`.

Examples:
Expand Down
1 change: 1 addition & 0 deletions examples/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"native": "cosmos-native"
},
"dependencies": {
"@mdx-js/rollup": "^2.3.0",
"@vitejs/plugin-react": "^4.0.0",
"examples-shared": "6.0.0-beta.3",
"react": "^18.2.0",
Expand Down
1 change: 1 addition & 0 deletions examples/vite/src/__fixtures__/HelloWorld.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Hello World!
1 change: 0 additions & 1 deletion examples/vite/src/__fixtures__/HelloWorld.ts

This file was deleted.

3 changes: 2 additions & 1 deletion examples/vite/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import mdx from '@mdx-js/rollup';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
plugins: [react(), mdx()],
});
1 change: 1 addition & 0 deletions examples/webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@babel/core": "^7.21.8",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.5",
"@mdx-js/loader": "^2.3.0",
"babel-loader": "^9.1.2",
"examples-shared": "6.0.0-beta.3",
"react": "^18.2.0",
Expand Down
1 change: 1 addition & 0 deletions examples/webpack/src/__fixtures__/HelloWorld.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Hello World!
1 change: 0 additions & 1 deletion examples/webpack/src/__fixtures__/HelloWorld.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function parseFixturePath(fixturePath: string) {
}

function removeFixtureNameExtension(fixtureName: string) {
return fixtureName.replace(/\.(j|t)sx?$/, '');
return fixtureName.replace(/\.(js|jsx|ts|tsx|md|mdx)$/, '');
}

function injectNode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export function getDefaultWebpackConfig(
const postcssLoaderPath = resolveFromSilent(rootDir, 'postcss-loader');
// Note: Since webpack >= v2.0.0, importing of JSON files will work by default
const jsonLoaderPath = resolveFromSilent(rootDir, 'json-loader');
const mdxLoaderPath = resolveFromSilent(rootDir, '@mdx-js/loader');

const rules: webpack.RuleSetRule[] = [];
const plugins: webpack.WebpackPluginInstance[] = [];

Expand Down Expand Up @@ -80,6 +82,14 @@ export function getDefaultWebpackConfig(
});
}

if (mdxLoaderPath) {
rules.push({
test: /\.mdx$/,
loader: mdxLoaderPath,
exclude: /node_modules/,
});
}

const htmlWebpackPlugin = getHtmlWebpackPlugin(rootDir);
if (htmlWebpackPlugin) {
plugins.push(
Expand Down
48 changes: 6 additions & 42 deletions packages/react-cosmos/src/getFixtures/getFixtures.test.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,14 @@
// Import mocks first
import { mockFile } from '../testHelpers/mockFs.js';

import path from 'node:path';
import { create } from 'react-test-renderer';
import { createCosmosConfig } from '../cosmosConfig/createCosmosConfig.js';
import { mockCosmosPlugins } from '../testHelpers/mockCosmosPlugins.js';
import { getFixtures } from './getFixtures.js';

const rootDir = path.join(__dirname, '../../../../examples/webpack');

const testCosmosPlugin = {
name: 'Test Cosmos plugin',
rootDir: path.join(__dirname, 'mock-cosmos-plugin'),
server: path.join(__dirname, 'mock-cosmos-plugin/server.js'),
};
mockCosmosPlugins([testCosmosPlugin]);

const testServerPlugin = {
name: 'testServerPlugin',

config: jest.fn(async ({ cosmosConfig }) => {
return {
...cosmosConfig,
rendererUrl: 'http://localhost:5000/renderer.html',
};
}),
};

beforeEach(() => {
mockFile(testCosmosPlugin.server, { default: testServerPlugin });
});

it('renders fixture elements', async () => {
const cosmosConfig = createCosmosConfig(rootDir);
const cosmosConfig = createCosmosConfig(rootDir, {
ignore: ['**/*.mdx'],
});

const fixures = getFixtures(cosmosConfig, {
rendererUrl: 'http://localhost:5000/renderer.html',
Expand All @@ -51,7 +27,9 @@ it('renders fixture elements', async () => {
});

it('returns fixture info', async () => {
const cosmosConfig = createCosmosConfig(rootDir);
const cosmosConfig = createCosmosConfig(rootDir, {
ignore: ['**/*.mdx'],
});

const fixtures = getFixtures(cosmosConfig, {
rendererUrl: 'http://localhost:5000/renderer.html',
Expand Down Expand Up @@ -142,20 +120,6 @@ it('returns fixture info', async () => {
'http://localhost:5000/renderer.html?fixtureId=%7B%22path%22%3A%22src%2FCounterButton.fixture.tsx%22%7D',
treePath: ['CounterButton'],
},
{
absoluteFilePath: path.join(rootDir, 'src/__fixtures__/HelloWorld.ts'),
fileName: 'HelloWorld',
getElement: expect.any(Function),
name: null,
parents: [],
playgroundUrl:
'http://localhost:5000/?fixtureId=%7B%22path%22%3A%22src%2F__fixtures__%2FHelloWorld.ts%22%7D',
relativeFilePath: 'src/__fixtures__/HelloWorld.ts',
rendererUrl:
'http://localhost:5000/renderer.html?fixtureId=%7B%22path%22%3A%22src%2F__fixtures__%2FHelloWorld.ts%22%7D',
treePath: ['HelloWorld'],
},

{
absoluteFilePath: path.join(
rootDir,
Expand Down
4 changes: 2 additions & 2 deletions packages/react-cosmos/src/userModules/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export type UserImportsTemplateArgs = {

// NODE: These can be made configurable if a proper need arises
const FIXTURE_PATTERNS = [
'**/<fixturesDir>/**/*.{js,jsx,ts,tsx}',
'**/*.<fixtureFileSuffix>.{js,jsx,ts,tsx}',
'**/<fixturesDir>/**/*.{js,jsx,ts,tsx,md,mdx}',
'**/*.<fixtureFileSuffix>.{js,jsx,ts,tsx,md,mdx}',
];
const DECORATOR_PATTERNS = ['**/cosmos.decorator.{js,jsx,ts,tsx}'];

Expand Down

0 comments on commit f88e4e6

Please sign in to comment.