Skip to content

Commit

Permalink
feat: customize webpack-rules
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Apr 23, 2020
1 parent 35a4afa commit cf6d001
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 122 deletions.
36 changes: 22 additions & 14 deletions core/webpack-rules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- [Installation](#installation)
- [Usage](#usage)
- [API](#api)
- [merge](#merge)
- [getRules](#getrules)
- [ruleMerge](#rulemerge)
- [rulesFactory](#rulesfactory)
Expand Down Expand Up @@ -32,7 +33,7 @@ addons: [
{
name: '@component-controls/storybook',
options: {
webpackRules: ['instrument', 'react-props', 'react-typescript']
webpackRules: ['instrument', 'react-docgen-typescript']
}
}
],
Expand All @@ -44,11 +45,17 @@ addons: [

<!-- START-TSDOC-TYPESCRIPT -->

## merge

_defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/index.ts#L1)_



## getRules

expands the rules into webpack rules

_defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/index.ts#L29)_
_defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/index.ts#L31)_

**function** getRules(`rules`\*: [RuleType](#ruletype)\[]): [WebpackRules](#webpackrules);

Expand All @@ -61,30 +68,31 @@ _defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/

## ruleMerge

_defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/index.ts#L14)_
_defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/index.ts#L16)_

**function** ruleMerge(`dest`\*: [WebpackRules](#webpackrules), `src`\*: [WebpackRules](#webpackrules)): [RuleSetRule](#rulesetrule)\[];
**function** ruleMerge(`dest`\*: [WebpackRules](#webpackrules), `src`\*: [WebpackRules](#webpackrules)): any\[];

### parameters

| Name | Type | Description |
| --------- | ------------------------------ | ----------- |
| `dest*` | [WebpackRules](#webpackrules) | |
| `src*` | [WebpackRules](#webpackrules) | |
| `returns` | [RuleSetRule](#rulesetrule)\[] | |
| Name | Type | Description |
| --------- | ----------------------------- | ----------- |
| `dest*` | [WebpackRules](#webpackrules) | |
| `src*` | [WebpackRules](#webpackrules) | |
| `returns` | any\[] | |

## rulesFactory

_defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/index.ts#L7)_
_defined in [@component-controls/webpack-rules/src/index.ts](https://github.com/ccontrols/component-controls/tree/master/core/webpack-rules/src/index.ts#L8)_



### properties

| Name | Type | Description |
| -------------- | ------------------------------ | ----------- |
| `instrument*` | [RuleSetRule](#rulesetrule)\[] | |
| `react-props*` | [RuleSetRule](#rulesetrule)\[] | |
| Name | Type | Description |
| -------------------------- | ------------------------------ | ----------- |
| `instrument*` | [RuleSetRule](#rulesetrule)\[] | |
| `react-docgen*` | [RuleSetRule](#rulesetrule)\[] | |
| `react-docgen-typescript*` | [RuleSetRule](#rulesetrule)\[] | |

## RuleType

Expand Down
33 changes: 18 additions & 15 deletions core/webpack-rules/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import * as merge from 'deepmerge';
const merge = require('deepmerge');
import { instrument } from './instrument';
import { reactProps } from './reactProps';
import { RuleType, WebpackRules, WebpackRule } from './types';
import { reactDocgen } from './react-docgen';
import { reactDocgenTypescript } from './react-docgen-typescript';
import { RuleType, WebpackRules, WebpackRule, RuleOptions } from './types';
export * from './types';

export const rulesFactory: {
[key: string]: WebpackRules;
} = {
'react-props': reactProps,
'react-docgen-typescript': reactDocgenTypescript,
'react-docgen': reactDocgen,
instrument,
};

const ruleMerge = (dest: WebpackRules, src: WebpackRules) => {
const srcItems = src.reduce((acc: WebpackRules, item: WebpackRule) => {
const destItem = dest.find(d => d.test === item.test);
const destItem = dest.find(
d => d.test === item.test || d.loader === item.loader,
);
if (destItem) {
return [...acc, merge(destItem, item)];
}
Expand All @@ -29,24 +33,23 @@ const ruleMerge = (dest: WebpackRules, src: WebpackRules) => {
export const getRules = (rules: RuleType[]): WebpackRules => {
const result: WebpackRules = rules.reduce(
(acc: WebpackRules, rule: RuleType) => {
debugger;
if (typeof rule === 'string') {
return [...acc, ...(rulesFactory[rule] || [])];
}
if (rule && rule.rules) {
const r: WebpackRules = getRules(rule.rules);
const o: WebpackRules = rule.options as WebpackRules;
return [
...acc,
...merge<WebpackRules>(r, o, {
if (rule && (rule as RuleOptions).name) {
const name = (rule as RuleOptions).name;
if (rulesFactory[name]) {
const r: WebpackRules = getRules(rulesFactory[name]);
const o: WebpackRules = rule.rules as WebpackRules;
const merged: WebpackRules = merge(r, o, {
arrayMerge: ruleMerge,
}),
];
});
return [...acc, ...merged];
}
}
return [...acc, rule as WebpackRule];
},
[],
);
debugger;
return result;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { WebpackRules } from '../types';

export const reactProps: WebpackRules = [
export const reactDocgenTypescript: WebpackRules = [
{
test: /\.(story|stories).(js|jsx|ts|tsx|mdx)$/,
loader: '@component-controls/loader/loader',
Expand All @@ -16,7 +16,6 @@ export const reactProps: WebpackRules = [
name: '@component-controls/react-docgen-typescript-info',
test: /\.(ts|tsx)$/,
},
,
],
},
},
Expand Down
18 changes: 18 additions & 0 deletions core/webpack-rules/src/react-docgen/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { WebpackRules } from '../types';

export const reactDocgen: WebpackRules = [
{
test: /\.(story|stories).(js|jsx|ts|tsx|mdx)$/,
loader: '@component-controls/loader/loader',
exclude: [/node_modules/],
enforce: 'pre',
options: {
propsLoaders: [
{
name: '@component-controls/react-docgen-info',
test: /\.(js|jsx|ts|tsx)$/,
},
],
},
},
];
12 changes: 5 additions & 7 deletions core/webpack-rules/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ import { RuleSetRule } from 'webpack';
export type WebpackRule = RuleSetRule;
export type WebpackRules = WebpackRule[];

export type RuleType =
| WebpackRule
| string
| {
rules: RuleTypes;
options: WebpackRules;
};
export interface RuleOptions {
name: string;
rules: WebpackRules;
}
export type RuleType = WebpackRule | string | RuleOptions;

export type RuleTypes = RuleType[];
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import { Button } from 'theme-ui';
import { ControlTypes } from '@component-controls/specification';

export default {
title: 'Storybook/Starter',
component: Button,
};

interface DocsControlsTable {
Expand Down
2 changes: 1 addition & 1 deletion examples/storybook-6/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ module.exports = {
configureJSX: true,
},
},
'@component-controls/storybook'
'@component-controls/storybook',
],
};
124 changes: 42 additions & 82 deletions integrations/storybook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@

# Overview

The Storybook](<https://storybook.js.org>) integration of component-controls.
### [storybook](<https://storybook.js.org>) integration of component-controls.

<p align="center">
<img src="./images/component-controls.gif" alt="introduction to using component-controls" width="738">
</p>



### Motivation

Expand All @@ -59,17 +65,6 @@ The Storybook](<https://storybook.js.org>) integration of component-controls.
- Only handles the CSF and MDX stories format. The storeisOf API is not supported and there are currently no plans to support it.
- The Storybook MDX is a proprietary format that will be replaced in due time with a portable [frontmatter](https://www.gatsbyjs.org/docs/mdx/markdown-syntax/#frontmatter--mdx-example) stories format, similar to the CSF format.

# Storybook

The Storybook integration of component-controls allows you to define and then edit story properties dynamically in the [Storybook](https://storybook.js.org) UI with a set of property editors.

The Storybook integration started as a successor of [addon-knobs](https://github.com/storybookjs/storybook/tree/next/addons/knobs) and we have attempted to keep some level of compatibility where possible.

# Introduction

<p align="center">
<img src="./images/component-controls.gif" alt="introduction to using component-controls" width="738">
</p>

# Getting Started

Expand Down Expand Up @@ -278,90 +273,55 @@ You can see Controls in separate tabs as shown below.
<img src="./images/grouped-controls.jpg" alt="control groups" width="428">
</p>

# Storybook Docs Block

By default, Addon Controls integrates in the addon panels, in the `<Props />` table on the StoryBook DocsPage and well as in the `<Preview />` component on the DocsPage. You can also add a specifc docs block with story controls by either changing the default DocsPage or directly in your `mdx` stories:

```js
import { Title, Subtitle, Description, Story, Props, Stories } from '@storybook/addon-docs/blocks';
import { ControlsTable } from '@component-controls/storybook';


export default {
title: 'Addons/Controls/controls',
parameters: {
docs: {
page: () => (
<>
<Title />
<Subtitle />
<Description />
<Story id="." />
<ControlsTable id="." />
<Props />
<Stories />
</>
),
},
},
```
```md
import { Story, Meta } from '@storybook/addon-docs/blocks';
import { ControlsTable } from '@component-controls/storybook';

<Meta title="Storybook controls" parameters={{component: Button}} />


<Story name="small story">
{props => (
<Button {...props} />
)}
</Story>

<ControlsTable name="small story" />
# Advanced configuration options

```
# Configuration options
The storybook addon controls comes with pre-configured options that you can use for quick start, but you can also customise the options.

The storybook controls addon accepts several option parameters to customize the default functionality.
Example `.storybook/main.js`:
## Custom loader options

`.storybook/main.js`:
```js
addons: [
...
{
name: '@component-controls/storybook',

options: {
addonPanel: false,
instrument: {
//instrumentation options
prettier: {
tabWidth: 2,
},
components: {
storeSourceFile: true, //false
resolveFile: (componentName, filePath) => {
if (filePath.includes('/theme-ui/dist')) {
return `${
filePath.split('/theme-ui/dist')[0]
}/@theme-ui/components/src/${componentName}.js`;
}
return filePath;
},
},
stories: {
storeSourceFile: true, //false
},
}
},
webpackRules: [{
name: 'react-docgen-typescript',
rules: [{
loader: '@component-controls/loader/loader',
options: {
//instrumentation options
prettier: {
tabWidth: 4,
},
components: {
storeSourceFile: true, //or false
resolveFile: (componentName, filePath) => {
if (filePath.includes('/theme-ui/dist')) {
return `${
filePath.split('/theme-ui/dist')[0]
}/@theme-ui/components/src/${componentName}.js`;
}
return filePath;
},
},
stories: {
storeSourceFile: true, //or false
},
}
}],
}
],
},
],
}],
```
For more information on [InstrumentOptions](../../core/instrument/README.md#instrumentoptions)

<tsdoc-typescript entry="./src/types.ts" map="InstrumentOptions|../../core/instrument/README.md#instrumentoptions"/>
<tsdoc-typescript entry="./src/types.ts" />

<!-- START-TSDOC-TYPESCRIPT -->

Expand Down
1 change: 1 addition & 0 deletions integrations/storybook/src/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = {
},
webpackFinal: (config: any = {}, options: PresetOptions = {}) => {
const rules = getRules(options?.webpackRules || defaultRules);
debugger;
const result = {
...config,
module: {
Expand Down
2 changes: 1 addition & 1 deletion integrations/storybook/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ export interface PresetOptions {
webpackRules?: RuleTypes;
}

export const defaultRules = ['react-props'];
export const defaultRules = ['react-docgen-typescript'];

0 comments on commit cf6d001

Please sign in to comment.