voltel/webpack-assets-bundle

Twig 函数用于列出 CSS/JS 资产文件,并在 Webpack 构建后加载入口点的串联 CSS 内容

安装: 8

依赖者: 0

建议者: 0

安全: 0

星标: 0

观察者: 2

分支: 0

开放问题: 0

类型:symfony-bundle

v1.1.0 2021-05-16 14:18 UTC

This package is auto-updated.

Last update: 2024-09-16 22:40:49 UTC


README

VoltelWebpackAssetsBundle 是一个引入了几个 Twig 函数的 Symfony 扩展包,这些函数可以解析 Webpack 输出,帮助

  • 获取任何感兴趣 入口点 的 CSS/JS 资产文件的 URL 列表
  • 获取任何感兴趣 入口点串联 CSS 内容字符串

注意:此扩展包试图解决的问题已经由 Symfony/WebpackEncoreBundle 解决。这是一个适用于依赖于 传统 webpack 配置(即自定义 webpack.config.js)和构建过程的项目的小型解决方案。

安装

确保已全局安装 Composer,如 Composer 文档中的 安装章节 所述。

打开命令控制台,进入您的项目目录并执行

$ composer require voltel/webpack-assets-bundle

不使用 Symfony Flex 的应用程序

步骤 1:下载扩展包

打开终端,进入您的项目目录并执行以下命令以下载此扩展包的最新稳定版本

$ composer require voltel/extra-foundry-bundle

步骤 2:启用扩展包

然后,通过将其添加到项目中 config/bundles.php 文件中注册的扩展包列表中来启用扩展包

    // config/bundles.php
    return [
        // ...
        Voltel\WebpackAssetsBundle\VoltelWebpackAssetsBundle::class => ['all' => true],
    ];

扩展包配置

config/packages/ 目录中创建配置文件(例如 voltel_webpack_assets.yaml)。

如往常一样,可以通过控制台命令检查 默认配置

$ php bin/console config:dump voltel_webpack_assets

要检查 当前配置,请运行控制台命令

$ php bin/console debug:config voltel_webpack_assets

默认配置

# in config/packages/voltel_webpack_assets.yaml

voltel_webpack_assets:

    # Name of the public web-content base-folder (e.g "public")
    public_dir_name:      public

    webpack:
        # Filepath of the "StatsWriterPlugin" plugin output RELATIVE to the project root
        stats_filepath:       stats.json

        # Name of the Webpack build output folder (e.g. "dist" or "build")
        output_dir_name:      dist
  • public_dir_name:包含从互联网可访问文件的目录名称。Webpack 将将其输出保存到该目录的子目录中(请参阅下面的 webpack.output_dir_name 配置参数)。

    该值可以是相对于项目根目录的路径,这虽然不常见但并非不可能(例如,./public)。

  • webpack.stats_filepath:Webpack 统计输出文件的路径,相对于项目根目录。默认情况下,stats.json 文件位于项目根目录中。如果,例如,您的 Webpack 配置将生成的 stats.json 文件放置在例如 public/dist 目录中,则使用 public/dist/stats.json 值。

  • webpack.output_dir_name:在公共目录内部(如上所述的 public_dir_name 配置参数)的目录名称,Webpack 将在此目录中输出构建过程中创建的文件。该值可以是相对于公共目录的路径,这虽然不常见但并非不可能(例如,./build)。

用法

HTML 页面:entry_css_urlsentry_js_urls Twig 函数

VoltelWebpackAssetsBundle 引入了 entry_css_urlsentry_js_urls Twig 函数,用于从参数中识别入口点的资产文件。

这些函数中的每一个都接受 恰好一个参数:它可以是一个字符串,包含入口点名称,或者是一个字符串数组,包含要加载资产的入口点名称。

    {# in homepage.html.twig #}

    {% set css_urls = entry_css_urls('homepage') %}
    {% set css_urls = entry_css_urls(['homepage']) %}
    {% set css_urls = entry_css_urls(['common_layout', 'homepage']) %}
    
    {% for c_this_relative_url in css_urls %}
        <link rel="stylesheet" href="{{ asset(c_this_relative_url) }}">
    {% endfor %}

    {% for c_this_relative_url in entry_js_urls(['common_layout', 'homepage']) %}
        <script src="{{ absolute_url(c_this_relative_url) }}">
    {% endfor %}

可以通过自定义 Twig 函数实现类似的结果——print_css_link_tagsprint_js_script_tags,它们一次性打印出从第一个参数提供的入口点生成的所有 <link><script> HTML 标签。

    {# in homepage.html.twig #}
    
    {% set l_print_absolute_url = true %}

    {# to print <link type="stylesheet"> html tags in one go #}
    {{ print_css_link_tags('homepage') }}
    {{ print_css_link_tags(['common_layout', 'homepage']) }}
    {{ print_css_link_tags(['common_layout', 'homepage'], l_print_absolute_url) }}

    {# to print <script src=""> html tags in one go #}
    {{ print_js_script_tags('homepage') }}
    {{ print_js_script_tags(['common_layout', 'homepage']) }}
    {{ print_js_script_tags(['common_layout', 'homepage'], l_print_absolute_url) }}

HTML 邮件内容:entry_css_source Twig 函数

    {% set c_css_rules = entry_css_source('common_email') %}
    {% apply inline_css(c_css_rules) %}
        {# email html content #}
    {% andapply %}

讨论

这个包试图解决的问题已知:在Webpack构建过程中,资产CSS和JS文件

  1. 可能会不可预测地聚合成具有未知名称的块,并且
  2. 哈希字符串可能附加到输出文件名上。

因此,加载任何特定入口点的正确资产取决于分析Webpack输出。

此包通过为所有可能依赖的入口点的Twig模板中的<link href="{{ css_url }}"><script src="{{ js_script_url }}">属性提供urls,简化了将CSS和JS文件加载到您的HTML页面中。

此包利用Webpack生成的输出,即stats.json输出文件的"entrypoints"键。

获取输出文件的最佳方法可能是使用StatsWriterPlugin Webpack插件。为此,在webpack.config.js中激活StatsWriterPlugin,例如:

const path = require("path");
const { StatsWriterPlugin } = require("webpack-stats-plugin");

const webpackConfig = {
    entry: entries,
    output: {
        filename: "[name]." + "[hash:6]" + ".js",
        path: path.resolve(__dirname, 'public', 'dist'),
        publicPath: '/dist/'
    },

    // ... Other configuration

    plugins: [
        // ... some built-in Webpack plugin instances
    ]   
};

// Activation of "StatsWriterPlugin" plugin 
webpackConfig.plugins.push(new StatsWriterPlugin({

    // choose your preferred location for webpack statistics output file 
    filename: "../../stats.json",

    // use the same stats config as for webpack standard output 
    stats: {
       all: false,
       entrypoints: true 
    }
}));


module.exports = webpackConfig;

之后,每次您运行Webpack时,它都会重新创建包含当前信息的stats.json文件。

$ webpack
$ npx webpack
$ npx webpack --watch

有关详细信息,请参阅FormidableLabs/webpack-stats-plugin GitHub仓库中的插件文档。

如果您不想使用StatsWriterPlugin,您可以修改webpackConfig.stats输出配置。

webpackConfig.stats = {
    all: false, 
    entrypoints: true, 
    //hash: false,
    //version: false,
    //timings: false,
    //assets: false,
    //chunks: false,
    //maxModules: 0,
    //modules: false,
    //reasons: false,
    //children: false,
    //source: false,
    //errors: false,
    //errorDetails: false,
    //warnings: false,
    //publicPath: false,
    //builtAt: false
};

您可以使用以下命令一次性构建并重新创建stats.json文件:

$ webpack --json > stats.json

使用Twig块的小技巧

为了在由Twig模板生成的HTML页面中填充<link><script>标签,可以使用一种技巧:在扩展的子模板中设置具有要加载的入口点名称的任意上下文变量(本例中为“entrypoints”)。

如果上下文中定义了entrypoints变量且不是null,则将使用此变量中的入口点。否则,将默认使用common_layout入口点的回退值。

为了说明这种方法,以下是base.html.twig模板和从其扩展的子模板homepage.html.twig的摘录

    {# in base.html.twig #}

    {% block stylesheets %}
        {% for c_this_relative_url in entry_css_urls(entrypoints ?? 'common_layout') %}
            <link rel="stylesheet" href="{{ asset(c_this_relative_url) }}">
        {% endfor %}
    {% endblock %}


    {% block javascripts %}
        {% for c_this_relative_url in entry_js_urls(entrypoints ?? 'common_layout') %}
            <script src="{{ asset(c_this_relative_url) }}"></script>
        {% endfor %}
    {% endblock javascripts %}

上述代码的注释

  • 如果设置了上下文变量“entrypoints”,则将使用其中列出的入口点。否则,将使用回退值“common-layout”。

  • 为了防止加载“common_layout.js”,应在页面上覆盖“javascripts”块,而不是跳过它。

在这种情况下,在扩展的子模板中,只需在模板上下文中定义一个entrypoints变量即可。

    {# in homepage.html.twig #}

    {% set entrypoints = ['common_layout', 'homepage'] %}
    
    {% block title %}{{ 'homepage.title' | trans }}{% endblock %}

    {% block main %}{# page content #}{% endblock %}
    

使用上下文变量entrypoints的父base.html.twig模板
将自动创建<link><script>标签,用于所有在提供的入口点中导入的样式表和javascript文件。

Note, that since <link> tags will be created sequentially,
in the order the entrypoints are listed, 
stylesheets from the second entrypoint ("homepage" in this case) 
will have precedence over CSS rules from stylesheets of "common_layout" entrypoint.
 
Therefore, "common_layout" endpoint should go first 
to let "homepage" override some CSS rules with page specific values, if needed. 

假设您想加载在"common_layout""homepage"入口点中定义的CSS文件,但跳过从"commont_layout"入口点加载*.js文件,可以像以下示例中那样覆盖javascripts块:

    {# in homepage.html.twig #}

    {# This context variable will be automatically used by the parent's "stylesheets" block #}
    {% set entrypoints = ['common_layout', 'homepage'] %}

    {% block javascripts %}
        {# Parent's "javascript" block will load ONLY files from "homepage" entrypoint #}
        {% set entrypoints = 'homepage'  %}
        {{ parent() }}
        
    {% endblock %}

在Twig模板中内联CSS:entry_css_source函数

inline_css Twig过滤器有助于将CSS格式化嵌入到HTML标签的style属性中。

有关它在电子邮件内容中的有用性的更多信息,请参阅Symfony文档,或观看Symfony Mailer的screencast,特别是以下章节

同样,我们必须依赖由webpack-stats-plugin创建的stats.json文件(特别是其“entrypoints”键)或手动在构建过程中创建的。

此包引入了Twig函数entry_css_source,它将执行以下操作

  • 根据参数确定要加载的*.css文件数组;
  • 对于每个文件,将CSS规则读取到字符串中;
  • 将所有样式表的CSS规则合并成一个字符串,然后返回,供例如inline_css过滤器使用。
    {% apply inky_to_html | inline_css(entry_css_source('common_email')) %}
        <container>
            {# email html content #}
        </container>
    {% andapply %}

"common_email" 入口点可能导入例如Zurb Foundation (Inky) CSS和自定义CSS规则。

/* This uses Zurb Foundation (Inky) - css for emails */
@import "~foundation-emails/dist/foundation-emails.min.css";

.logo {
  text-align: center;
}
.email-header {
  color: darkslategrey;
  text-align: center;
}
.email-recipient {
  color: red;
}

贡献

Of course, open source is fueled by everyone's ability to give just a little bit
of their time for the greater good. If you'd like to see a feature or add some of
your *own* happy words, awesome! You can request it - but creating a pull request
is an even better way to get things done.

Either way, please feel comfortable submitting issues or pull requests: all contributions
and questions are warmly appreciated :).

尽管如此,您可能会发现使用和贡献Symfony/WebpackEncoreBundle更为合适,因为它是一个主流的Symfony包,可以解决相同的问题。