Add tree shaking support for woocommerce components (https://github.com/woocommerce/woocommerce-admin/pull/7034)
* Add woocommerce/components tree shaking support * Compile individual component styles for individual use * Update readme * Add changelog * Fix correct import * Update readme with dependency extraction updates * Update dependency extraction naming
This commit is contained in:
parent
dc175824c9
commit
69dfdf733c
|
@ -115,7 +115,7 @@ function buildJsFile( file, silent ) {
|
|||
*/
|
||||
async function buildPackageScss( packagePath ) {
|
||||
const srcDir = path.resolve( packagePath, SRC_DIR );
|
||||
const scssFiles = glob.sync( `${ srcDir }/*.scss` );
|
||||
const scssFiles = glob.sync( `${ srcDir }/**/*.scss` );
|
||||
|
||||
// Build scss files individually.
|
||||
return Promise.all( scssFiles.map( ( file ) => buildScssFile( file ) ) );
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
- Fix style regression with the Chart header. #7002
|
||||
- Remove the use of Dashicons and replace with @wordpress/icons or gridicons #7020
|
||||
- Add tree shaking support to this package. #7034
|
||||
|
||||
# 6.2.0
|
||||
|
||||
|
|
|
@ -11,3 +11,24 @@ npm install @woocommerce/components --save
|
|||
```
|
||||
|
||||
View [the full Component documentation](https://woocommerce.github.io/woocommerce-admin/#/components/) for usage information.
|
||||
|
||||
## Usage
|
||||
|
||||
```jsx
|
||||
/**
|
||||
* Woocommerce dependencies
|
||||
*/
|
||||
import { Card } from '@woocommerce/components';
|
||||
|
||||
export default function MyCard() {
|
||||
return (
|
||||
<Card title="Store Performance" description="Key performance metrics">
|
||||
<p>Your stuff in a Card.</p>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Many components include CSS to add style, you will need to add in order to appear correctly. Within WooCommerce, add the `wc-components` stylesheet as a dependency of your plugin's stylesheet. See [wp_enqueue_style documentation](https://developer.wordpress.org/reference/functions/wp_enqueue_style/#parameters) for how to specify dependencies.
|
||||
|
||||
In non-WordPress projects, link to the `build-style/card/style.css` file directly, it is located at `node_modules/@woocommerce/components/build-style/<component_name>/style.css`.
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
"main": "build/index.js",
|
||||
"module": "build-module/index.js",
|
||||
"react-native": "src/index",
|
||||
"sideEffects": [
|
||||
"build-style/**",
|
||||
"src/**/*.scss"
|
||||
],
|
||||
"dependencies": {
|
||||
"@woocommerce/csv-export": "file:../csv-export",
|
||||
"@woocommerce/currency": "file:../currency",
|
||||
|
|
|
@ -10,7 +10,8 @@ import { isArray, isNumber, isString } from 'lodash';
|
|||
* @param {Array<string|Node>} components array of components
|
||||
*
|
||||
* @return {string} concatenated text content of all nodes
|
||||
*/ export function textContent( components ) {
|
||||
*/
|
||||
export function textContent( components ) {
|
||||
let text = '';
|
||||
|
||||
const toText = ( component ) => {
|
||||
|
|
|
@ -13,6 +13,8 @@ import PropTypes from 'prop-types';
|
|||
import { withViewportMatch } from '@wordpress/viewport';
|
||||
|
||||
import { validateDateInputForRange } from '@woocommerce/date';
|
||||
import 'react-dates/initialize';
|
||||
// ^^ The above: Turn on react-dates classes/styles, see https://github.com/airbnb/react-dates#initialize.
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import 'react-dates/initialize';
|
||||
// The above: Turn on react-dates classes/styles, see https://github.com/airbnb/react-dates#initialize
|
||||
|
||||
export { default as AdvancedFilters } from './advanced-filters';
|
||||
export { default as AnimationSlider } from './animation-slider';
|
||||
export { default as Chart } from './chart';
|
||||
|
|
|
@ -9,7 +9,7 @@ import PropTypes from 'prop-types';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import EllipsisMenu from '../ellipsis-menu';
|
||||
import { H } from '../section';
|
||||
import { H } from '../section/header';
|
||||
import { validateComponent } from '../lib/proptype-validator';
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { createContext } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Context container for heading level. We start at 2 because the `h1` is defined in <Header />
|
||||
*
|
||||
* See https://medium.com/@Heydon/managing-heading-levels-in-design-systems-18be9a746fa3
|
||||
*/
|
||||
const Level = createContext( 2 );
|
||||
|
||||
export { Level };
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useContext } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { Level } from './context';
|
||||
|
||||
/**
|
||||
* These components are used to frame out the page content for accessible heading hierarchy. Instead of defining fixed heading levels
|
||||
* (`h2`, `h3`, …) you can use `<H />` to create "section headings", which look to the parent `<Section />`s for the appropriate
|
||||
* heading level.
|
||||
*
|
||||
* @param {Object} props -
|
||||
* @return {Object} -
|
||||
*/
|
||||
export function H( props ) {
|
||||
const level = useContext( Level );
|
||||
|
||||
const Heading = 'h' + Math.min( level, 6 );
|
||||
return <Heading { ...props } />;
|
||||
}
|
|
@ -1,72 +1,2 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { createContext } from '@wordpress/element';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Context container for heading level. We start at 2 because the `h1` is defined in <Header />
|
||||
*
|
||||
* See https://medium.com/@Heydon/managing-heading-levels-in-design-systems-18be9a746fa3
|
||||
*/
|
||||
const Level = createContext( 2 );
|
||||
|
||||
/**
|
||||
* These components are used to frame out the page content for accessible heading hierarchy. Instead of defining fixed heading levels
|
||||
* (`h2`, `h3`, …) you can use `<H />` to create "section headings", which look to the parent `<Section />`s for the appropriate
|
||||
* heading level.
|
||||
*
|
||||
* @param {Object} props -
|
||||
* @return {Object} -
|
||||
*/
|
||||
export function H( props ) {
|
||||
return (
|
||||
<Level.Consumer>
|
||||
{ ( level ) => {
|
||||
const Heading = 'h' + Math.min( level, 6 );
|
||||
return <Heading { ...props } />;
|
||||
} }
|
||||
</Level.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The section wrapper, used to indicate a sub-section (and change the header level context).
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {string} props.component
|
||||
* @param {Node} props.children
|
||||
* @return {Object} -
|
||||
*/
|
||||
export function Section( { component, children, ...props } ) {
|
||||
const Component = component || 'div';
|
||||
return (
|
||||
<Level.Consumer>
|
||||
{ ( level ) => (
|
||||
<Level.Provider value={ level + 1 }>
|
||||
{ component === false ? (
|
||||
children
|
||||
) : (
|
||||
<Component { ...props }>{ children }</Component>
|
||||
) }
|
||||
</Level.Provider>
|
||||
) }
|
||||
</Level.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
Section.propTypes = {
|
||||
/**
|
||||
* The wrapper component for this section. Optional, defaults to `div`. If passed false, no wrapper is used. Additional props
|
||||
* passed to Section are passed on to the component.
|
||||
*/
|
||||
component: PropTypes.oneOfType( [
|
||||
PropTypes.func,
|
||||
PropTypes.string,
|
||||
PropTypes.bool,
|
||||
] ),
|
||||
/**
|
||||
* The children inside this section, rendered in the `component`. This increases the context level for the next heading used.
|
||||
*/
|
||||
children: PropTypes.node,
|
||||
};
|
||||
export { Section } from './section';
|
||||
export { H } from './header';
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { Level } from './context';
|
||||
|
||||
/**
|
||||
* The section wrapper, used to indicate a sub-section (and change the header level context).
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {string} props.component
|
||||
* @param {Node} props.children
|
||||
* @return {Object} -
|
||||
*/
|
||||
export function Section( { component, children, ...props } ) {
|
||||
const Component = component || 'div';
|
||||
return (
|
||||
<Level.Consumer>
|
||||
{ ( level ) => (
|
||||
<Level.Provider value={ level + 1 }>
|
||||
{ component === false ? (
|
||||
children
|
||||
) : (
|
||||
<Component { ...props }>{ children }</Component>
|
||||
) }
|
||||
</Level.Provider>
|
||||
) }
|
||||
</Level.Consumer>
|
||||
);
|
||||
}
|
||||
|
||||
Section.propTypes = {
|
||||
/**
|
||||
* The wrapper component for this section. Optional, defaults to `div`. If passed false, no wrapper is used. Additional props
|
||||
* passed to Section are passed on to the component.
|
||||
*/
|
||||
component: PropTypes.oneOfType( [
|
||||
PropTypes.func,
|
||||
PropTypes.string,
|
||||
PropTypes.bool,
|
||||
] ),
|
||||
/**
|
||||
* The children inside this section, rendered in the `component`. This increases the context level for the next heading used.
|
||||
*/
|
||||
children: PropTypes.node,
|
||||
};
|
|
@ -1,3 +1,7 @@
|
|||
# Unreleased
|
||||
|
||||
- Add new `bundledPackages` option to bundle in specific packages.
|
||||
|
||||
# 1.5.0
|
||||
|
||||
- Add `@woocommerce/explat` to list of packages.
|
||||
|
|
|
@ -33,3 +33,26 @@ Additional module requests on top of Wordpress [Dependency Extraction Webpack Pl
|
|||
| `@woocommerce/blocks-registry` | `wc['wcBlocksRegistry']` | `wc-blocks-registry` |
|
||||
| `@woocommerce/settings` | `wc['wcSettings']` | `wc-settings` |
|
||||
| `@woocommerce/*` | `wc['*']` | `wc-*` |
|
||||
|
||||
#### Options
|
||||
|
||||
An object can be passed to the constructor to customize the behavior, for example:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
plugins: [
|
||||
new WooCommerceDependencyExtractionWebpackPlugin( {
|
||||
bundledPackages: [ '@woocommerce/components' ],
|
||||
} ),
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
##### `bundledPackages`
|
||||
|
||||
- Type: array
|
||||
- Default: []
|
||||
|
||||
A list of potential WooCommerce excluded packages, this will include the excluded package within the bundle (example above).
|
||||
|
||||
For more supported options see the original [dependency extraction plugin](https://github.com/WordPress/gutenberg/blob/trunk/packages/dependency-extraction-webpack-plugin/README.md#options).
|
||||
|
|
|
@ -17,7 +17,7 @@ function camelCaseDash( string ) {
|
|||
return string.replace( /-([a-z])/g, ( _, letter ) => letter.toUpperCase() );
|
||||
}
|
||||
|
||||
const wooRequestToExternal = ( request ) => {
|
||||
const wooRequestToExternal = ( request, excludedExternals ) => {
|
||||
if ( packages.includes( request ) ) {
|
||||
const handle = request.substring( WOOCOMMERCE_NAMESPACE.length );
|
||||
const irregularExternalMap = {
|
||||
|
@ -25,6 +25,10 @@ const wooRequestToExternal = ( request ) => {
|
|||
settings: [ 'wc', 'wcSettings' ],
|
||||
};
|
||||
|
||||
if ( ( excludedExternals || [] ).includes( request ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( irregularExternalMap[ handle ] ) {
|
||||
return irregularExternalMap[ handle ];
|
||||
}
|
||||
|
@ -63,7 +67,10 @@ class DependencyExtractionWebpackPlugin extends WPDependencyExtractionWebpackPlu
|
|||
typeof externalRequest === 'undefined' &&
|
||||
this.options.useDefaults
|
||||
) {
|
||||
externalRequest = wooRequestToExternal( request );
|
||||
externalRequest = wooRequestToExternal(
|
||||
request,
|
||||
this.options.bundledPackages || []
|
||||
);
|
||||
}
|
||||
|
||||
if ( externalRequest ) {
|
||||
|
|
|
@ -119,7 +119,7 @@ const webpackConfig = {
|
|||
},
|
||||
{
|
||||
test: /\.s?css$/,
|
||||
exclude: /storybook\/wordpress/,
|
||||
exclude: [ /storybook\/wordpress/, /build-style\/*\/*.css/ ],
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
|
|
Loading…
Reference in New Issue