{"id":28282647,"url":"https://github.com/adambrgmn/wp-bundler","last_synced_at":"2025-06-30T01:33:02.527Z","repository":{"id":43208008,"uuid":"409305636","full_name":"adambrgmn/wp-bundler","owner":"adambrgmn","description":"A minimal and fast bundler for your WordPress front end assets.","archived":false,"fork":false,"pushed_at":"2024-05-24T13:31:46.000Z","size":1138,"stargazers_count":16,"open_issues_count":1,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-21T15:23:14.781Z","etag":null,"topics":["bundler","esbuild","wordpress"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adambrgmn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-09-22T18:00:22.000Z","updated_at":"2025-04-09T10:19:26.000Z","dependencies_parsed_at":"2024-02-18T14:49:54.854Z","dependency_job_id":null,"html_url":"https://github.com/adambrgmn/wp-bundler","commit_stats":{"total_commits":72,"total_committers":2,"mean_commits":36.0,"dds":"0.18055555555555558","last_synced_commit":"d29297a157432640cf08d886e536ea5272eb7b73"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/adambrgmn/wp-bundler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adambrgmn%2Fwp-bundler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adambrgmn%2Fwp-bundler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adambrgmn%2Fwp-bundler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adambrgmn%2Fwp-bundler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adambrgmn","download_url":"https://codeload.github.com/adambrgmn/wp-bundler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adambrgmn%2Fwp-bundler/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260306809,"owners_count":22989667,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bundler","esbuild","wordpress"],"created_at":"2025-05-21T15:19:34.995Z","updated_at":"2025-06-17T06:31:45.768Z","avatar_url":"https://github.com/adambrgmn.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WP Bundler\n\nWP Bundler is a minimal and fast bundler for your WordPress front end assets. It is a \"thin\" wrapper around [`esbuild`](https://esbuild.github.io/) with built-in support for translations. It handles all of your front end assets including Javascript (with Typescript and React support), CSS and other static assets imported in these, e.g. images and fonts.\n\nIt will output modern Javascript for modern browsers as well as a \"legacy\" version of your scripts for older browsers meaning that you will not send unneccessary content to modern browsers, while keeping the same functionality for older browsers as well.\n\n- [Installation](#installation)\n- [Cli](#cli)\n- [Configuration](#configuration)\n  - [`BundlerConfig.entryPoints` (required)](#bundlerconfigentrypoints-required)\n  - [`BundlerConfig.outdir` (optional)](#bundlerconfigoutdir-optional)\n  - [`BundlerConfig.sourcemap` (optional)](#bundlerconfigsourcemap-optional)\n  - [`BundlerConfig.externals` (optional)](#bundlerconfigexternals-optional)\n  - [`BundlerConfig.assetLoader` (optional)](#bundlerconfigassetloader-optional)\n  - [`BundlerConfig.translations` (optional)](#bundlerconfigtranslations-optional)\n- [Development](#development)\n- [Asset types](#asset-types)\n  - [Javascript and Typescript](#javascript-and-typescript)\n  - [CSS](#css)\n    - [CSS modules](#css-modules)\n- [Asset loader](#asset-loader)\n  - [Usage](#usage)\n- [External dependencies](#external-dependencies)\n- [Translations](#translations)\n  - [PHP and Twig translations](#php-and-twig-translations)\n- [Environment variables](#environment-variables)\n  - [Other injected variables](#other-injected-variables)\n  - [Other `.env` files](#other-env-files)\n- [Other WordPress focused bundlers](#other-wordpress-focused-bundlers)\n- [LICENSE](#license)\n\n## Installation\n\nInstall the bundler locally as a dependency of you theme or plugin.\n\n```shell\n$ npm i -d @fransvilhelm/wp-bundler\n$ yarn add --dev @fransvilhelm/wp-bundler\n```\n\nThen configure the scripts in your `package.json`.\n\n```json\n{\n  \"scripts\": {\n    \"build\": \"wp-bundler build\",\n    \"dev\": \"wp-bundler dev\"\n  }\n}\n```\n\n## Cli\n\n```shell\n$ wp-bundler --help\n  wp-bundler [command]\n\n  Commands:\n    wp-bundler build  Create production ready version of your project\n    wp-bundler dev    Run a development server\n\n  Options:\n    --help     Show help                                                 [boolean]\n    --version  Show version number                                       [boolean]\n```\n\n```shell\n$ wp-bundler build --help\n  wp-bundler build\n\n  Create production ready version of your project\n\n  Options:\n        --help     Show help                                             [boolean]\n        --version  Show version number                                   [boolean]\n    -m, --mode     Version of your source to output\n                                        [choices: \"dev\", \"prod\"] [default: \"prod\"]\n        --cwd      Optional path to your project                          [string]\n```\n\n```shell\n$ wp-bundler dev --help\n  wp-bundler dev\n\n  Run a development server\n\n  Options:\n        --help     Show help                                             [boolean]\n        --version  Show version number                                   [boolean]\n    -h, --host     Host to bind the server to               [default: \"localhost\"]\n    -p, --port     Port to bind the server to                      [default: 3000]\n    -m, --mode     Version of your source to output\n                                        [choices: \"dev\", \"prod\"] [default: \"dev\"]\n        --cwd      Optional path to your project                          [string]\n```\n\n## Configuration\n\nThere are _three_ places in which you can configure `wp-bundler`. Either in your projects `package.json` under the property `\"wp-bundler\"`, or in any of the files `.wp-bundlerrc` and `wp-bundler.config.json`.\n\nBelow is an example configuration with all available configuration options used:\n\n```json\n{\n  \"entryPoints\": {\n    \"app\": \"src/app.ts\",\n    \"admin\": \"src/admin.ts\"\n  },\n  \"outdir\": \"dist\",\n  \"sourcemap\": true,\n  \"externals\": { \"lodash\": \"_\" },\n  \"assetLoader\": {\n    \"path\": \"inc/AssetLoader.php\",\n    \"namespace\": \"MyNamespace\"\n  },\n  \"translations\": {\n    \"domain\": \"theme-domain\",\n    \"pot\": \"languages/theme.pot\",\n    \"pos\": [\"languages/sv_SE.po\", \"languages/en_US.po\"]\n  }\n}\n```\n\nThe app uses schema validation logic to validate the configuration. The actual schema can be found in [`./src/schema.ts`](./src/schema.ts).\n\n### `BundlerConfig.entryPoints` (required)\n\n- **Type:** `Record\u003cstring, string\u003e`\n\n`entryPoints` is used to tell the bundler which source files we care about. It should be an object with string values. The keys (`app` and `admin`) in the above example can later be used to load the assets with the [`AssetLoader`](#asset-loader).\n\nThe values should point to source files, most often it is `.js` (or `.ts`) files, but it can also be `.css` files. The files will be bundled by `esbuild` and placed in the output directory (same directory as your `package.json`).\n\nThe paths should be referenced as relative to your projects root directory.\n\nYou don't have to specify one entry point for css and one for js if they are tightly coupled. Instead you can import the css from your js source (`import './app.css'`).\n\n### `BundlerConfig.outdir` (optional)\n\n- **Type:** `string`\n- **Default:** `'dist'`\n\n`outdir` is the directory in which to put your assets. It should be referenced as relative to your projects root directory (same directory as your `package.json`).\n\n### `BundlerConfig.sourcemap` (optional)\n\n- **Type:** `boolean`\n- **Default:** `undefined`\n\nTell the bundler to output sourcemaps together with the bundled output. This option is optional and defaults to `true` when you run `wp-bundler dev` and `false` when you run `wp-bundler build`.\n\n### `BundlerConfig.externals` (optional)\n\n- **Type:** `Record\u003cstring, string\u003e`\n- **Default:** `undefined`\n\nIf you are loading some libraries from e.g. a cdn or in some other fashion you can tell `wp-bundler` to ignore those libraries and instead \"import\" them from the `window` object. The key should be the name of the dependency and the value should be the key used to access it from `window`.\n\n**Example:** Given the following config: `{ \"externals\": { \"lodash\": \"_\" } }` the library will skip bundling `lodash` and instead access it from `window._`.\n\nBuilt-in dependencies, e.g. jQuery, React and WordPress libraries are [handled automatically](#external-dependencies).\n\n### `BundlerConfig.assetLoader` (optional)\n\n- **Type:** `{ path?: string; namespace?: string }`\n- **Default:** `{ path: './AssetLoader.php', namespace: 'WPBundler' }`\n\nThe `AssetLoader` is a php file that is emitted as part of the `build` and `dev` scripts. It can be used to load assets as part of the WordPress workflow. With these options you can specify the location of the emitted `AssetLoader` and also which namespace should be used. [Read more](#asset-loader).\n\n### `BundlerConfig.translations` (optional)\n\n- **Types:** `{ domain: string; pot: string; pos?: string[] }`\n- **Default:** `undefined`\n\nConfigure if translations are enabled and if so where translations should live and how to handle them. [Read more](#translations).\n\n## Development\n\nDuring development a minimal web-socket server is initiated and a small dev client is injected on all your apps pages. This means that as soon as you make changes to any of you source files the page will automatically reload. If you only change a `.css` file the page will not be reloaded, instead the css will be replaced \"in-flight\".\n\nBy default the web socket will be setup to listen on `localhost` and port `3000`. You can configure this by passing flags to the CLI; `wp-bundler dev --host \u003chost\u003e --port \u003cport\u003e`.\n\n## Asset types\n\n`wp-bundler` can handle the same asset types as [`esbuild`](https://esbuild.github.io/content-types/) can. Outside of what's setup by default by `esbuild` it will also handle font files (`.ttf`, `.eot`, `.woff` and `.woff2`).\n\n### Javascript and Typescript\n\nJavascript and Typescript is mainly compiled for modern browsers. During development that's the only version emitted. But when building for production an extra version of all js is also emitted, a \"nomodule\" version which is compiled to work with older browsers. It uses [`swc`](https://swc.rs/) under the hood to make the compilation fast.\n\nThe \"modern\" bundle is loaded in a script tag with `type=\"module\"` specified, and the version for older browsers are loaded with `nomodule` set on the script tag.\n\n### CSS\n\nYour css is \"post processed\" by [`postcss`](https://postcss.org/). `wp-bundler` uses [`postcss-preset-env`](https://preset-env.cssdb.org/) to compile the css to a version that is more friendly to older browsers. See `postcss-preset-env`'s documentation for details around which features are available for compilation.\n\n#### CSS modules\n\nCSS modules are supported out of the box. Name your css files with the `.module.css` extension and they will be treated as css modules. The class names will be globally unique and each class will be available as a named export.\n\n```css\n.button {\n  background: rebeccapurple;\n}\n```\n\n```js\nimport * as style from './button.module.css';\n\n\u003cbutton className={style.button}\u003eHello\u003c/button\u003e;\n```\n\nYou can read more about what is possible with CSS modules within the context of wp-bundler and esbuild by referencing the [esbuild documentation](https://esbuild.github.io/content-types/#local-css).\n\n## Asset loader\n\nAs part of both the `dev` and `build` commands a special \"asset loader\" php class is created (you can configure its location by defining `assetLoader.path` in your `wp-bundler` config).\n\nThe file gets emitted with the most recent versions of you assets. These assets can then be loaded as part of the WordPress flow.\n\n### Usage\n\nIf you are not using some kind of autoloader for your project you need to require the file to make the `AutoLoader` class available in your environment. Your theme's `functions.php` or plugins main entry point is probably a suitable file for this.\n\nYou also need to call the static `prepare` method on the class in order to setup some necessary action and filter hooks.\n\n```php\nrequire_once __DIR__ . '/AssetLoader.php';\n\\WPBundler\\AssetLoader::prepare();\n\n// If you are developing a plugin you need to explicitly pass your plugin's root folder and url like so:\n\\WPBundler\\AssetLoader::prepare(\\plugin_dir_path(__FILE__), \\plugin_dir_url(__FILE__));\n```\n\nAfter that you should be able to use the `AssetLoader` class anywhere in your application code. The loader will take care of loading both javascript and css emitted by the bundler. All methods are static.\n\n```php\n// Enqueue the script as parth of the `wp_enqueue_scripts` action hook\n\\WPBundler\\AssetLoader::enqueueAssets('app');\n\n// Enqueue your assets as part of the Gutenberg block editor, using the `enqueue_block_editor_assets` action hook\n\\WPBundler\\AssetLoader::enqueueEditorAssets('app');\n\n// Hook into `init` action and register a block type together with its assets\n\\WPBundler\\AssetLoader::enqueueBlockType('editor', 'my-block');\n\n// Then there are methods which are not wrapped in \"hooks\". These are more\n// similar to the `wp_register_script` or `wp_enqueue_script` et.al.\n\\WPBundler\\AssetLoader::register('app');\n\\WPBundler\\AssetLoader::enqueue('app');\n\\WPBundler\\AssetLoader::registerBlockType('editor', 'my-block');\n```\n\nSee the [`AssetLoader`](./assets/AssetLoader.php) implementation for more information about what the methods can do.\n\n## External dependencies\n\n`wp-bundler` will automatically recognize external modules that are already built into and distributed by WordPress. These dependencies will not be included in your bundle and instead automatically loaded as dependencies by the `AutoLoader`.\n\nThis means that as long as you use any of the built-in dependencies (`@wordpress/*`, `react`, `jquery` etc.) you don't have to specify them in the `$deps` array. Though if you specifiy other externals in your bundler config (`config.externals`) you need to register them with `wp_register_script` and specify them as dependencies of your asset (`AssetLoader::enqueueAsset('app' ['dependency-handle']);`).\n\nThe following dependencies are automatically detected and loaded by `wp-bundler`:\n\n- React (`import React from 'react'`)\n- ReactDOM (`import ReactDOM from 'react-dom'`)\n- jQuery (`import $ from 'jquery'`)\n\n_Note that accessing `window.$('.whatever')` is not recognized by `wp-bundler` and you therefore need to specify `jquery` as a dependency of you asset._\n\nOutside of that all `@wordpress/*` packages are automatically identified by the bundler and excluded from the bundle, then enqueued by the `AssetLoader`. For example if you, somewhere in your source code, do `import api from '@wordpress/api-fetch'` the `AssetLoader` will automatically define `wp-api-fetch` as a dependency of the asset that depends on it.\n\n## Translations\n\nTranslation support is one of the main reasons this project was created in the beginning. None of the other projects that I've found cares about translations, at all. And `wp-cli i18n make-pot` and `wp-cli i18n make-json` are very limited in what the can do. For example they can't extract translations from Typescript files or scripts created by a bundler.\n\n`wp-bundler` uses ast processing to find all translations in your source code and then generate `jed` formatted translation files for all the scripts that needs it. The translations are automatically loaded by the `AssetLoader` when you register/enqueue an asset.\n\n`wp-bundler` will look for calls to the `__`, `_x`, `_n` and `_nx` methods. And all the below calls will be recognized:\n\n```js\nimport { __, _n as translate } from '@wordpress/i18n';\n\n__('Foo', 'domain');\ntranslate('Foo', 'Foos', 1, 'domain');\nwindow.wp.i18n._x('Foo', 'context', 'domain');\nwp.i18n._nx('Foo', 'Foos', 2, 'context', 'domain');\n```\n\n_Note that using `window.wp.i18n.{method}` will not recognize `wp-i18n` as a dependency of your script. In that case you need to specify it as a dependency when you register/enqueue the asset._\n\nAll translations found will also be emitted to a translations template file (`.pot`) of your choice. That means that every time you add a new translation a new entry will be created in your pot file, even in development mode.\n\nThe `.po` files, configured in `translations.pos`, will then be used to emit `jed` formatted json files that the WordPress i18n package can handle.\n\n### PHP and Twig translations\n\nThe bundler will also look for, and extract, translations from your projects `.php` and `.twig` files. It will find all of these files in you project, but ignoring the `vendor` and `node_modules` folders. This means that using this package means you no longer need to use `wp-cli i18n make-pot/make-json` to extract and generate translations.\n\n`.mo` files will also me compiled from all your `.po` files.\n\n## Environment variables\n\nYou can define environment variables in a `.env` file located in the root of you project, right by you `package.json` file. `wp-bundler` will inject any env variable defined in those that starts with `WP_`.\n\n- `WP_API_KEY` =\u003e injected\n- `API_KEY` =\u003e not injected\n\nThen in your application code you can access those by reading `process.env.WP_API_KEY` (or whatever the variable was called).\n\nThe variables defined in `.env` will not override any environment variables already set.\n\n### Other injected variables\n\nExcept environment variable prefixed with `WP_` `wp-bundler` will also inject the following variables:\n\n- `process.env.NODE_ENV`: `'production'` during build, `'development'` in watch mode\n- `__DEV__`: `false` during build, `true` in watch mode\n- `__PROD__`: `true` during build, `false` in watch mode\n\n### Other `.env` files\n\nExcept the `.env` file you can use a few other `.env` files to inject variables from. The list below defines which files are read during which script. Files to the left have more priority than files to the right. Meaning that variables coming from a file to the left will override a variable coming from a file to the right.\n\n- `wp-bundler build` (or `--mode prod`): `.env.production.local` \u003e `.env.local` \u003e `.env.production` \u003e `.env`\n- `wp-bundler dev` (or `--mode dev`): `.env.development.local` \u003e `.env.local` \u003e `.env.development` \u003e `.env`\n\nWith this structure you could have a `.env` file tracked by `git` and then allow developers to override these defaults with their own `.env.local` files, which should not be checked into `git`. This is the same mechanism as e.g. [Next.js uses](https://nextjs.org/docs/basic-features/environment-variables#environment-variable-load-order).\n\n## Other WordPress focused bundlers\n\nThe following projects might interest you if `wp-bundler` doesn't meet your requirements.\n\n- [`wpack.io`](https://wpack.io/)\n- [`presspack`](https://github.com/jaredpalmer/presspack))\n\n## LICENSE\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadambrgmn%2Fwp-bundler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadambrgmn%2Fwp-bundler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadambrgmn%2Fwp-bundler/lists"}