Skip to content

Commit

Permalink
chore: refactor Webpack contexts in Fluent docs to improve treeshaking (
Browse files Browse the repository at this point in the history
#14843)

* chore: refactor Webpack contexts in Fluent docs to improve treeshaking

* one more chunk

* fix HMR for examples

* fix lint issue
  • Loading branch information
layershifter authored Sep 16, 2020
1 parent 4551771 commit 006119f
Show file tree
Hide file tree
Showing 16 changed files with 80 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as _ from 'lodash';
import * as PropTypes from 'prop-types';
import * as React from 'react';

import { exampleBestPracticesContext } from '../../utils';
import { exampleBestPracticesContext } from '../../contexts/exampleBestPracticesContext';
import ExampleSection from '../ComponentDoc/ExampleSection';

interface ComponentBestPracticesProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ import { ArrowDownIcon } from '@fluentui/react-icons-northstar';
import { getFormattedHash } from '../../utils';
// import ComponentDocLinks from './ComponentDocLinks'
// import ComponentDocSee from './ComponentDocSee'
import { ComponentExamples } from './ComponentExamples';
import ComponentProps from './ComponentProps';
import { ComponentDocAccessibility } from './ComponentDocAccessibility';
import { ThemeContext } from '../../context/ThemeContext';
import ExampleContext from '../../context/ExampleContext';
import { ComponentInfo } from '../../types';
import ComponentBestPractices from './ComponentBestPractices';
import * as _ from 'lodash';

const ComponentExamples = React.lazy(async () => ({
default: (await import(/* webpackChunkName: "examples-with-source" */ './ComponentExamples')).ComponentExamples,
}));
const ComponentPlayground = React.lazy(() =>
import(/* webpackChunkName: "playground" */ '../ComponentPlayground/ComponentPlayground'),
);
const ComponentBestPractices = React.lazy(() =>
import(/* webpackChunkName: "best-practices" */ './ComponentBestPractices'),
);

const exampleEndStyle: React.CSSProperties = {
textAlign: 'center',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import * as _ from 'lodash';
import * as PropTypes from 'prop-types';
import * as React from 'react';

import { exampleIndexContext, exampleSourcesContext } from '../../utils';
import { exampleIndexContext } from '../../contexts/exampleIndexContext';
import { exampleSourcesContext } from '../../contexts/exampleSourcesContext';
import { List, Segment } from '@fluentui/react-northstar';
import { componentAPIs } from './ComponentSourceManager';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from 'react';

import { ExampleSource } from '../../../types';
import { examplesContext, exampleSourcesContext } from '../../../utils';
import { examplesContext } from '../../../contexts/examplesContext';
import { exampleSourcesContext } from '../../../contexts/exampleSourcesContext';
import { componentAPIs, ComponentAPIs } from './componentAPIs';

const getExampleModule = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { KnobProvider } from '@fluentui/docs-components';
import * as _ from 'lodash';
import * as React from 'react';

import { examplePlaygroundContext } from '../../utils';
import { examplePlaygroundContext } from '../../contexts/examplePlaygroundContext';
import ComponentPlaygroundTemplate from './ComponentPlaygroundTemplate';
import usePlaygroundComponent from './usePlaygroundComponent';

Expand Down
23 changes: 6 additions & 17 deletions packages/fluentui/docs/src/components/ExternalExampleLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import * as React from 'react';
import { match } from 'react-router-dom';
import { KnobProvider } from '@fluentui/docs-components';

import { ExampleSource } from '../types';
import { exampleSourcesContext, exampleKebabNameToSourceFilename, parseExamplePath } from '../utils';
import { examplesContext } from '../contexts/examplesContext';
import PageNotFound from '../views/PageNotFound';
import { SourceRender } from './ComponentDoc/SourceRender';
import { babelConfig, importResolver } from './Playground/renderConfig';
import { exampleKebabNameToFilename, parseExamplePath } from '../utils';

const examplePaths = exampleSourcesContext.keys();
const examplePaths = examplesContext.keys();

type ExternalExampleLayoutProps = {
match: match<{
Expand All @@ -28,7 +26,6 @@ const themes = {
const ExternalExampleLayout: React.FC<ExternalExampleLayoutProps> = props => {
const { exampleName, rtl } = props.match.params;

const [error, setError] = React.useState<Error | null>(null);
const [renderId, setRenderId] = React.useState<number>(0);
const [themeName, setThemeName] = React.useState<string>();

Expand All @@ -37,26 +34,18 @@ const ExternalExampleLayout: React.FC<ExternalExampleLayoutProps> = props => {
window.switchTheme = setThemeName;
}, []);

const exampleFilename = exampleKebabNameToSourceFilename(exampleName);
const exampleFilename = exampleKebabNameToFilename(exampleName);
const examplePath = _.find(examplePaths, path => exampleFilename === parseExamplePath(path).exampleName);

if (!examplePath) return <PageNotFound />;

const exampleSource: ExampleSource = exampleSourcesContext(examplePath);
const Example: React.ElementType = examplesContext(examplePath).default;
const theme = (themeName && themes[themeName]) || {};

return (
<Provider key={renderId} theme={theme} rtl={rtl === 'true'}>
<KnobProvider>
<SourceRender
babelConfig={babelConfig}
onRender={setError}
source={exampleSource.js}
resolver={importResolver}
hot
/>
{/* This block allows to see issues with examples as visual regressions. */}
{error && <div style={{ fontSize: '5rem', color: 'red' }}>{error.toString()}</div>}
<Example />
</KnobProvider>
</Provider>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* The Webpack Context for doc site example groups.
*/
export const exampleBestPracticesContext = require.context('../examples/', true, /BestPractices.tsx$/);
4 changes: 4 additions & 0 deletions packages/fluentui/docs/src/contexts/exampleIndexContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* The Webpack Context for doc site example groups.
*/
export const exampleIndexContext = require.context('../examples/', true, /index.tsx$/);
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* The Webpack Context for component playgrounds.
*/
export const examplePlaygroundContext = require.context('../examples/', true, /Playground.tsx$/);
21 changes: 21 additions & 0 deletions packages/fluentui/docs/src/contexts/exampleSourcesContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* The Webpack Context for doc site example sources.
*/
// It's required for a hot reload
// eslint-disable-next-line import/no-mutable-exports
export let exampleSourcesContext = require.context('../exampleSources/', true, /.source.json$/);

// ----------------------------------------
// HMR
// ----------------------------------------

if (__DEV__) {
// When the application source code changes, re-render the whole thing.
if (module.hot) {
// We need this to catch cases unhandled by RHL
// https://github.com/webpack/webpack/issues/834#issuecomment-76590576
module.hot.accept(exampleSourcesContext.id, () => {
exampleSourcesContext = require.context('../exampleSources/', true, /.source.json$/);
});
}
}
21 changes: 21 additions & 0 deletions packages/fluentui/docs/src/contexts/examplesContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* The Webpack Context for doc examples.
*/
// It's required for a hot reload
// eslint-disable-next-line import/no-mutable-exports
export let examplesContext = require.context('../examples/', true, /(\w+Example(\w|\.)*|\w+.perf|\w+.bsize)\.tsx$/);

// ----------------------------------------
// HMR
// ----------------------------------------

if (__DEV__) {
// When the application source code changes, re-render the whole thing.
if (module.hot) {
// We need this to catch cases unhandled by RHL
// https://github.com/webpack/webpack/issues/834#issuecomment-76590576
module.hot.accept(examplesContext.id, () => {
examplesContext = require.context('../examples/', true, /(\w+Example(\w|\.)*|\w+.perf|\w+.bsize)\.tsx$/);
});
}
}
6 changes: 4 additions & 2 deletions packages/fluentui/docs/src/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Loader } from '@fluentui/react-northstar';
import * as React from 'react';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';

import ExternalExampleLayout from './components/ExternalExampleLayout';
import DocsLayout from './components/DocsLayout';
import DocsRoot from './components/DocsRoot';
import DocsBehaviorRoot from './components/DocsBehaviorRoot';
Expand Down Expand Up @@ -39,6 +38,10 @@ import { LazyWithBabel } from './components/ComponentDoc/LazyWithBabel';
import MenuList from './prototypes/menuList/';
import TextAreaAutoSize from './prototypes/TextAreaAutoSize';

const ExternalExampleLayout = React.lazy(() =>
import(/* webpackChunkName: "examples" */ './components/ExternalExampleLayout'),
);

const _Builder = React.lazy(async () => ({
default: (await import(/* webpackChunkName: "builder" */ '@fluentui/react-builder')).Builder,
}));
Expand All @@ -48,7 +51,6 @@ const Builder: React.FunctionComponent = () => (
<_Builder />
</LazyWithBabel>
);

const FullScreenPreview = React.lazy(async () => ({
default: (await import(/* webpackChunkName: "builder" */ '@fluentui/react-builder')).FullScreenPreview,
}));
Expand Down
46 changes: 0 additions & 46 deletions packages/fluentui/docs/src/utils/exampleContexts.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ import * as _ from 'lodash';
/**
* Converts kebab-cased-example-name back into the original filename.
*/
const exampleKebabNameToSourceFilename = (exampleKebabName: string) => {
export const exampleKebabNameToFilename = (exampleKebabName: string) => {
// button-example => ButtonExample.source.json
// button-example-shorthand => ButtonExample.shorthand.source.json
return `${_.startCase(exampleKebabName)
.replace(/ /g, '')
.replace(/Shorthand$/, '.shorthand')
.replace(/Rtl$/, '.rtl')
.replace(/Perf$/, '.perf')
.replace(/Bsize$/, '.bsize')}.source.json`;
.replace(/Bsize$/, '.bsize')}.tsx`;
};

export default exampleKebabNameToSourceFilename;
10 changes: 1 addition & 9 deletions packages/fluentui/docs/src/utils/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
export { default as componentInfoContext } from './componentInfoContext';
export {
examplesContext,
exampleIndexContext,
usageIndexContext,
exampleBestPracticesContext,
examplePlaygroundContext,
exampleSourcesContext,
} from './exampleContexts';
export { default as exampleKebabNameToSourceFilename } from './exampleKebabNameToSourceFilename';
export { exampleKebabNameToFilename } from './exampleKebabNameToFilename';
export { default as examplePathToHash } from './examplePathToHash';
export { default as getComponentGroup } from './getComponentGroup';
export { default as getComponentPathname } from './getComponentPathname';
Expand Down
1 change: 1 addition & 0 deletions scripts/webpack/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const webpackConfig: webpack.Configuration = {
alias: {
...lernaAliases(),
src: paths.packageSrc('react-northstar'),
faker: 'faker/locale/en',
'react-hook-form': 'react-hook-form/dist/react-hook-form.ie11',
},
},
Expand Down

0 comments on commit 006119f

Please sign in to comment.