-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Package: Webpack plugin to externalize WordPress deps #31513
Conversation
What do you think about including other non- List used by Gutenberg: const externals = [
{
react: 'React',
'react-dom': 'ReactDOM',
moment: 'moment',
jquery: 'jQuery',
lodash: 'lodash',
'lodash-es': 'lodash',
// Distributed NPM packages may depend on Babel's runtime regenerator.
// In a WordPress context, the regenerator is assigned to the global
// scope via the `wp-polyfill` script. It is reassigned here as an
// externals to reduce the size of generated bundles.
//
// See: https://github.com/WordPress/gutenberg/issues/13890
'@babel/runtime/regenerator': 'regeneratorRuntime',
},
wordpressExternals,
]; |
Related naive question; should we then need to worry about aliases such as |
We should reasonably be able to cover a lot of cases and it's good to keep them in mind. It concerns me how varied lodash imports might look:
I'd like to focus on supporting the basics on a first pass. In the future we can improve this. |
3c48157
to
14148d4
Compare
b01ea5c
to
25eb15a
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Jon, awesome job! 🎉
Shall we always include
wp-polyfill
or make that an option?
Not sure. Might be fine to always include it for a first iteration and potentially add the option later if it turns out that we need it. (We'd need to add the polyfill tho before actually using the deps
files in JP, i.e. before merging Automattic/jetpack#11591.)
The
jetpack-blocks
output isn't the same and I believe it's because additional things are externed likereact
andmoment
.
I tend to agree, from a cursory glance at the diff. The blocks I've tested seem to work well -- if there's anything off, I'm confident that we'll discover it before the next release.
I tried running this plugin in the Gutenberg webpack config and it exposed some issues. I've added some hacks that make the synthetic I'd be open to more idiomatic ways of creating a chunk. Source map plugins should provide some insight, but my comprehension of webpack internals is still quite limited. To try it agains Gutenberg, you'll need to link this package ( Gutenberg patchdiff --git a/packages/scripts/config/webpack.config.js b/packages/scripts/config/webpack.config.js
index 9a1daabf5..516f6a907 100644
--- a/packages/scripts/config/webpack.config.js
+++ b/packages/scripts/config/webpack.config.js
@@ -4,54 +4,16 @@
const { BundleAnalyzerPlugin } = require( 'webpack-bundle-analyzer' );
const LiveReloadPlugin = require( 'webpack-livereload-plugin' );
const path = require( 'path' );
+const WordPressExternalDependenciesPlugin = require("@automattic/wordpress-external-dependencies-plugin");
/**
* Internal dependencies
*/
const { camelCaseDash, hasBabelConfig } = require( '../utils' );
-/**
- * Converts @wordpress/* string request into request object.
- *
- * Note this isn't the same as camel case because of the
- * way that numbers don't trigger the capitalized next letter.
- *
- * @example
- * formatRequest( '@wordpress/api-fetch' );
- * // { this: [ 'wp', 'apiFetch' ] }
- * formatRequest( '@wordpress/i18n' );
- * // { this: [ 'wp', 'i18n' ] }
- *
- * @param {string} request Request name from import statement.
- * @return {Object} Request object formatted for further processing.
- */
-const formatRequest = ( request ) => {
- // '@wordpress/api-fetch' -> [ '@wordpress', 'api-fetch' ]
- const [ , name ] = request.split( '/' );
-
- // { this: [ 'wp', 'apiFetch' ] }
- return {
- this: [ 'wp', camelCaseDash( name ) ],
- };
-};
-
-const wordpressExternals = ( context, request, callback ) => {
- if ( /^@wordpress\//.test( request ) ) {
- callback( null, formatRequest( request ), 'this' );
- } else {
- callback();
- }
-};
const externals = [
{
- react: 'React',
- 'react-dom': 'ReactDOM',
- moment: 'moment',
- jquery: 'jQuery',
- lodash: 'lodash',
- 'lodash-es': 'lodash',
-
// Distributed NPM packages may depend on Babel's runtime regenerator.
// In a WordPress context, the regenerator is assigned to the global
// scope via the `wp-polyfill` script. It is reassigned here as an
@@ -60,7 +22,6 @@ const externals = [
// See: https://github.com/WordPress/gutenberg/issues/13890
'@babel/runtime/regenerator': 'regeneratorRuntime',
},
- wordpressExternals,
];
const isProduction = process.env.NODE_ENV === 'production';
@@ -111,6 +72,7 @@ const config = {
// WP_LIVE_RELOAD_PORT global variable changes port on which live reload works
// when running watch mode.
! isProduction && new LiveReloadPlugin( { port: process.env.WP_LIVE_RELOAD_PORT || 35729 } ),
+ new WordPressExternalDependenciesPlugin(),
].filter( Boolean ),
stats: {
children: false,
|
@@ -0,0 +1,75 @@ | |||
const wpModules = new Map( [ | |||
[ 'jquery', { dependency: 'jquery', globalName: 'jQuery' } ], | |||
[ 'lodash', { dependency: 'lodash', globalName: 'lodash' } ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More lodash alternatives?
[ 'lodash', { dependency: 'lodash', globalName: 'lodash' } ], | |
[ 'lodash', { dependency: 'lodash', globalName: 'lodash' } ], | |
[ 'lodash-es', { dependency: 'lodash', globalName: 'lodash' } ], |
@@ -0,0 +1,75 @@ | |||
const wpModules = new Map( [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious to hear thoughts about this… it's practical but rigid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not generate @wordpress/
deps instead of defining each one manually, since their naming patterns are predictable and there seems to be a kind of contract that they'll remain to be so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thinking was that there are @wordpress/
packages that aren't available as script dependencies in WordPress and would need to be bundled. It may be that those packages are not for the browser and this bundler shouldn't need to worry about them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be an interesting configuration point, allow consumers to specify the elements of this map so if they're designing a plugin that exposes additional WordPress script dependencies, they can define them here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It very impractical because there will be more packages created and published and you will have to remember to update it.
I don't quite understand why you need to manually craft this list of dependencies. You probably could auto-generate it based on npm dependencies added to your |
The Gutenberg trick in particular will probably stop working as soon as some We need a better trick 🙂 |
- No static deps mapping - Better deps file generation
886550d
to
78787f7
Compare
Rebased to fix conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good and tested that this works well with SDK builder, too:
npm run sdk -- generic --global-wp packages/o2-blocks/src/editor.js ./extern-test.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually one thing I just noticed;
in this branch, building with calypso-build
gives me a new cache folder that isn't gitignored:
packages/calypso-build/.cache
Just run npx lerna run prepare --scope="*/o2-blocks"
to replicate.
I believe that's from a stale branch point. It was fixed on master by #32040. |
Confirmed, all good in |
Mostly for Automattic/jetpack#11802, which needs the package to contain #31513. Sticking with alpha versioning for a bit longer since there are a few more changes we know we'd like to get in before considering its interface somewhat stable.
Introduce a webpack plugin as described in #31486
Partly resolves Automattic/jetpack#11907
Automattic/jetpack#11591 demonstrates how the output of this plugin would be used:
Example usage:
Closes #31486
To do
wp-polyfill
or make that an option? (handle in follow-up)Testing
I've put the plugin into use for the Jetpack blocks build. The entry points like
editor.js
should produceeditor.deps.json
.npx lerna run prepare --scope="*/o2-blocks"
- is aneditor.deps.json
built to the same location aseditor.js
?.deps.json
file created for each entry point?@wordpress
,jquery
,react
,react-dom
,moment
, andlodash
deps should be externals that appear in exactly the same way as before.