illuminatech/override-build

允许使用补丁重新构建第三方库中的材料

1.1.5 2024-03-25 11:28 UTC

This package is auto-updated.

Last update: 2024-08-25 12:24:01 UTC


README

Laravel Materials Build Override


此扩展允许使用补丁重新构建第三方库中的材料。

有关许可信息,请查看 LICENSE 文件。

Latest Stable Version Total Downloads Build Status

安装

安装此扩展的首选方式是通过 composer

运行

php composer.phar require --prefer-dist illuminatech/override-build

或添加

"illuminatech/override-build": "*"

到您的 composer.json 的 require 部分。

用法

此扩展允许使用补丁重新构建第三方库中的材料。在使用某些已包含编译JavaScript文件的扩展时可能很有用,您需要修改并重新编译这些文件。例如:第三方 CMS(如 Nova)的扩展。

我们可以以 froala/nova-froala-field 为例。此包包含集成到 VueJS 组件中的 JavaScript WYSIWYG 编辑器,它们一起编译成一个单独的 '*.js' 文件。如果您需要将 自定义插件 应用于编辑器,除非您使用自己的更改重新编译扩展,否则将无法实现。

在这种情况下,您可能会简单地调整 'vendor/froala/nova-froala-field' 目录内的源文件,并从那里运行 NPM 构建。然而,在 'vendor' 目录内进行的任何手动更改都可能导致您在未来遇到问题。以这种方式创建的补丁无法通过 VCS 跟踪,并且您将不得不在更新库时重新应用它。此外,对 "vendor" 目录中的文件所做的任何更改都可能导致 Composer 在 'install' 或 'update' 命令失败。

此包就是为了解决这个问题而创建的。它允许从不同路径下的特定源文件创建新的构建(编译)。此任务按照以下步骤执行

  • 将不受 VCS 控制的源文件复制到新的 'build' 目录。

  • 使用 'override' 目录中的文件(可能受 VCS 控制)追加/覆盖复制的文件。

  • 对创建的文件应用预定义的补丁,如搜索替换或 JSON 修改。

  • 在 'build' 目录文件上运行构建/编译。

注意! 实际上以这种方式重新构建第三方材料是一种黑客行为。除非您无法使用其他方法实现目标,否则请勿使用它。

应用程序配置

此扩展使用 illuminatech/array-factory 进行配置。在配置此扩展之前,请确保您熟悉 'array factory' 概念。配置存储在 'config/override-build.php' 文件中。

您可以使用以下控制台命令发布预定义的配置文件

php artisan vendor:publish --provider="Illuminatech\OverrideBuild\OverrideBuildServiceProvider" --tag=config

在配置文件中,您需要定义要重新构建的包列表。对于我们的 'Froala' 例子,配置可能如下所示

<?php

return [
    'packages' => [
        'nova-froala-field' => [
            'srcPath' => base_path('vendor/froala/nova-froala-field'), // directory to get source files from
            'srcFiles' => [ // probably you do not need to copy every vendor file, in this case you can list the needed ones here
                'resources',
                '.babelrc',
                'package.json',
                'webpack.mix.js',
            ],
            'buildPath' => storage_path('build-override/nova-froala-field'), // in this directory the new build will take place.
            'overridePath' => app_path('Nova/Extensions/Froala'), // any file from this directory will be append to the source ones before build
            'patches' => [ // list of patches to be applied to the source files.
                'resources/js/field.js' => [
                    '__class' => Illuminatech\OverrideBuild\Patches\Wrap::class,
                    'template' => "{{INHERITED}}\n\nrequire('./custom-plugins');",
                ],
            ],
            'buildCommand' => [ // shell commands to be executed for the build creation
                'yarn install',
                'yarn run prod',
            ],
        ],
    ],
];

每个包规范是 \Illuminatech\OverrideBuild\Builder 实例的 'array factory' 兼容配置。请参阅 \Illuminatech\OverrideBuild\Builder 类以获取有关特定选项的更多信息。

配置完成后,您可以使用 'override-build' artisan 命令运行重新构建。此命令接受配置中的包名称作为参数,指定哪个包应该被重新构建。例如

php artisan override-build nova-froala-field

注意!请记住,此扩展不会以使用新编译文件的方式重新配置构建的包。您必须手动调整您正在修改的扩展的配置。对于 'Nova Froala field' 的例子,您应该按照以下方式调整您的 \App\Providers\NovaServiceProvider

<?php

namespace App\Providers;

use Laravel\Nova\Nova;
use Laravel\Nova\Events\ServingNova;
use Laravel\Nova\NovaApplicationServiceProvider;

class NovaServiceProvider extends NovaApplicationServiceProvider
{
    public function boot()
    {
        parent::boot();

        Nova::serving(function (ServingNova $event) {
            // override original JS for 'nova-froala-field'
            Nova::script('nova-froala-field', storage_path('build-override/nova-froala-field/dist/js/field.js'));
        });
    }
}

覆盖文件

您可能不需要对某个包进行任何修改就重新构建它。最简单的方法是使用 'override' 目录。它应该重复包含那些需要追加或替换的文件的源目录结构。在我们的 'Nova Froala field' 示例中,源目录具有以下结构

config/
database/
dist/
resources/
    components/
        DetailField.vue
        FormField.vue
        IndexField.vue
    js/
        FroalaAttachmentsAdapter.js
        MediaConfigurator.js
        PluginsLoader.js
        TrixAttachmentsAdapter.js
        field.js
routes/
src/
.babelrc
package.json

它的覆盖目录结构可能如下所示

resources/
    js/
        field.js
        custom-plugins.js

它的应用将替换 'resources/js/field.js' 文件,并追加 'resources/js/custom-plugins.js'。

原始的 'resources/js/field.js' 文件内容如下

require('froala-editor/js/froala_editor.pkgd.min');
require('froala-editor/js/plugins.pkgd.min.js');

import VueFroala from 'vue-froala-wysiwyg';

Nova.booting(Vue => {
    Vue.use(VueFroala);

    Vue.component('index-nova-froala-field', require('./components/IndexField'));
    Vue.component('detail-nova-froala-field', require('./components/DetailField'));
    Vue.component('form-nova-froala-field', require('./components/FormField'));
});

覆盖可能包含额外的代码,添加在 'resources/js/custom-plugins.js' 文件中定义的自定义编辑器插件

require('froala-editor/js/froala_editor.pkgd.min');
require('froala-editor/js/plugins.pkgd.min.js');

require('./custom-plugins'); // add custom plugins to the build

import VueFroala from 'vue-froala-wysiwyg';

Nova.booting(Vue => {
    Vue.use(VueFroala);

    Vue.component('index-nova-froala-field', require('./components/IndexField'));
    Vue.component('detail-nova-froala-field', require('./components/DetailField'));
    Vue.component('form-nova-froala-field', require('./components/FormField'));
});

修补文件

虽然完全覆盖源文件是最简单的方式应用您的修改,但它有一些显著的缺点。您需要将所有原始文件内容复制到覆盖中,然后进行修改,即使只是更改一行代码。在源库升级的情况下,它可能会更改您覆盖的文件,导致构建结束时出现错误。为了使您的更改更加持久,已创建了 \Illuminatech\OverrideBuild\Builder::$patches。每个补丁都是一个匹配 \Illuminatech\OverrideBuild\PatchContract 的 PHP 对象,它修改文件内容。以下是一些预定义的补丁

  • \Illuminatech\OverrideBuild\Patches\Replace - 替换一组字符串。

  • \Illuminatech\OverrideBuild\Patches\Wrap - 将原始内容包装到指定的字符串中,允许追加/前置额外的行。

  • \Illuminatech\OverrideBuild\Patches\Json - 允许修改 JSON 结构。

请参阅特定的补丁类以获取更多详细信息。

对于我们的 'Nova Froala field' 示例,我们可以简单地修补 'resources/js/field.js',添加一行额外的代码 require('./custom-plugins');,而不是完全重写它。

<?php

return [
    'packages' => [
        'nova-froala-field' => [
            // ...
            'patches' => [
                'resources/js/field.js' => [
                    // wrap the original file content, appending `require('./custom-plugins');` to the end of the file
                    '__class' => Illuminatech\OverrideBuild\Patches\Wrap::class,
                    'template' => "{{INHERITED}}\n\nrequire('./custom-plugins');",
                ],
            ],
            // ...
        ],
    ],
];

构建优化

为了加快构建过程,'override-build' 在创建新的构建之前会检查包构建是否已存在。如果构建存在,并且其文件修改日期晚于 'source' 和 'override' 目录中的文件修改日期,则不会启动新的构建。您可以通过在命令调用中使用 --force 标志强制重新创建构建。例如

php artisan override-build nova-froala-field --force

清理文件

在构建过程中,可能会生成一些您可能不想保留的辅助文件。例如,在我们的 'Nova Froala field' 示例中构建时,会创建包含所有 NPM 依赖项的 'node_modules' 目录。为了简化项目结构并节省磁盘空间,您可以设置 \Illuminatech\OverrideBuild\Builder::$cleanupFiles,列出构建完成后应删除的文件和目录。例如

<?php

return [
    'packages' => [
        'nova-froala-field' => [
            // ...
            'cleanupFiles' => [
                'node_modules',
                'yarn.lock',
            ],
        ],
    ],
];