pyro/webpack

提供构建 PyroCMS 管理控制面板现代和模块化前端应用的工具和逻辑

安装次数: 162

依赖: 1

建议者: 0

安全: 0

星标: 0

关注者: 2

分支: 0

开放问题: 0

语言:TypeScript

dev-master / 1.1.x-dev 2020-12-05 13:39 UTC

This package is auto-updated.

Last update: 2024-09-14 17:48:20 UTC


README

此包提供构建 PyroCMS 管理控制面板模块化前端应用的工具和逻辑。

此包提供前端应用。此包改变 PyroCMS 的任何功能

特性

  • 为插件创建模块化的 JavaScript(插件已经是模块化的)。
  • 插件可以在任何给定点启用 JavaScript 模块。
  • 使用 yarn workspaces(为 yarn 提供类似于 composer-merge-plugincomposer 的功能)
  • 利用 webpack 提供的(伟大的)功能
    • 摇树优化
    • 动态导入(异步加载)
    • 热重载

基本示例

  1. 假设我们有一个模块 addons/shared/pyro/core-module,其中包含

    • 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');
          }
      }
  2. 假设我们还有另一个模块 addons/shared/pyro/foo-module,其中包含

    • 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
          }
      }
  3. 假设还有一个模块 addons/shared/pyro/bar-module,其中包含

    • 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');
          }
      }
  4. 我们可以将它们组合并在视图中引导

    addons/shared/pyro/core-module/resources/view/frontend__application.twig,并在 CoreModuleServiceProvider::boot 中调用 ViewIncludes->include('cp_scripts', 'pyro.module.core::frontend__application')

    {% 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>

5运行 yarn serveyarn build:devyarn 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.

安装

  1. composer.json

     "pyro/webpack": "^1.0"
  2. app.php

    Pyro\Webpack\WebpackServiceProvider::class;
  3. .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
  4. 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"
        }
    }
  5. 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;
  6. 创建一个视图,如所示 基本示例 > 4: 创建一个视图以..

将插件添加到构建器

为了将插件包含在构建器中,需要执行一些额外步骤。

  1. 确保插件有一个 package.json(位于 composer.json 文件旁边)
  2. 建议在 package.json 中设置 name 字段与 composer.json 中相同,但前缀为 @
  3. 确保 package.json 有一个 version 字段,最好为 1.0.0。此版本不应更改。
  4. 添加 pyro 配置。请查看下面的示例

有效的 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-chain 提供链式 webpack 配置器 API,用于生成和简化 webpack 的修改
  • @radic/webpacker 通过各种实用功能扩展链式 API。此外,它还提供了一系列 预配置但可重新配置的预设。这旨在使您的 webpack 配置小巧而直接。
  • @pyro/webpack 提供了 PyroBuilder 来设置 webpack。它定位所有 PyroCMS JavaScript 插件模块,并将它们正确添加到 webpack 配置中。
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;