Skip to content
This repository was archived by the owner on Jul 12, 2024. It is now read-only.

Conversation

@louwie17
Copy link
Contributor

@louwie17 louwie17 commented May 20, 2021

Fixes #7024

This adds tree shaking support to the @woocommerce/components package, allowing you to only bundle in the used components.
The biggest changes are the sideEffects addition in package.json, and the update in extensions/build.js to also build the style for each individual component if used outside of WooCommerce.

For the rest none of the components really looked like they had sideEffects , and I only updated a couple components that where in the same file.

No changelog as it is in the package.

Detailed test instructions:

The easiest way of testing this is by making use of the extension examples, just have to update the webpack config for it a bit:
Update the extensions/examples.config.js by setting the mode to production (enabled tree shaking) adding components to the excludedExternals list for the extraction plugin:

new WooCommerceDependencyExtractionWebpackPlugin( {
	excludedExternals: [ 'components' ],
} )

And I also had to set loose to false for the babel-loader (I had some warnings show up), and disabled minification:

optimization: {
  minimize: false,
},
  • Then build one of the examples npm run example -- --ext=add-task adding a woocommerce/components component to it somewhere. (The Spinner for example).
  • Then check the dist/index.js file to see if only the imported component and it's dependencies are added, I used a grep command:
    grep -r 'CONCATENATED MODULE: ./packages/components' docs/examples/extensions/add-task/dist
  • Enable the plugin, and see if the component renders correctly (styling will work automatically given we are within WooCommerce).
  • Now remove this line to remove the main styling: https://github.com/woocommerce/woocommerce-admin/blob/main/src/Loader.php#L420-L425
  • Add the specific component styling to the example index.scss (you might have to enqueue it as well, if it wasn't there before)
    Going with the spinner example:
    @import '../../../../../packages/components/build-style/spinner/style.css';
  • Check if the component you added is styled correctly now.

async function buildPackageScss( packagePath ) {
const srcDir = path.resolve( packagePath, SRC_DIR );
const scssFiles = glob.sync( `${ srcDir }/*.scss` );
const scssFiles = glob.sync( `${ srcDir }/**/*.scss` );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way we generate the css for the individual package components as well.

"sideEffects": [
"build-style/**",
"src/**/*.scss"
],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I stole this from @wordpress/components, but it seemed to match our use case pretty well.

* @return {string} Camel-cased string.
*/
function camelCaseDash( string ) {
return string.replace( /-([a-z])/g, ( _, letter ) => letter.toUpperCase() );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes allowed me to more easily exclude a package if needed by doing this:

new WooCommerceDependencyExtractionWebpackPlugin( {
	excludedExternals: [ 'components' ],
} ),

{
test: /\.s?css$/,
exclude: /storybook\/wordpress/,
exclude: [ /storybook\/wordpress/, /build-style\/*\/*.css/ ],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this to not include all the individual component styles as well. Not sure how much of a difference it makes (or if I did it correctly).

@louwie17 louwie17 force-pushed the dev/7024_woocommerce_components_tree_shaking branch from 87ec791 to 1c16db6 Compare May 20, 2021 19:03
# Unreleased

- Add tree shaking support to this package. #7034

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we go ahead with this we probably want to do a major release (7.0.0)

@louwie17
Copy link
Contributor Author

@samueljseay & @psealock I added both of you, given you guy's might be most interested in these changes, let me know what you think?

/**
* External dependencies
*/
import { useContext } from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be importing this from @wordpress/element

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated here: e44d096

Copy link
Contributor

@psealock psealock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to test this with a brand new plugin using npm run create-wc-extension. All of the @woocommerce/components get bundled unfortunately, but I may not be doing it right. Here are my steps, but I excluded changes to babel-loader because I didn't quite understand what was needed there.

  1. npm run create-wc-extension to get a new extension
  2. npm link the dependency extraction webpack plugin so that the new extension can get the version in this branch
  3. In my extension, npm install
  4. npm install --save @woocommerce/components
  5. npm link @woocommerce/dependency-extraction-webpack-plugin
  6. Add the new option to exclude externals excludedExternals: [ 'components' ],
  7. npm run build Build a production version

My extension's js looks like:

import { Count } from '@woocommerce/components';

console.log( Count );

Then I check the build file, build/index.js and its pretty clear all the components got included. Can you advise what steps might be missing?

}

const wooRequestToExternal = ( request ) => {
const wooRequestToExternal = ( request, excludedExternals ) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@psealock psealock May 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I think about it, this should really be upstream in Gutenberg as well https://github.com/WordPress/gutenberg/tree/trunk/packages/dependency-extraction-webpack-plugin if you want to make a PR there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify: We should keep the changes in this PR (with README updates), but also support the excludedExternals param in the original plugin within Gutenberg?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, thats right

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a PR, I will just update this PR to follow the format I went with here: WordPress/gutenberg#32220

@samueljseay samueljseay added needs: author feedback The issue/PR needs a response from any of the parties involved in the issue. and removed status: needs review labels May 24, 2021
@louwie17
Copy link
Contributor Author

louwie17 commented May 25, 2021

Then I check the build file, build/index.js and its pretty clear all the components got included. Can you advise what steps might be missing?

@psealock I just followed your steps, with the only additional step being npm link @woocommerce/components and it seem to tree shake correctly. Maybe you forgot the npm link @woocommerce/components step?
The most important addition is the sideEffects in package.json, so just see if that is there in node_modules/@woocommerce/components/package.json, if not, it didn't link correctly.

@louwie17 louwie17 force-pushed the dev/7024_woocommerce_components_tree_shaking branch 2 times, most recently from 50b649e to 221140c Compare May 25, 2021 19:31
Copy link
Contributor

@psealock psealock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you forgot the npm link @woocommerce/components step?

Yup, that was the one. Thanks @louwie17 this is testing well for me and is a big improvement for @woocommerce/components

@psealock psealock added status: ready to merge and removed needs: author feedback The issue/PR needs a response from any of the parties involved in the issue. labels May 26, 2021
@louwie17 louwie17 force-pushed the dev/7024_woocommerce_components_tree_shaking branch from 221140c to 23c2cd1 Compare May 26, 2021 17:15
@louwie17 louwie17 merged commit 84dcfd7 into main May 26, 2021
@louwie17 louwie17 deleted the dev/7024_woocommerce_components_tree_shaking branch May 26, 2021 19:35
ObliviousHarmony pushed a commit to woocommerce/woocommerce that referenced this pull request Mar 18, 2022
…ommerce-admin#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
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add tree shaking support to woocommerce/components

4 participants