* install directory-named-webpack-plugin

* create new plugin for fallback legacy imports

* implement webpack configuration for fallback legacy imports and legacy builds

Note: legacy builds are currently disabled, we can enable by just commenting out when we need them.

* removed unused webpack plugin experimented with in earlier iteration

* prettier fixes

* add legacy folder with readme for explanation

* add some info on legacy builds to `CONTRIBUTING.md`

* refactor imports to use new aliases

* fix link in doc

* update jest test config for new aliases

* use native string.startsWith instead of custom function

* reformat file for spacing/code style

* add slash to alias

* clean up webpack config and make things more dry

* update indent style for json files to be tab not spaces

- adjusts editorconfig rules
- reformat jest.config.json

* simplify conditional
This commit is contained in:
Darren Ethier 2019-10-06 08:36:15 -04:00 committed by GitHub
parent 85bcbbebd4
commit f3bd3e6a09
56 changed files with 682 additions and 376 deletions

View File

@ -22,3 +22,6 @@ trim_trailing_whitespace = false
trim_trailing_whitespace = false
indent_style = space
indent_size = 2
[*.json]
indent_style = tab

View File

@ -89,3 +89,14 @@ To release a new version, perform the following steps:
- Run `npm pack` to prep a `.tgz` file.
- Optionally test the package by uploading this onto a test site.
- Run `npm publish --access public`, which will push the version up to npm.
## Legacy builds
This plugin supports two type of builds:
- legacy builds (assets have `-legacy` suffix on their file names)
- main builds (without the `-legacy` prefix)
The legacy builds are loaded in a site environment where the WordPress version doesn't meet minimum requirements for a components used in a set build.
You can read more about legacy builds in the [this doc](./assets/js/legacy/README.md).

View File

@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import Label from '../label';
import Label from '@woocommerce/base-components/label';
import './style.scss';
export const LoadMoreButton = ( { onClick, label, screenReaderLabel } ) => {

View File

@ -7,8 +7,8 @@ import classNames from 'classnames';
/**
* Internal dependencies
*/
import Label from '../label';
import withComponentId from '../../hocs/with-component-id';
import Label from '@woocommerce/base-components/label';
import withComponentId from '@woocommerce/base-hocs/with-component-id';
import './style.scss';
/**

View File

@ -8,7 +8,7 @@ import classNames from 'classnames';
/**
* Internal dependencies
*/
import Label from '../label';
import Label from '@woocommerce/base-components/label';
import { getIndexes } from './utils.js';
import './style.scss';

View File

@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import OrderSelect from '../order-select';
import OrderSelect from '@woocommerce/base-components/order-select';
const ProductOrderSelect = ( { defaultValue, onChange, readOnly, value } ) => {
return (

View File

@ -8,7 +8,7 @@ import classNames from 'classnames';
/**
* Internal dependencies
*/
import ReadMore from '../read-more';
import ReadMore from '@woocommerce/base-components/read-more';
import './style.scss';
function getReviewImage( review, imageType, isLoading ) {

View File

@ -10,7 +10,7 @@ import {
/**
* Internal dependencies
*/
import ReviewListItem from '../review-list-item';
import ReviewListItem from '@woocommerce/base-components/review-list-item';
import './style.scss';
const ReviewList = ( { attributes, reviews } ) => {

View File

@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import OrderSelect from '../order-select';
import OrderSelect from '@woocommerce/base-components/order-select';
import './style.scss';
const ReviewOrderSelect = ( { defaultValue, onChange, readOnly, value } ) => {

View File

@ -34,9 +34,9 @@ import { MIN_HEIGHT } from '@woocommerce/block-settings';
/**
* Internal dependencies
*/
import { IconFolderStar } from '../../components/icons';
import ProductCategoryControl from '../../components/product-category-control';
import ErrorPlaceholder from '../../components/error-placeholder';
import { IconFolderStar } from '@woocommerce/block-components/icons';
import ProductCategoryControl from '@woocommerce/block-components/product-category-control';
import ErrorPlaceholder from '@woocommerce/block-components/error-placeholder';
import {
dimRatioToClass,
getBackgroundImageStyles,

View File

@ -12,7 +12,7 @@ import { DEFAULT_HEIGHT } from '@woocommerce/block-settings';
import './style.scss';
import './editor.scss';
import Block from './block';
import { IconFolderStar } from '../../components/icons';
import { IconFolderStar } from '@woocommerce/block-components/icons';
/**
* Register and run the "Featured Category" block.

View File

@ -35,14 +35,14 @@ import { MIN_HEIGHT } from '@woocommerce/block-settings';
/**
* Internal dependencies
*/
import ProductControl from '../../components/product-control';
import ErrorPlaceholder from '../../components/error-placeholder';
import ProductControl from '@woocommerce/block-components/product-control';
import ErrorPlaceholder from '@woocommerce/block-components/error-placeholder';
import { dimRatioToClass, getBackgroundImageStyles } from './utils';
import {
getImageSrcFromProduct,
getImageIdFromProduct,
} from '../../utils/products';
import { withProduct } from '../../hocs';
import { withProduct } from '@woocommerce/block-hocs';
/**
* Component to handle edit mode of "Featured Product".

View File

@ -24,10 +24,10 @@ import { MAX_COLUMNS, MIN_COLUMNS } from '@woocommerce/block-settings';
/**
* Internal dependencies
*/
import GridContentControl from '../../components/grid-content-control';
import { IconWidgets } from '../../components/icons';
import ProductsControl from '../../components/products-control';
import ProductOrderbyControl from '../../components/product-orderby-control';
import GridContentControl from '@woocommerce/block-components/grid-content-control';
import { IconWidgets } from '@woocommerce/block-components/icons';
import ProductsControl from '@woocommerce/block-components/products-control';
import ProductOrderbyControl from '@woocommerce/block-components/product-orderby-control';
/**
* Component to handle edit mode of "Hand-picked Products".

View File

@ -11,7 +11,7 @@ import { DEFAULT_COLUMNS } from '@woocommerce/block-settings';
import './editor.scss';
import Block from './block';
import { deprecatedConvertToShortcode } from '../../utils/deprecations';
import { IconWidgets } from '../../components/icons';
import { IconWidgets } from '@woocommerce/block-components/icons';
registerBlockType( 'woocommerce/handpicked-products', {
title: __( 'Hand-picked Products', 'woo-gutenberg-products-block' ),

View File

@ -10,9 +10,9 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import GridContentControl from '../../components/grid-content-control';
import GridLayoutControl from '../../components/grid-layout-control';
import ProductCategoryControl from '../../components/product-category-control';
import GridContentControl from '@woocommerce/block-components/grid-content-control';
import GridLayoutControl from '@woocommerce/block-components/grid-layout-control';
import ProductCategoryControl from '@woocommerce/block-components/product-category-control';
/**
* Component to handle edit mode of "Best Selling Products".

View File

@ -9,7 +9,7 @@ import { HOME_URL } from '@woocommerce/block-settings';
/**
* Internal dependencies
*/
import withComponentId from '../../base/hocs/with-component-id';
import withComponentId from '@woocommerce/base-hocs/with-component-id';
/**
* Component displaying the categories as dropdown or list.

View File

@ -11,9 +11,9 @@ import { PanelBody, ToggleControl, Placeholder } from '@wordpress/components';
*/
import './editor.scss';
import Block from './block.js';
import ToggleButtonControl from '../../components/toggle-button-control';
import ToggleButtonControl from '@woocommerce/block-components/toggle-button-control';
import getCategories from './get-categories';
import { IconFolder } from '../../components/icons';
import { IconFolder } from '@woocommerce/block-components/icons';
export default function( { attributes, setAttributes } ) {
const { hasCount, hasEmpty, isDropdown, isHierarchical } = attributes;

View File

@ -10,7 +10,7 @@ import { registerBlockType } from '@wordpress/blocks';
import './editor.scss';
import './style.scss';
import edit from './edit.js';
import { IconFolder } from '../../components/icons';
import { IconFolder } from '@woocommerce/block-components/icons';
registerBlockType( 'woocommerce/product-categories', {
title: __( 'Product Categories List', 'woo-gutenberg-products-block' ),

View File

@ -21,10 +21,10 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import GridContentControl from '../../components/grid-content-control';
import GridLayoutControl from '../../components/grid-layout-control';
import ProductCategoryControl from '../../components/product-category-control';
import ProductOrderbyControl from '../../components/product-orderby-control';
import GridContentControl from '@woocommerce/block-components/grid-content-control';
import GridLayoutControl from '@woocommerce/block-components/grid-layout-control';
import ProductCategoryControl from '@woocommerce/block-components/product-category-control';
import ProductOrderbyControl from '@woocommerce/block-components/product-orderby-control';
/**
* Component to handle edit mode of "Products by Category".

View File

@ -10,9 +10,9 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import GridContentControl from '../../components/grid-content-control';
import GridLayoutControl from '../../components/grid-layout-control';
import ProductCategoryControl from '../../components/product-category-control';
import GridContentControl from '@woocommerce/block-components/grid-content-control';
import GridLayoutControl from '@woocommerce/block-components/grid-layout-control';
import ProductCategoryControl from '@woocommerce/block-components/product-category-control';
/**
* Component to handle edit mode of "Newest Products".

View File

@ -10,7 +10,7 @@ import { without } from 'lodash';
*/
import Block from './block';
import { deprecatedConvertToShortcode } from '../../utils/deprecations';
import { IconNewReleases } from '../../components/icons';
import { IconNewReleases } from '@woocommerce/block-components/icons';
import sharedAttributes, {
sharedAttributeBlockTypes,
} from '../../utils/shared-attributes';

View File

@ -10,10 +10,10 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import GridContentControl from '../../components/grid-content-control';
import GridLayoutControl from '../../components/grid-layout-control';
import ProductCategoryControl from '../../components/product-category-control';
import ProductOrderbyControl from '../../components/product-orderby-control';
import GridContentControl from '@woocommerce/block-components/grid-content-control';
import GridLayoutControl from '@woocommerce/block-components/grid-layout-control';
import ProductCategoryControl from '@woocommerce/block-components/product-category-control';
import ProductOrderbyControl from '@woocommerce/block-components/product-orderby-control';
/**
* Component to handle edit mode of "On Sale Products".

View File

@ -13,7 +13,7 @@ import { deprecatedConvertToShortcode } from '../../utils/deprecations';
import sharedAttributes, {
sharedAttributeBlockTypes,
} from '../../utils/shared-attributes';
import { IconProductOnSale } from '../../components/icons';
import { IconProductOnSale } from '@woocommerce/block-components/icons';
registerBlockType( 'woocommerce/product-on-sale', {
title: __( 'On Sale Products', 'woo-gutenberg-products-block' ),

View File

@ -13,7 +13,7 @@ import { Fragment } from '@wordpress/element';
import './style.scss';
import './editor.scss';
import Block from './block.js';
import { IconProductSearch } from '../../components/icons';
import { IconProductSearch } from '@woocommerce/block-components/icons';
registerBlockType( 'woocommerce/product-search', {
title: __( 'Product Search', 'woo-gutenberg-products-block' ),

View File

@ -22,11 +22,11 @@ import { HAS_TAGS } from '@woocommerce/block-settings';
/**
* Internal dependencies
*/
import GridContentControl from '../../components/grid-content-control';
import GridLayoutControl from '../../components/grid-layout-control';
import ProductTagControl from '../../components/product-tag-control';
import ProductOrderbyControl from '../../components/product-orderby-control';
import { IconProductTag } from '../../components/icons';
import GridContentControl from '@woocommerce/block-components/grid-content-control';
import GridLayoutControl from '@woocommerce/block-components/grid-layout-control';
import ProductTagControl from '@woocommerce/block-components/product-tag-control';
import ProductOrderbyControl from '@woocommerce/block-components/product-orderby-control';
import { IconProductTag } from '@woocommerce/block-components/icons';
/**
* Component to handle edit mode of "Products by Tag".

View File

@ -10,7 +10,7 @@ import { DEFAULT_COLUMNS, DEFAULT_ROWS } from '@woocommerce/block-settings';
*/
import './editor.scss';
import Block from './block';
import { IconProductTag } from '../../components/icons';
import { IconProductTag } from '@woocommerce/block-components/icons';
/**
* Register and run the "Products by Tag" block.

View File

@ -11,9 +11,9 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import GridContentControl from '../../components/grid-content-control';
import GridLayoutControl from '../../components/grid-layout-control';
import ProductCategoryControl from '../../components/product-category-control';
import GridContentControl from '@woocommerce/block-components/grid-content-control';
import GridLayoutControl from '@woocommerce/block-components/grid-layout-control';
import ProductCategoryControl from '@woocommerce/block-components/product-category-control';
/**
* Component to handle edit mode of "Top Rated Products".

View File

@ -22,10 +22,10 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import GridContentControl from '../../components/grid-content-control';
import GridLayoutControl from '../../components/grid-layout-control';
import ProductAttributeControl from '../../components/product-attribute-control';
import ProductOrderbyControl from '../../components/product-orderby-control';
import GridContentControl from '@woocommerce/block-components/grid-content-control';
import GridLayoutControl from '@woocommerce/block-components/grid-layout-control';
import ProductAttributeControl from '@woocommerce/block-components/product-attribute-control';
import ProductOrderbyControl from '@woocommerce/block-components/product-orderby-control';
/**
* Component to handle edit mode of "Products by Attribute".

View File

@ -10,7 +10,7 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import { IconAllReviews } from '../../../components/icons';
import { IconAllReviews } from '@woocommerce/block-components/icons';
import EditorContainerBlock from '../editor-container-block.js';
import NoReviewsPlaceholder from './no-reviews-placeholder.js';
import {

View File

@ -9,7 +9,7 @@ import { registerBlockType } from '@wordpress/blocks';
*/
import '../editor.scss';
import Editor from './edit';
import { IconAllReviews } from '../../../components/icons';
import { IconAllReviews } from '@woocommerce/block-components/icons';
import sharedAttributes from '../attributes';
import save from '../save.js';

View File

@ -7,7 +7,7 @@ import { Placeholder } from '@wordpress/components';
/**
* Internal dependencies
*/
import { IconAllReviews } from '../../../components/icons';
import { IconAllReviews } from '@woocommerce/block-components/icons';
const NoCategoryReviewsPlaceholder = () => {
return (

View File

@ -18,7 +18,7 @@ import {
/**
* Internal dependencies
*/
import ToggleButtonControl from '../../components/toggle-button-control';
import ToggleButtonControl from '@woocommerce/block-components/toggle-button-control';
export const getBlockControls = ( editMode, setAttributes ) => (
<BlockControls>

View File

@ -10,11 +10,11 @@ import { ENABLE_REVIEW_RATING } from '@woocommerce/block-settings';
/**
* Internal dependencies
*/
import ErrorPlaceholder from '../../components/error-placeholder';
import LoadMoreButton from '../../base/components/load-more-button';
import ReviewList from '../../base/components/review-list';
import ReviewOrderSelect from '../../base/components/review-order-select';
import withReviews from '../../base/hocs/with-reviews';
import ErrorPlaceholder from '@woocommerce/block-components/error-placeholder';
import LoadMoreButton from '@woocommerce/base-components/load-more-button';
import ReviewList from '@woocommerce/base-components/review-list';
import ReviewOrderSelect from '@woocommerce/base-components/review-order-select';
import withReviews from '@woocommerce/base-hocs/with-reviews';
/**
* Block rendered in the editor.

View File

@ -9,10 +9,10 @@ import { ENABLE_REVIEW_RATING } from '@woocommerce/block-settings';
/**
* Internal dependencies
*/
import LoadMoreButton from '../../base/components/load-more-button';
import ReviewOrderSelect from '../../base/components/review-order-select';
import ReviewList from '../../base/components/review-list';
import withReviews from '../../base/hocs/with-reviews';
import LoadMoreButton from '@woocommerce/base-components/load-more-button';
import ReviewOrderSelect from '@woocommerce/base-components/review-order-select';
import ReviewList from '@woocommerce/base-components/review-list';
import withReviews from '@woocommerce/base-hocs/with-reviews';
/**
* Block rendered in the frontend.

View File

@ -17,8 +17,8 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import ProductCategoryControl from '../../../components/product-category-control';
import { IconReviewsByCategory } from '../../../components/icons';
import ProductCategoryControl from '@woocommerce/block-components/product-category-control';
import { IconReviewsByCategory } from '@woocommerce/block-components/icons';
import EditorContainerBlock from '../editor-container-block.js';
import NoReviewsPlaceholder from './no-reviews-placeholder.js';
import {

View File

@ -9,7 +9,7 @@ import { registerBlockType } from '@wordpress/blocks';
*/
import '../editor.scss';
import Editor from './edit';
import { IconReviewsByCategory } from '../../../components/icons';
import { IconReviewsByCategory } from '@woocommerce/block-components/icons';
import sharedAttributes from '../attributes';
import save from '../save.js';

View File

@ -7,7 +7,7 @@ import { Placeholder } from '@wordpress/components';
/**
* Internal dependencies
*/
import { IconReviewsByCategory } from '../../../components/icons';
import { IconReviewsByCategory } from '@woocommerce/block-components/icons';
const NoReviewsPlaceholder = () => {
return (

View File

@ -16,8 +16,8 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import ProductControl from '../../../components/product-control';
import { IconReviewsByProduct } from '../../../components/icons';
import ProductControl from '@woocommerce/block-components/product-control';
import { IconReviewsByProduct } from '@woocommerce/block-components/icons';
import EditorContainerBlock from '../editor-container-block.js';
import NoReviewsPlaceholder from './no-reviews-placeholder.js';
import {

View File

@ -9,7 +9,7 @@ import { registerBlockType } from '@wordpress/blocks';
*/
import '../editor.scss';
import Editor from './edit';
import { IconReviewsByProduct } from '../../../components/icons';
import { IconReviewsByProduct } from '@woocommerce/block-components/icons';
import sharedAttributes from '../attributes';
import save from '../save.js';

View File

@ -8,9 +8,9 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import ErrorPlaceholder from '../../../components/error-placeholder';
import { IconReviewsByProduct } from '../../../components/icons';
import { withProduct } from '../../../hocs';
import ErrorPlaceholder from '@woocommerce/block-components/error-placeholder';
import { IconReviewsByProduct } from '@woocommerce/block-components/icons';
import { withProduct } from '@woocommerce/block-hocs';
const NoReviewsPlaceholder = ( { error, getProduct, isLoading, product } ) => {
const renderApiError = () => (

View File

@ -11,8 +11,8 @@ import { SelectControl, Spinner } from '@wordpress/components';
/**
* Internal dependencies
*/
import { withAttributes } from '../../hocs';
import ErrorMessage from '../error-placeholder/error-message.js';
import { withAttributes } from '@woocommerce/block-hocs';
import ErrorMessage from '@woocommerce/block-components/error-placeholder/error-message.js';
import './style.scss';
const ProductAttributeControl = ( {

View File

@ -11,8 +11,8 @@ import { SelectControl } from '@wordpress/components';
/**
* Internal dependencies
*/
import { withCategories } from '../../hocs';
import ErrorMessage from '../error-placeholder/error-message.js';
import { withCategories } from '@woocommerce/block-hocs';
import ErrorMessage from '@woocommerce/block-components/error-placeholder/error-message.js';
import './style.scss';
const ProductCategoryControl = ( {

View File

@ -11,13 +11,16 @@ import {
withProductVariations,
withSearchedProducts,
withTransformSingleSelectToMultipleSelect,
} from '../../hocs';
} from '@woocommerce/block-hocs';
/**
* Internal dependencies
*/
import { IconRadioSelected, IconRadioUnselected } from '../icons';
import ErrorMessage from '../error-placeholder/error-message.js';
import {
IconRadioSelected,
IconRadioUnselected,
} from '@woocommerce/block-components/icons';
import ErrorMessage from '@woocommerce/block-components/error-placeholder/error-message.js';
import './style.scss';
function getHighlightedName( name, search ) {

View File

@ -8,8 +8,8 @@ import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import { withSearchedProducts } from '../../hocs';
import ErrorMessage from '../error-placeholder/error-message.js';
import { withSearchedProducts } from '@woocommerce/block-hocs';
import ErrorMessage from '@woocommerce/block-components/error-placeholder/error-message.js';
/**
* The products control exposes a custom selector for searching and selecting

View File

@ -9,7 +9,7 @@ import { debounce } from 'lodash';
/**
* Internal dependencies
*/
import { getAttributes, getTerms } from '../components/utils';
import { getAttributes, getTerms } from '@woocommerce/block-components/utils';
import { formatError } from '../base/utils/errors.js';
const withAttributes = createHigherOrderComponent( ( OriginalComponent ) => {

View File

@ -7,7 +7,7 @@ import { createHigherOrderComponent } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { getCategories } from '../components/utils';
import { getCategories } from '@woocommerce/block-components/utils';
import { formatError } from '../base/utils/errors.js';
const withCategories = createHigherOrderComponent( ( OriginalComponent ) => {

View File

@ -7,7 +7,7 @@ import { createHigherOrderComponent } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { getCategory } from '../components/utils';
import { getCategory } from '@woocommerce/block-components/utils';
import { formatError } from '../base/utils/errors.js';
const withCategory = createHigherOrderComponent( ( OriginalComponent ) => {

View File

@ -9,7 +9,7 @@ import isShallowEqual from '@wordpress/is-shallow-equal';
/**
* Internal dependencies
*/
import { getProductVariations } from '../components/utils';
import { getProductVariations } from '@woocommerce/block-components/utils';
import { formatError } from '../base/utils/errors.js';
const withProductVariations = createHigherOrderComponent(

View File

@ -7,7 +7,7 @@ import { createHigherOrderComponent } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { getProduct } from '../components/utils';
import { getProduct } from '@woocommerce/block-components/utils';
import { formatError } from '../base/utils/errors.js';
const withProduct = createHigherOrderComponent( ( OriginalComponent ) => {

View File

@ -10,7 +10,7 @@ import { IS_LARGE_CATALOG } from '@woocommerce/block-settings';
/**
* Internal dependencies
*/
import { getProducts } from '../components/utils';
import { getProducts } from '@woocommerce/block-components/utils';
import { formatError } from '../base/utils/errors.js';
/**

View File

@ -0,0 +1,52 @@
This folder is used to hold any components/code that will get exported to the
legacy build.
> Currently, builds in this folder target WP < 5.3
When you add a file, add it in the same folder structure as the root.
So for example, if the original file was in:
`assets/js/base/components/label/index.js`
Then the legacy version will be located in:
`assets/js/legacy/base/components/label/index.js`
Note: you _must_ copy all files related to the entry point for that module according to the path aliased.
Legacy builds will be identical to the main builds except:
- files will have a `-legacy` suffix (so server can conditionally enqueue). It is expected that the server will load either the main or the legacy bundles, not both.
- any imports not in the legacy folder will fallback to the main file.
## How does the legacy system work?
Short answer, through the magic of WebPack! Long answer:
### A. Aliases
We use aliases for paths covering anything that might need a legacy version. Then we have a dedicated builds for main and legacy code.
Current aliases are:
- `@woocommerce/base-components` -> `assets/js/base/components/`
- `@woocommerce/base-hocs` -> `assets/js/base/hocs/`
- `@woocommerce/block-components` -> `assets/js/components`
- `@woocommerce/block-hocs` -> `assets/js/block-hocs`
When importing, if outside the module referenced by that path, import from the alias. That will ensure that at compile time the bundles can pull from the appropriate location.
Example:
```js
// will pull from '/assets/js/base/components/label/index.js in the main build
// will pull from '/assets/js/legacy/base/components/label/index.js in the legacy
// build.
import { Label } from '@woocommerce/base-components/label';
```
### B. Webpack Plugin
The second part of the webpack magic is a custom plugin. Located in `bin/fallback-module-directory-webpack-plugin.js`, this custom plugin is used instead of the default Alias plugin. It handles trying a fallback if the original path aliased to does not exist. The fallback is a variation of the aliased path using the provided `search` and `replace` strings when instantiating the plugin. You can see it setup in the `LegacyBlocksConfig.resolve.plugins` property of the `webpack.config.js` file.

View File

@ -0,0 +1,118 @@
/*eslint-env node*/
/**
* External dependencies
*/
const fs = require( 'fs' );
// Note, this has some inspiration from the AliasPlugin and its implementation
// @see https://github.com/webpack/enhanced-resolve/blob/v4.1.0/lib/AliasPlugin.js
module.exports = class FallbackModuleDirectoryWebpackPlugin {
constructor( search, replacement, alias ) {
this.search = search;
this.replacement = replacement;
this.alias = this.parseAlias( alias );
this.hooks = [
[ 'described-resolve', 'resolve' ],
[ 'file', 'resolve' ],
];
this.applyFallback = this.applyFallback.bind( this );
this.doApply = this.doApply.bind( this );
}
parseAlias( alias ) {
if ( typeof alias === 'object' && ! Array.isArray( alias ) ) {
alias = Object.keys( alias ).map( ( key ) => {
let onlyModule = false;
let obj = alias[ key ];
if ( /\$$/.test( key ) ) {
onlyModule = true;
key = key.substr( 0, key.length - 1 );
}
if ( typeof obj === 'string' ) {
obj = {
alias: obj,
};
}
obj = Object.assign(
{
name: key,
onlyModule,
},
obj
);
return obj;
} );
}
return alias;
}
applyFallback( path ) {
if ( path.includes( this.search ) && ! fs.existsSync( path ) ) {
return path.replace( this.search, this.replacement );
}
return path;
}
doApply( resolver, source, target, alias ) {
resolver
.getHook( source )
.tapAsync(
'FallbackModuleDirectoryWebpackPlugin',
( request, resolveContext, callback ) => {
const innerRequest = request.request || request.path;
if ( ! innerRequest ) return callback();
for ( const item of alias ) {
if (
innerRequest === item.name ||
( ! item.onlyModule &&
innerRequest.startsWith( item.name + '/' ) )
) {
if (
innerRequest !== item.alias &&
! innerRequest.startsWith( item.alias + '/' )
) {
const newRequestStr = this.applyFallback(
item.alias +
innerRequest.substr( item.name.length )
);
const obj = {
...request,
request: newRequestStr,
};
return resolver.doResolve(
target,
obj,
`aliased with mapping '${
item.name
}' to '${ newRequestStr }'`,
resolveContext,
( err, result ) => {
if ( err ) return callback( err );
// Don't allow other aliasing or raw request
if ( result === undefined ) {
return callback( null, null );
}
callback( null, result );
}
);
}
}
}
return callback();
}
);
}
apply( resolver ) {
const alias = this.alias;
this.hooks.forEach( ( [ source, target ] ) => {
target = resolver.ensureHook( target );
this.doApply( resolver, source, target, alias );
} );
}
};

View File

@ -0,0 +1,328 @@
/**
* External dependencies
*/
const path = require( 'path' );
const MergeExtractFilesPlugin = require( './merge-extract-files-webpack-plugin' );
const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' );
const ProgressBarPlugin = require( 'progress-bar-webpack-plugin' );
const DependencyExtractionWebpackPlugin = require( '@wordpress/dependency-extraction-webpack-plugin' );
const WebpackRTLPlugin = require( 'webpack-rtl-plugin' );
const chalk = require( 'chalk' );
const NODE_ENV = process.env.NODE_ENV || 'development';
function findModuleMatch( module, match ) {
if ( module.request && match.test( module.request ) ) {
return true;
} else if ( module.issuer ) {
return findModuleMatch( module.issuer, match );
}
return false;
}
const requestToExternal = ( request ) => {
const wcDepMap = {
'@woocommerce/settings': [ 'wc', 'wcSettings' ],
};
if ( wcDepMap[ request ] ) {
return wcDepMap[ request ];
}
};
const requestToHandle = ( request ) => {
const wcHandleMap = {
'@woocommerce/settings': 'wc-settings',
'@woocommerce/block-settings': 'wc-settings',
};
if ( wcHandleMap[ request ] ) {
return wcHandleMap[ request ];
}
};
const getAlias = ( options = {} ) => {
let { pathPart } = options;
pathPart = pathPart ? `${ pathPart }/` : '';
return {
'@woocommerce/block-settings': path.resolve(
__dirname,
'../assets/js/settings/blocks'
),
'@woocommerce/base-components': path.resolve(
__dirname,
`../assets/js/${ pathPart }base/components/`
),
'@woocommerce/base-hocs': path.resolve(
__dirname,
`../assets/js/${ pathPart }base/hocs/`
),
'@woocommerce/block-components': path.resolve(
__dirname,
`../assets/js/${ pathPart }components/`
),
'@woocommerce/block-hocs': path.resolve(
__dirname,
`../assets/js/${ pathPart }hocs`
),
};
};
const getMainConfig = ( options = {} ) => {
let { fileSuffix } = options;
const { alias, resolvePlugins = [] } = options;
fileSuffix = fileSuffix ? `-${ fileSuffix }` : '';
const resolve = alias
? {
alias,
plugins: resolvePlugins,
}
: {
plugins: resolvePlugins,
};
return {
entry: {
// Shared blocks code
blocks: './assets/js/index.js',
// Blocks
'handpicked-products':
'./assets/js/blocks/handpicked-products/index.js',
'product-best-sellers':
'./assets/js/blocks/product-best-sellers/index.js',
'product-category': './assets/js/blocks/product-category/index.js',
'product-categories':
'./assets/js/blocks/product-categories/index.js',
'product-new': './assets/js/blocks/product-new/index.js',
'product-on-sale': './assets/js/blocks/product-on-sale/index.js',
'product-top-rated':
'./assets/js/blocks/product-top-rated/index.js',
'products-by-attribute':
'./assets/js/blocks/products-by-attribute/index.js',
'featured-product': './assets/js/blocks/featured-product/index.js',
'all-reviews': './assets/js/blocks/reviews/all-reviews/index.js',
'reviews-by-product':
'./assets/js/blocks/reviews/reviews-by-product/index.js',
'reviews-by-category':
'./assets/js/blocks/reviews/reviews-by-category/index.js',
'product-search': './assets/js/blocks/product-search/index.js',
'product-tag': './assets/js/blocks/product-tag/index.js',
'featured-category':
'./assets/js/blocks/featured-category/index.js',
},
output: {
path: path.resolve( __dirname, '../build/' ),
filename: `[name]${ fileSuffix }.js`,
library: [ 'wc', 'blocks', '[name]' ],
libraryTarget: 'this',
// This fixes an issue with multiple webpack projects using chunking
// overwriting each other's chunk loader function.
// See https://webpack.js.org/configuration/output/#outputjsonpfunction
jsonpFunction: 'webpackWcBlocksJsonp',
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
enforce: true,
},
editor: {
// Capture all `editor` stylesheets and the components stylesheets.
test: ( module = {} ) =>
module.constructor.name === 'CssModule' &&
( findModuleMatch( module, /editor\.scss$/ ) ||
findModuleMatch(
module,
/[\\/]assets[\\/]components[\\/]/
) ),
name: 'editor',
chunks: 'all',
priority: 10,
},
style: {
test: /style\.scss$/,
name: 'style',
chunks: 'all',
priority: 5,
},
},
},
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader?cacheDirectory',
options: {
presets: [ '@wordpress/babel-preset-default' ],
plugins: [
NODE_ENV === 'production'
? require.resolve(
'babel-plugin-transform-react-remove-prop-types'
)
: false,
require.resolve(
'@babel/plugin-proposal-class-properties'
),
].filter( Boolean ),
},
},
},
{
test: /\.s[c|a]ss$/,
use: [
'style-loader',
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader',
{
loader: 'sass-loader',
query: {
includePaths: [ 'assets/css/abstracts' ],
data:
'@import "_colors"; ' +
'@import "_variables"; ' +
'@import "_breakpoints"; ' +
'@import "_mixins"; ',
},
},
],
},
],
},
plugins: [
new WebpackRTLPlugin( {
filename: `[name]${ fileSuffix }-rtl.css`,
minify: {
safe: true,
},
} ),
new MiniCssExtractPlugin( {
filename: `[name]${ fileSuffix }.css`,
} ),
new MergeExtractFilesPlugin(
[ 'build/editor.js', 'build/style.js' ],
'build/vendors.js'
),
new ProgressBarPlugin( {
format:
chalk.blue( 'Build' ) +
' [:bar] ' +
chalk.green( ':percent' ) +
' :msg (:elapsed seconds)',
} ),
new DependencyExtractionWebpackPlugin( {
injectPolyfill: true,
requestToExternal,
requestToHandle,
} ),
],
resolve,
};
};
const getFrontConfig = ( options = {} ) => {
let { fileSuffix } = options;
const { alias, resolvePlugins = [] } = options;
fileSuffix = fileSuffix ? `-${ fileSuffix }` : '';
const resolve = alias
? {
alias,
plugins: resolvePlugins,
}
: {
plugins: resolvePlugins,
};
return {
entry: {
'product-categories':
'./assets/js/blocks/product-categories/frontend.js',
reviews: './assets/js/blocks/reviews/frontend.js',
},
output: {
path: path.resolve( __dirname, '../build/' ),
filename: `[name]${ fileSuffix }-frontend.js`,
// This fixes an issue with multiple webpack projects using chunking
// overwriting each other's chunk loader function.
// See https://webpack.js.org/configuration/output/#outputjsonpfunction
jsonpFunction: 'webpackWcBlocksJsonp',
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader?cacheDirectory',
options: {
presets: [
[
'@babel/preset-env',
{
modules: false,
targets: {
browsers: [
'extends @wordpress/browserslist-config',
],
},
},
],
],
plugins: [
require.resolve(
'@babel/plugin-proposal-object-rest-spread'
),
require.resolve(
'@babel/plugin-transform-react-jsx'
),
require.resolve(
'@babel/plugin-proposal-async-generator-functions'
),
require.resolve(
'@babel/plugin-transform-runtime'
),
require.resolve(
'@babel/plugin-proposal-class-properties'
),
NODE_ENV === 'production'
? require.resolve(
'babel-plugin-transform-react-remove-prop-types'
)
: false,
].filter( Boolean ),
},
},
},
{
test: /\.s[c|a]ss$/,
use: {
loader: 'ignore-loader',
},
},
],
},
plugins: [
new ProgressBarPlugin( {
format:
chalk.blue( 'Build frontend scripts' ) +
' [:bar] ' +
chalk.green( ':percent' ) +
' :msg (:elapsed seconds)',
} ),
new DependencyExtractionWebpackPlugin( {
injectPolyfill: true,
requestToExternal,
requestToHandle,
} ),
],
resolve,
};
};
module.exports = {
getAlias,
getFrontConfig,
getMainConfig,
};

View File

@ -4104,7 +4104,7 @@
},
"util": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
"resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
"dev": true,
"requires": {
@ -5489,7 +5489,7 @@
},
"browserify-aes": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"dev": true,
"requires": {
@ -5526,7 +5526,7 @@
},
"browserify-rsa": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true,
"requires": {
@ -5586,7 +5586,7 @@
},
"buffer": {
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"dev": true,
"requires": {
@ -5760,7 +5760,7 @@
"dependencies": {
"callsites": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
"resolved": "http://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
"dev": true
}
@ -6517,7 +6517,7 @@
},
"create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true,
"requires": {
@ -6530,7 +6530,7 @@
},
"create-hmac": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true,
"requires": {
@ -7253,7 +7253,7 @@
},
"diffie-hellman": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"dev": true,
"requires": {
@ -9528,7 +9528,7 @@
},
"gettext-parser": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz",
"resolved": "http://registry.npmjs.org/gettext-parser/-/gettext-parser-1.4.0.tgz",
"integrity": "sha512-sedZYLHlHeBop/gZ1jdg59hlUEcpcZJofLq2JFwJT1zTqAU3l2wFv6IsuwFHGqbiT9DWzMUW4/em2+hspnmMMA==",
"requires": {
"encoding": "^0.1.12",
@ -10725,7 +10725,7 @@
},
"is-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"dev": true
},
@ -13157,7 +13157,7 @@
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
@ -14045,7 +14045,7 @@
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
"dev": true
},
@ -14106,7 +14106,7 @@
},
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
"dev": true
},
@ -14299,7 +14299,7 @@
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
@ -16307,7 +16307,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true,
"requires": {
@ -16918,7 +16918,7 @@
},
"safe-regex": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"dev": true,
"requires": {
@ -17393,7 +17393,7 @@
},
"sha.js": {
"version": "2.4.11",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dev": true,
"requires": {
@ -18099,7 +18099,7 @@
},
"strip-eof": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
"dev": true
},
@ -20330,7 +20330,7 @@
},
"wrap-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"dev": true,
"requires": {

View File

@ -6,19 +6,27 @@
"!**/vendor/**",
"!**/test/**"
],
"moduleDirectories": [ "node_modules" ],
"moduleDirectories": [
"node_modules"
],
"moduleNameMapper": {
"@woocommerce/settings": "assets/js/settings/shared",
"@woocommerce/block-settings": "assets/js/settings/blocks"
"@woocommerce/block-settings": "assets/js/settings/blocks",
"@woocommerce/block-components(.*)$": "assets/js/components/$1",
"@woocommerce/block-hocs(.*)$": "assets/js/hocs/$1",
"@woocommerce/base-components(.*)$": "assets/js/base/components/$1",
"@woocommerce/base-hocs(.*)$": "assets/js/base/hocs/$1"
},
"setupFiles": [
"<rootDir>/node_modules/@wordpress/jest-preset-default/scripts/setup-globals.js",
"<rootDir>/tests/js/setup-globals"
],
"transformIgnorePatterns": [ "node_modules/(?!(simple-html-tokenizer)/)" ],
"transformIgnorePatterns": [
"node_modules/(?!(simple-html-tokenizer)/)"
],
"preset": "@wordpress/jest-preset-default",
"transform": {
"^.+\\.js$": "<rootDir>/tests/js/jestPreprocess.js"
},
"verbose": true
}
}

View File

@ -3,23 +3,17 @@
*/
const path = require( 'path' );
const { kebabCase } = require( 'lodash' );
const MergeExtractFilesPlugin = require( './bin/merge-extract-files-webpack-plugin' );
const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' );
const { CleanWebpackPlugin } = require( 'clean-webpack-plugin' );
const ProgressBarPlugin = require( 'progress-bar-webpack-plugin' );
const DependencyExtractionWebpackPlugin = require( '@wordpress/dependency-extraction-webpack-plugin' );
const chalk = require( 'chalk' );
const NODE_ENV = process.env.NODE_ENV || 'development';
const WebpackRTLPlugin = require( 'webpack-rtl-plugin' );
function findModuleMatch( module, match ) {
if ( module.request && match.test( module.request ) ) {
return true;
} else if ( module.issuer ) {
return findModuleMatch( module.issuer, match );
}
return false;
}
const FallbackModuleDirectoryPlugin = require( './bin/fallback-module-directory-webpack-plugin' );
const {
getAlias,
getMainConfig,
getFrontConfig,
} = require( './bin/webpack-helpers.js' );
const baseConfig = {
mode: NODE_ENV,
@ -37,32 +31,6 @@ const baseConfig = {
},
};
const alias = {
'@woocommerce/block-settings': path.resolve(
__dirname,
'assets/js/settings/blocks'
),
};
const requestToExternal = ( request ) => {
const wcDepMap = {
'@woocommerce/settings': [ 'wc', 'wcSettings' ],
};
if ( wcDepMap[ request ] ) {
return wcDepMap[ request ];
}
};
const requestToHandle = ( request ) => {
const wcHandleMap = {
'@woocommerce/settings': 'wc-settings',
'@woocommerce/block-settings': 'wc-settings',
};
if ( wcHandleMap[ request ] ) {
return wcHandleMap[ request ];
}
};
const CoreConfig = {
...baseConfig,
entry: {
@ -107,235 +75,50 @@ const CoreConfig = {
],
};
/**
* Config for compiling Gutenberg blocks JS.
*/
const GutenbergBlocksConfig = {
...baseConfig,
entry: {
// Shared blocks code
blocks: './assets/js/index.js',
// Blocks
'handpicked-products':
'./assets/js/blocks/handpicked-products/index.js',
'product-best-sellers':
'./assets/js/blocks/product-best-sellers/index.js',
'product-category': './assets/js/blocks/product-category/index.js',
'product-categories': './assets/js/blocks/product-categories/index.js',
'product-new': './assets/js/blocks/product-new/index.js',
'product-on-sale': './assets/js/blocks/product-on-sale/index.js',
'product-top-rated': './assets/js/blocks/product-top-rated/index.js',
'products-by-attribute':
'./assets/js/blocks/products-by-attribute/index.js',
'featured-product': './assets/js/blocks/featured-product/index.js',
'all-reviews': './assets/js/blocks/reviews/all-reviews/index.js',
'reviews-by-product':
'./assets/js/blocks/reviews/reviews-by-product/index.js',
'reviews-by-category':
'./assets/js/blocks/reviews/reviews-by-category/index.js',
'product-search': './assets/js/blocks/product-search/index.js',
'product-tag': './assets/js/blocks/product-tag/index.js',
'featured-category': './assets/js/blocks/featured-category/index.js',
},
output: {
path: path.resolve( __dirname, './build/' ),
filename: '[name].js',
library: [ 'wc', 'blocks', '[name]' ],
libraryTarget: 'this',
// This fixes an issue with multiple webpack projects using chunking
// overwriting each other's chunk loader function.
// See https://webpack.js.org/configuration/output/#outputjsonpfunction
jsonpFunction: 'webpackWcBlocksJsonp',
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
enforce: true,
},
editor: {
// Capture all `editor` stylesheets and the components stylesheets.
test: ( module = {} ) =>
module.constructor.name === 'CssModule' &&
( findModuleMatch( module, /editor\.scss$/ ) ||
findModuleMatch(
module,
/[\\/]assets[\\/]components[\\/]/
) ),
name: 'editor',
chunks: 'all',
priority: 10,
},
style: {
test: /style\.scss$/,
name: 'style',
chunks: 'all',
priority: 5,
},
},
},
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader?cacheDirectory',
options: {
presets: [ '@wordpress/babel-preset-default' ],
plugins: [
NODE_ENV === 'production'
? require.resolve(
'babel-plugin-transform-react-remove-prop-types'
)
: false,
require.resolve(
'@babel/plugin-proposal-class-properties'
),
].filter( Boolean ),
},
},
},
{
test: /\.s[c|a]ss$/,
use: [
'style-loader',
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader',
{
loader: 'sass-loader',
query: {
includePaths: [ 'assets/css/abstracts' ],
data:
'@import "_colors"; ' +
'@import "_variables"; ' +
'@import "_breakpoints"; ' +
'@import "_mixins"; ',
},
},
],
},
...getMainConfig( { alias: getAlias() } ),
};
// eslint-disable-next-line no-unused-vars
const LegacyBlocksConfig = {
...baseConfig,
...getMainConfig( {
fileSuffix: 'legacy',
resolvePlugins: [
new FallbackModuleDirectoryPlugin(
'/legacy/',
'/',
getAlias( { pathPart: 'legacy' } )
),
],
},
plugins: [
new WebpackRTLPlugin( {
filename: '[name]-rtl.css',
minify: {
safe: true,
},
} ),
new MiniCssExtractPlugin( {
filename: '[name].css',
} ),
new MergeExtractFilesPlugin(
[ 'build/editor.js', 'build/style.js' ],
'build/vendors.js'
),
new ProgressBarPlugin( {
format:
chalk.blue( 'Build' ) +
' [:bar] ' +
chalk.green( ':percent' ) +
' :msg (:elapsed seconds)',
} ),
new DependencyExtractionWebpackPlugin( {
injectPolyfill: true,
requestToExternal,
requestToHandle,
} ),
],
resolve: { alias },
} ),
};
const BlocksFrontendConfig = {
...baseConfig,
entry: {
'product-categories':
'./assets/js/blocks/product-categories/frontend.js',
reviews: './assets/js/blocks/reviews/frontend.js',
},
output: {
path: path.resolve( __dirname, './build/' ),
filename: '[name]-frontend.js',
// This fixes an issue with multiple webpack projects using chunking
// overwriting each other's chunk loader function.
// See https://webpack.js.org/configuration/output/#outputjsonpfunction
jsonpFunction: 'webpackWcBlocksJsonp',
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader?cacheDirectory',
options: {
presets: [
[
'@babel/preset-env',
{
modules: false,
targets: {
browsers: [
'extends @wordpress/browserslist-config',
],
},
},
],
],
plugins: [
require.resolve(
'@babel/plugin-proposal-object-rest-spread'
),
require.resolve(
'@babel/plugin-transform-react-jsx'
),
require.resolve(
'@babel/plugin-proposal-async-generator-functions'
),
require.resolve(
'@babel/plugin-transform-runtime'
),
require.resolve(
'@babel/plugin-proposal-class-properties'
),
NODE_ENV === 'production'
? require.resolve(
'babel-plugin-transform-react-remove-prop-types'
)
: false,
].filter( Boolean ),
},
},
},
{
test: /\.s[c|a]ss$/,
use: {
loader: 'ignore-loader',
},
},
],
},
plugins: [
new ProgressBarPlugin( {
format:
chalk.blue( 'Build frontend scripts' ) +
' [:bar] ' +
chalk.green( ':percent' ) +
' :msg (:elapsed seconds)',
} ),
new DependencyExtractionWebpackPlugin( {
injectPolyfill: true,
requestToExternal,
requestToHandle,
} ),
],
resolve: { alias },
...getFrontConfig( { alias: getAlias() } ),
};
module.exports = [ CoreConfig, GutenbergBlocksConfig, BlocksFrontendConfig ];
// eslint-disable-next-line no-unused-vars
const LegacyFrontendBlocksConfig = {
...baseConfig,
...getFrontConfig( {
fileSuffix: 'legacy',
resolvePlugins: [
new FallbackModuleDirectoryPlugin(
'/legacy/',
'/',
getAlias( { pathPart: 'legacy' } )
),
],
} ),
};
module.exports = [
CoreConfig,
GutenbergBlocksConfig,
BlocksFrontendConfig,
// LegacyBlocksConfig,
// LegacyFrontendBlocksConfig,
];