-
Notifications
You must be signed in to change notification settings - Fork 1.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
allow assigning external modules to global variables #337
Comments
I think this feature would be most appropriately addressed by a plugin instead of adding it to esbuild's core. There is a plugin API in development that I believe should be able to implement this feature: #111. |
This comment has been minimized.
This comment has been minimized.
I was thinking about a plugin like this: let examplePlugin = plugin => {
plugin.setName('wp-global')
plugin.addResolver({ filter: /^@wordpress\// }, args => ({
path: args.path, namespace: 'wp-global',
}))
plugin.addLoader({ filter: /.*/, namespace: 'wp-global' }, args => {
let name = args.path.slice(11).replace(/-(.)/g, (_, x) => x.toUpperCase())
let contents = `export default wp[${JSON.stringify(name)}]`
return { contents }
})
} When you build this file with that plugin: import blocks from '@wordpress/blocks'
console.log(blocks) you get something like this: // wp-global:@wordpress/blocks
var blocks_default = wp["blocks"];
// <stdin>
console.log(blocks_default); I'm not familiar with Rollup so I'm not sure what your use case is, but that's what I thought you were trying to do. Is that what you were looking for? |
I think i misunderstood this feature request, i created #451 with my use case I want to do the opposite, replace global objects with external modules, this way you can for example replace the “process” global object with a polyfill ExampleBuilding with a setting like The code below console.log(`This platform is ${process.platform}`); Would become import process from './process-polyfill.js'
console.log(`This platform is ${process.platform}`); |
#415 has now been implemented.
Actually this is already possible without plugins by using {
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@wordpress/blocks": "file-that-exports-wp.blocks.js",
"@wordpress/block-editor": "file-that-exports-wp.blockEditor.js",
"@wordpress/components": "file-that-exports-wp.components.js",
"@wordpress/compose": "file-that-exports-wp.compose.js",
"@wordpress/data": "file-that-exports-wp.data.js",
"@wordpress/date": "file-that-exports-wp.date.js",
"@wordpress/edit-post": "file-that-exports-wp.editPost.js",
"@wordpress/element": "file-that-exports-wp.element.js",
"@wordpress/plugins": "file-that-exports-wp.plugins.js"
}
}
} For example, export default wp.blocks |
Closing this. It should now be possible to implement things like this using plugins and/or inject. |
I am trying to implement something similar to webpack's external config but am not having any luck. This module will be executed in an iframe with some global variables in scope so I don't want to bundle those. In my source I have something like: import { foo } from 'my-package'; In webpack I would do: {
externals: {
'my-package': 'MyPackage'
}
} Where
I have implemented the plugin as suggested above. Is this possible to do with esbuild? EDIT: Some background: I am working on ui extensions that are to be embedded in our app. I need to ensure that the same module is used in the hosting app and in the ui extension. For instance, using different versions of react causes runtime errors when using DOUBLE EDIT: I got this working just by using commonjs exports instead. const myPlugin = {
name: 'my-plugin',
setup(build) {
build.onResolve({ filter: /^my-package$/ }, (args) => ({
path: args.path,
namespace: 'my-plugin',
}));
build.onLoad({ filter: /.*/, namespace: 'my-plugin' }, () => {
const contents = `module.exports = MyPackage`;
return { contents };
});
}
} |
The tsconfig method works but at least with WordPRess you'll need to use commonjs exports like a-b-r-o-w-n mentions.
If you use import { registerPlugin } from "@wordpress/plugins"; it will cause import error:
UPDATE: I ended up creating a generic plugin for this. Sharing here as it might help others too. function importAsGlobals(mapping) {
// https://stackoverflow.com/a/3561711/153718
const escRe = (s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
const filter = new RegExp(
Object.keys(mapping)
.map((mod) => `^${escRe(mod)}$`)
.join("|"),
);
return {
name: "global-imports",
setup(build) {
build.onResolve({ filter }, (args) => {
if (!mapping[args.path]) {
throw new Error("Unknown global: " + args.path);
}
return {
path: args.path,
namespace: "external-global",
};
});
build.onLoad(
{
filter,
namespace: "external-global",
},
async (args) => {
const global = mapping[args.path];
return {
contents: `module.exports = ${global};`,
loader: "js",
};
},
);
},
};
} and pass the mapping to esbuild: plugins: [
importAsGlobals({
"@wordpress/components": "wp.components",
"@wordpress/api-fetch": "wp.apiFetch",
"@wordpress/edit-post": "wp.editPost",
"@wordpress/element": "wp.element",
"@wordpress/plugins": "wp.plugins",
"@wordpress/editor": "wp.editor",
"@wordpress/block-editor": "wp.blockEditor",
"@wordpress/blocks": "wp.blocks",
"@wordpress/hooks": "wp.hooks",
"@wordpress/utils": "wp.utils",
"@wordpress/date": "wp.date",
"@wordpress/data": "wp.data",
react: "React",
"react-dom": "ReactDOM",
}),
], This probably already exists but my google-fu fails me atm. |
* fix: modernize build using esbuild * example: build & serve demo w/ esbuild move to examples folder so more apps could be added * tools: add livereload, fix demo target folder * tools: remove Webpack tooling * tools: remove babel-eslint, upgrade standard * fix: robust minimal test stack esbuild/zora/c8 * fix: add esbuild global externals plugin evanw/esbuild#337
It would be great if we could reference external modules to their global counterpart as I currently do on rollup like:
a possible interface for this, could be something like:
The text was updated successfully, but these errors were encountered: