pyro / webpack
Provides the tools and logic to build a modern and modular frontend application for the PyroCMS admin control panel
Installs: 162
Dependents: 1
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Language:TypeScript
pkg:composer/pyro/webpack
Requires
- laradic/support: ~2.0
- ocramius/generated-hydrator: 3.0.*
This package is auto-updated.
Last update: 2025-10-14 20:09:43 UTC
README
This package provides the tools and logic to build a modular frontend application for the PyroCMS admin control panel.
This package does not provide a frontend application. This package does not change anything PyroCMS is doing
Features
- Create modular javascript for addons (which are already modular).
- Addons can enable javascript module(s) at any given point.
- Uses yarn workspaces(providesyarnwith somewhat similar functionality as thecomposer-merge-plugindoes withcomposer)
- Utilizes the (great) things webpack provides
- Tree shaking
- Dynamic imports (async loading)
- HOT reloading
 
Basic Example
- 
Lets pretend to have a module addons/shared/pyro/core-module that contains - 
lib/index.js export class Application { static getInstance(){return new Application()} register(provider){} boot(){} bind(){} make(){} } export class ServiceProvider { app = Application.getInstance() } export class CoreModuleServiceProvider extends ServiceProvider{ register(){} } 
- 
lib/__variables.scss @use "~bootstrap/scss/variables" with ( $text-color: blue; ) $core-variable-one: #333 !default; $core-variable-two: darken($core-variable-one, 5) !default; 
- 
src/CoreModuleServiceProvider.php class CoreModuleServiceProvider extends \Anomaly\Streams\Platform\Addon\AddonServiceProvider { public function boot(Webpack $webpack){ $webpack->enableEntry('@pyro/core-module'); } } 
 
- 
- 
Lets pretend to have another module addons/shared/pyro/foo-module that contains - 
lib/index.js import './style.scss'; import {ServiceProvider} from '@pyro/core-module' export function logWithPrefix(string){ console.log('prefix', string) } export class FooService { hello(){ logWithPrefix('FooService hello') } } export class FooModuleServiceProvider extends ServiceProvider{ register(){ logWithPrefix('registered FooModuleServiceProvider') this.app.bind('foo.service', FooService); } } 
- 
lib/style.scss- @import "@pyro/core-module/lib/variables"; .foo-module { &__item { color: $core-variable-one; &--disabled { color: $core-variable-two; } } } 
- 
src/FooModuleServiceProvider.php class FooModuleServiceProvider extends \Anomaly\Streams\Platform\Addon\AddonServiceProvider { public function boot(Webpack $webpack){ $webpack->enableEntry('@pyro/foo-module'); // can obviously be called anywhere, like controllers actions, route-groups etc } } 
 
- 
- 
Lets pretend to have another module addons/shared/pyro/bar-module that contains - 
lib/index.js import {ServiceProvider} from '@pyro/core-module' import {FooService} from '@pyro/foo-module'; // can import from other modules export class BarModuleServiceProvider extends ServiceProvider{ register(){ logWithPrefix('registered BarModuleServiceProvider') } boot(){ const fooService:FooService = this.app.make('foo.service'); fooService.hello(); } async loadStyle(){ return import('./style.scss') } } 
- 
lib/style.scss $core-variable-one: #999; @import "@pyro/core-module/lib/variables"; .bar-module { &__item { color: $core-variable-one; &--disabled { color: $core-variable-two; } } } 
- 
src/BarModuleServiceProvider.php class BarModuleServiceProvider extends \Anomaly\Streams\Platform\Addon\AddonServiceProvider { public function boot(Webpack $webpack){ $webpack->enableEntry('@pyro/bar-module'); } } 
 
- 
- 
Which we can combine and bootstrap in a view Like addons/shared/pyro/core-module/resources/view/frontend__application.twig And pretend we called ViewIncludes->include('cp_scripts', 'pyro.module.core::frontend__application')inCoreModuleServiceProvider::boot{% import "webpack::include_webpack" %} <script> // The namespace is set in webpack.php config (or .env WEBPACK_NAMESPACE) var exported = window['$NAMESPACE$']; exported.providers; // array of ServiceProvider classes of enabled entries. var app = exported.pyro__core_module.Application.getInstance() // or var app = exported['@pyro/core-module'].Application.getInstance() exported.providers.forEach(function(ProviderClass){ app.register(ProviderClass); }) app.boot().then(function(){ var fooService = app.make('foo.service'); fooService.hello() // app.$mount() ??? // app.render() ??? // implement it yourself }) </script>
5Run yarn serve, yarn build:dev or yarn build:prod
**`yarn serve`** Will start a webpack-dev-server. `Pyro\Webpack` is aware of this will render the webpack-dev-server asset paths.
This will enable HOT Reloading on the scss files we defined. (Vue or React can easily be added with HMR aswell, and is explained further onwards)
**`yarn build:prod`** Will create production assets and place them by default in the `public/assets` (configurable). Again `Pyro\Webpack` is aware of this and will render the production asset paths.
Installation
- 
composer.json "pyro/webpack": "^1.0" 
- 
app.php Pyro\Webpack\WebpackServiceProvider::class; 
- 
.env WEBPACK_ENABLED=true WEBPACK_NAMESPACE=pyro WEBPACK_OUTPUT_PATH=public/assets WEBPACK_PROTOCOL=http WEBPACK_HOST=localhost WEBPACK_PORT=8079 WEBPACK_PATH=storage/webpack.json 
- 
package.json { "workspaces": { "packages": [ "addons/shared/*/*", "core/*/*", "vendor/pyro/webpack" ] }, "scripts": { "build:dev": "NODE_ENV=development webpack --config webpack.config.js", "build:prod": "rm -rf public/assets && NODE_ENV=production webpack --production --config webpack.config.js", "serve": "NODE_ENV=development webpack-dev-server --inline --hot --config webpack.config.js" }, "dependencies": { "@pyro/webpack": "^1.0.0", "@radic/webpacker": "^7.2.0", "webpack": "^4.40.2", "webpack-cli": "^3.3.8", "webpack-dev-server": "^3.8.0" } }
- 
webpack.config.js import { PyroBuilder } from '@pyro/webpack'; const builder = new PyroBuilder({ globs : [ 'addons/shared/*/*', 'addons/*/*', 'core/*/*' ], rootPath : __dirname }) const { wp, env, addons } = builder.init(); // any custom logic const config = wp.toConfig(); export default config; 
- 
Create a view like shown at Basic Example > 4: Create a view to.. 
Add a addon to the builder
In order to get a addon included in the builder, a few additional steps are required.
- Ensure the addon has a package.json(next to the composer.json file)
- It's recommended to set the namefield in package.json the same as in composer.json, but prefixed with an@.
- Ensure package.json has a the versionfield, preferably1.0.0. This version should not be changed.
- Add the pyroconfiguration. Check the example below
Example of a valid package.json:
{
    "name": "@pyro/foo-module",
    "version": "1.0.0",
    "scripts": {},
    "main": "lib/index.js",
    "typings": "lib/index.js",
    "types": "lib/index.js",
    "pyro": {
        "srcPath": "lib",
        "entrypoints": [
            {"path": "index.js", "provider": "FooModuleServiceProvider"}
        ]
    },
    "dependencies": {
        "@pyro/core-module": "^1.0.0",
        "bootstrap": "^4.3.1",
        "element-ui": "^2.12.0",
        "font-awesome": "^4.7.0",
        "vue-clickaway": "^2.2.2"
    },
    "devDependencies": {}
}
PHP Pyro\Webpack
Pyro\Webpack\Webpack
enableEntry($name, $suffix = null)
JS @pyro/webpack
- webpack-chainProvides the chaining webpack configurator API to generate and simplify the modification of webpack
- @radic/webpackerExtends the chaining API with various useful features. Additionally it also provides a whole range of pre-configured, but reconfigurable presets. This aims to make your webpack config small and to the point.
- @pyro/webpackProvides- PyroBuilderto setup webpack. It locates all PyroCMS javascript addon modules and adds them correctly to the webpack configuration.
import { PyroBuilder } from '@pyro/webpack'; const builder = new PyroBuilder({ globs : [ 'addons/shared/*/*', 'addons/*/*', 'core/*/*' ], rootPath : __dirname }) // init() // 1: will find and register all found addons // 2: setup webpack configuration, including addons // 3: returns the Webpacker (webpack-chain) and addon instances array const { wp, env, addons } = builder.init(); // At this point you can use 'wp' (Webpacker/webpack-chain) to add or alter any configuration made // change the output dir? wp.output.path('public/some-other-dir'); // add postcss loader before sass loader in the sass loader use array? wp.module.rule('scss') .use('postcss-loader') .loader('postcss-loader') .before('sass-loader') .options({ preserve : true, whitespace: false }) // modify module rule options? wp.module.rule('babel').use('babel-loader').tap(options => { options.plugins.push(['someplugin']) return options }) // Webpacker also comes with some extra features. // Example: to use @import "~accelerant-theme/.." in SCSS instead of relative paths. wp.ensureLink(path('core/pyrocms/accelerant-theme'), path('node_modules/accelerant-theme')); // At the end of the script transform into a webpack configuration object and export it const config = wp.toConfig(); export default config;