Skip to content
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

Conflict with externals #42

Open
kucrut opened this issue Jan 29, 2020 · 4 comments
Open

Conflict with externals #42

kucrut opened this issue Jan 29, 2020 · 4 comments
Milestone

Comments

@kucrut
Copy link

kucrut commented Jan 29, 2020

The way externals are currently defined makes it impossible for to export own's library to the global this.

Example config:

module.exports = {
	// ...
	name: 'myPlugin',
	entry: {
		components: filePath( 'assets/src/components/index.js' ),
		dashboard: filePath( 'assets/src/dashboard.js' ),
		preview: filePath( 'assets/src/preview.js' ),
	},
	output: {
		library: [ 'myPlugin', '[name]' ],
		libraryTarget: 'this',
		path: filePath( '/assets/dist/' ),
	},
	resolve: {
		alias: {
			'@myPlugin/components': filePath( '/assets/src/components/' ),
		},
	},
};

The intention was to make the entrypoints available under this.myPlugin object. However, since webpack helpers defined the externals differently, they're overriden by this config.

From webpack docs:

Note that not setting a output.library will cause all properties returned by the entry point to be assigned to the given object; there are no checks against existing property names.

One possible solution is to update externals definition to:

[ `@wordpress/${ name }` ]: { this: [ 'wp', camelCaseDash( name ) ] }
@kadamwhite
Copy link
Contributor

@kucrut Rereading the Webpack docs, it looks like the this or root options of the externals definition object would only apply if that libraryTarget is in use. If I'm understanding what that means correctly, then, it seems like it would be very verbose to enumerate every variant in our externals config.

Given that this was originally conceived of as a solution for the majority of cases, which covers theme and plugins bundles but does not necessarily include library targets (yet anyway), what would you think about leaving things as is but providing this guidance around how to handle it if you are targeting a library:

const { externals: originalExternals } = require( '@humanmade/webpack-helpers' );

// Remap externals to { this: [ 'wp', 'packageName' ] } format for library use.
const externals = Object.keys( originalExternals ).reduce( ( externals, key ) => {
	const path = originalExternals[ key ].split( '.' );
	return {
		...externals,
		[ key ]: {
			this: path,
		},
	};
}, {} );

This is untested pseudocode but I think that would potentially address this use case without adding complexity or specificity to the base usage. Thoughts?

@kadamwhite
Copy link
Contributor

@kucrut Remind me to remind you about this thread :)

@kucrut
Copy link
Author

kucrut commented Jul 23, 2020

@kadamwhite I think it's a good idea to add a code sample in the docs to cover the use case 👍

I remember the early days when Gutenberg wasn't in core yet and I was creating my very first block. I kept having issues with externals until I followed they way Gutenberg set its output, so I tend to stick with it 🙂

@kadamwhite
Copy link
Contributor

@kucrut This keeps slipping off my radar. Would you be interested in preparing a pull request for this?

@kadamwhite kadamwhite added this to the 1.0 milestone Jun 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants