maba/webpack-bundle

将Webpack集成到Symfony的项目中

安装次数:267,087

依赖: 4

建议者: 0

安全性: 0

星标: 122

关注者: 14

分支: 36

开放性问题: 15

类型:symfony-bundle

1.1.3 2020-01-17 10:14 UTC

This package is auto-updated.

Last update: 2024-09-17 21:23:47 UTC


README

Symfony扩展,帮助将webpack集成到Symfony项目中。

什么是webpack?

模块打包器和CommonJS/AMD依赖管理器。

对我来说,它取代了grunt/gulp和RequireJS。

这个扩展做了什么?

  1. 在twig模板中找到javascript入口点。
  2. 使用assets-webpack-plugin运行webpack。
  3. 保存生成的文件名,以便twig函数返回正确的资源URL。

此外,在开发环境中

  1. 运行webpack-dev-server,当资源发生变化时,它会提供并重新生成资源。
  2. 监视twig模板的更改,当webpack配置发生变化时,更新入口点并重启webpack-dev-server。

更多功能

  1. 允许您按需配置webpack配置,同时仍然提供来自Symfony的所需参数,如入口点、别名、环境和附加参数。
  2. 允许您定义自定义入口点提供者,如果您不使用twig或以其他方式包含脚本。
  3. 默认支持图像和css/less/sass文件,如有需要。
  4. 支持Webpack 2(默认)和Webpack 1。

请查看Symfony、Webpack和AngularJS单页面应用示例以获取使用示例。

还可以查看MabaWebpackMigrationBundle,它可以帮助从AsseticBundle迁移到webpack。

这与assetic相比如何?

Webpack允许您创建知道其依赖项的组件。

使用assetic时,您必须显式地在模板中提供所有需要的javascript和CSS文件。如果您将一个javascript文件分割成两个文件,您需要更新所有需要新依赖项的模板。使用webpack,您只需在javascript文件中用require('./newFile.js');即可。

此外,您可以通过javascript像其他javascript一样轻松地require CSS文件 - require('./styles.css');然后您就可以开始了。

如果您的应用程序是前端驱动的,迟早您需要异步加载您的资源。Webpack默认支持这一点。Assetic仅打包资源,您需要使用类似RequireJS的库来完成此操作(例如,您可以考虑HearsayRequireJSBundle作为替代方案)。

webpack-dev-server支持文件的即时重新加载,有时无需刷新页面(对于样式和一些JS框架,如React来说非常理想)。

安装

composer require maba/webpack-bundle

AppKernel内部

new Maba\Bundle\WebpackBundle\MabaWebpackBundle(),

运行命令

app/console maba:webpack:setup

它会复制默认的webpack.config.jspackage.json文件,并运行npm install

如果任何文件已存在,您将被询问是否要覆盖它们。

webpack.config.js必须导出一个函数,该函数接受options作为参数,并返回webpack配置。

您可以根据需要修改此配置文件 - 扩展仅提供默认配置作为起点。

您应该将 webpack.config.jspackage.json 添加到您的仓库中。您还应该将 node_modules 添加到 .gitignore 文件中,并运行 npm install,类似于 composer install(在克隆仓库后,在 package.json 更新后,以及在部署任务中)。当然,您也可以直接将其添加到您的仓库中。

git add package.json app/config/webpack.config.js

如果您出于某种原因想使用 Webpack 1,请将 --useWebpack1 作为命令行选项传递给 setup 命令。

用法

在 twig 模板内部

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    {% webpack css '@app/bootstrap.less' '@ApplicationBundle/Resources/assets/script.js' %}
        <link rel="stylesheet" href="{{ asset_url }}"/>
    {% end_webpack %}
</head>
<body>
    
    <img src="{{ webpack_asset('@app/funny-kitten.png') }}"/>
    
    <script src="{{ webpack_asset('@ApplicationBundle/Resources/assets/script.js') }}"></script>
</body>
</html>

script.js 内部

require('./script2.js');
require('./my-styles.less');

function loadScript3() {
    require.ensure([], function() {
        require('@AnotherBundle/Resources/assets/script3.js');
        require('./style.css');
    });
}
setTimeout(loadScript3, 1000);

作为部署到生产环境的一部分,在清除缓存之后

app/console maba:webpack:compile --env=prod

在开发环境中(这必须始终在后台运行,类似于 assetic:watch

app/console maba:webpack:dev-server

或者,如果您不是积极开发您的前端,您可以一次性编译并忘记它,类似于生产环境

app/console maba:webpack:compile

如果您正在对您的应用程序运行功能测试,请确保为测试环境编译一次以生成测试环境的清单文件

app/console maba:webpack:compile --env=test

Twig 函数和标签

您可以选择使用 webpack_asset 函数或 webpack 标签。

函数

webpack_asset(resource, type = null)

typejscss,留空以猜测类型。对于 css,此函数可能会返回 null,如果从提供的入口点提取不出 CSS。如果您确定将有一些 CSS,您可以忽略这一点。否则,您可以使用 webpack 标签,因为它为您处理这一点(在这种情况下,完全省略了 <link/> 标签)。

标签

{% webpack [js|css] [named] [group=...] resource [resource, ...] %}
    Content that will be repeated for each compiled resource.
    {{ asset_url }} - inside this block this variable holds generated URL for current resource
{% end_webpack %}

webpack_asset 函数类似,提供 jscss 或留空以猜测类型。

使用通用块 部分中查看使用 namedgroup 的示例。

请注意,您必须在标签和函数中提供硬编码的资产路径。这是为了在编译时找到所有可用的资产。

样式表

默认情况下,已配置 ExtractTextPlugin。这意味着如果您 require 任何编译为 CSS(.css.less.scss)的文件,它将从编译的 JS 文件中删除并存储在单独的文件中。因此,您必须显式包含它。

请注意,当您提供入口点时,它通常仍然是 .js 文件(请参阅使用示例)。

如果您想禁用此功能,以便 CSS 与 JS 一起在单个请求中加载,请禁用 extract_css

maba_webpack:
    config:
        parameters:
            extract_css: false

如果您想直接将 css/less/sass 文件作为入口点,则需要此插件。

ES6、Less 和 Sass 支持

ES6、Less 和 Sass 无需配置即可使用

  • 使用 .js.jsx 扩展名,使用 Babel 将 ES6 和 ES7 编译为 ES5;
  • 使用 .less 扩展名编译 Less 文件;
  • 使用 .scss 扩展名编译 Sass 文件。

如果您需要任何自定义加载器,请随时使用 npm 安装它们,并在必要时修改 app/config/webpack.config.js

加载图像

默认情况下,使用 image-webpack-loader 对图像进行优化。

您可以使用相同的 webpack_asset 函数直接在 twig 模板中包含图像。

为了正确运行,图像文件的加载器必须保持您的 webpack 配置中的 file

<img src="{{ webpack_asset('@AcmeHelloBundle/Resources/images/cat.png') }}"/>

当然,您也可以在 CSS 中使用它们。

.cat {
    /* cat.png will be optimized and copied to compiled directory with hashed file name */
    /* URL to generated image file will be in the css output  */
    background: url("~@AcmeHelloBundle/Resources/images/cat.png")
}

如果您在 CSS 中提供 webpack 兼容的资产路径,请用 ~ 前缀。使用相对路径,如常。有关更多信息,请参阅 css-loader

别名

默认情况下,别名前缀为 @,指向特定的路径。您可以通过配置 aliases.prefix 参数来更改此前缀。

别名在 twig 模板(webpack_asset 函数的参数)和 JavaScript 文件(require 或类似 Webpack 提供的函数)中工作方式相同。

默认情况下,这些别名已注册

  • @app,指向 %kernel.root_dir%/Resources/assets
  • @root,指向 %kernel.project_dir%(通常是您的仓库根目录)
  • @templates,指向 %kernel.project_dir%/templates
  • @assets,指向 %kernel.project_dir%/assets
  • @AcmeHelloBundle 或类似为每个您的包。这指向包的根目录(Bundle 类所在的目录),与在 Symfony 中定位资源时相同
  • @acme_hello 或类似为每个您的包。默认情况下,这指向 @AcmeHelloBundle/Resources/assets

您也可以注册自己的别名,例如如果您使用任何这些包管理器,则 @bower@npm 是不错的选择。或者如果您使用 composer 安装前端资源,则类似 @vendor 也很合适。

maba_webpack:
    aliases:
        additional:
            npm: %kernel.root_dir%/node_modules     # or any other path where assets are installed
            bower: %kernel.root_dir%/bower
            vendor: %kernel.root_dir%/../vendor

在您的 JavaScript 文件内

var $ = require('@npm/jquery');

如果您想使用不同的前缀

maba_webpack:
    aliases:
        prefix: '%'
        additional:
            npm: %kernel.root_dir%/node_modules

现在在您的 JavaScript 文件内

var $ = require('%npm/jquery');

请确保在无法直接从网络上访问的路径上安装依赖项(无论是 npm、bower 还是其他)。Webpack 不需要这(它会编译它们 - 它们可以位于系统上的任何位置),并且可能导致安全漏洞(某些资源包含后端示例,这可能在您的生产环境中被潜在使用)。

配置

请参阅带解释的示例。

maba_webpack:
    enabled_bundles:
        - ApplicationBundle
    twig:
        additional_directories:
            - %kernel.root_dir%/Resources/partials
        suppress_errors:      true              # whether files not found or twig parse errors should be ignored
                                                # defaults to true in dev environment
                                                # defaults to "ignore_unkwowns" in prod - this option ignores
                                                #     unknown functions etc., but fails on syntax errors
                                                # set to false to always fail on any twig error
    config:
        path:                 '%kernel.root_dir%/config/webpack.config.js'
        parameters:           []        # additional parameters passed to webpack config file
                                        # for example, set dev_server_public_path and public_path to overwrite
                                            # //:8080/compiled/ and /compiled/
                                            # see inside your webpack.config.js for more info
        # set location of cached manifests. Useful for deploy, when you don't want to include your cache directory
        manifest_file_path:        '%kernel.cache_dir%/webpack_manifest.php'

    aliases:                            # allows to set aliases inside require() in your JS files
        path_in_bundle:       /Resources/assets     # this means that require('@acme_hello/a.js')
                                                    # will include something like
                                                    # src/Acme/Bundles/AcmeHelloBundle/Resources/assets/a.js
                                                    # see "Aliases" for more information
        prefix:               '@'           # configure default prefix to be added to aliases.
        additional:           []            # provide any other aliases, prefix is always added automatically
    bin:
        webpack:
            executable: # how maba:webpack:compile executes webpack
                        # should be array, for example ['/usr/bin/node', 'node_modules/webpack/bin/webpack.js']
                - node_modules/.bin/webpack
            arguments:        []        # additional parameters to pass to webpack
                                        # --config with configuration path is always passed
        dev_server:
            executable: # how maba:webpack:dev-server executes webpack-dev-server
                - node_modules/.bin/webpack-dev-server
            arguments:  # additional parameters to pass to webpack-dev-server; these are default ones
                - --hot
                - --history-api-fallback
                - --inline
        disable_tty: false      # disables TTY setting. Defaults to false in dev environment, true in others.
                                # TTY is needed to run dashboard and/or to display colors, but does not work
                                # in some environments like AWS
        working_directory: %kernel.root_dir%/..
        
    dashboard:                  # configuration for dashboard plugin - only works when TTY available
        enabled: dev_server     # `always` for both compile and dev-server, `false` to disable
        executable:
            - node_modules/.bin/webpack-dashboard

配置 dev-server

app/console maba:webpack:dev-server 以独立进程运行 webpack-dev-server,它监听在 localhost:8080。默认情况下,开发环境中的资源指向 //:8080/compiled/*

如果您在 VM、docker 容器等内部运行此命令,请配置 maba_webpack.config.parameters.dev_server_public_path 以使用正确的宿主。此外,由于 dev-server 默认只监听 localhost 连接,请将以下内容添加到配置中

maba_webpack:
    bin:
        dev_server:
            arguments:
                - --hot                     # these are default options - leave them if needed
                - --history-api-fallback
                - --inline
                - --host                    # let's add host option
                - 0.0.0.0                   # each line is escaped, so option comes in it's own line
                - --public                  # this is also needed from webpack-dev-server 2.4.3
                - dev-server-host.dev:8080  # change to whatever host you are using
    config:
        parameters:                         # this is where the assets will be loaded from
            dev_server_public_path: //dev-server-host.dev:8080/compiled/
            dev_server: {}                  # any additional parameters to pass to `devServer` configuration

如果您需要提供不同的端口,请确保将 --port 和端口号本身放在单独的行上。

当使用 webpack-dev-server 编译资源时,使用 webpack-dashboard 以获得更友好的用户体验。您可以通过将 tty_prefix 选项设置为 [] 来禁用它。您还可以在这种情况下从 webpack.config.js 中删除 DashboardPlugin

配置 Node.js 的内存

如果您在运行 maba:webpack:compile 和/或 maba:webpack:dev-server 时遇到“堆内存不足”错误,请尝试为 Node.js 进程提供更多内存。

maba_webpack:
    bin:
        webpack:        # same with dev_server
            executable:
                - node
                - "--max-old-space-size=4096"   # 4GB
                - node_modules/webpack/bin/webpack.js

使用公共块

此包支持单个和多个 公共块,但您必须明确配置此功能。

在您的 webpack.config.js

config.plugins.push(
    new webpack.optimize.CommonsChunkPlugin({
        name: 'commons'
    })
);

在您的基模板中

{% webpack named css 'commons' %}
    <link rel="stylesheet" href="{{ asset_url }}"/>
{% end_webpack %}
{# ... #}
{% webpack named js 'commons' %}
    <script src="{{ asset_url }}"></script>
{% end_webpack %}

您也可以使用 webpack_named_asset twig 函数来替代 webpack 标签。

分组公共块

webpack 标签支持 group 选项

{% webpack js '@app/admin-init.js' group='admin' %}
    <script src="{{ asset_url }}"></script>
{% end_webpack %}

资源名称在 options.groups 中给出,它传递到您的 webpack.config.js。未设置组的资源被分配到 default 组。配置示例

config.plugins.push(new webpack.optimize.CommonsChunkPlugin({
    name: 'admin_commons_chunk',
    chunks: options.groups['admin']
}));
config.plugins.push(new webpack.optimize.CommonsChunkPlugin({
    name: 'front_commons_chunk',
    chunks: options.groups['default']
}));

请注意,目前同一个入口点不能属于多个组,即使它在不同的地方使用。这意味着您必须为同一资源的 JavaScript 和 CSS 版本提供相同的组。

关于包继承的说明

如果您使用具有继承的包,请注意,这些资源本身通常在不同的上下文中解析(在webpack本身中),指向父包(通过其别名)的资源实际上会指向子包。这允许您覆盖父包中的任何资源,但需要复制所有资源,因为它们根本不会在父包目录中查找。

语义化版本控制

此包遵循语义化版本控制

此包的公共API(换句话说,如果您想轻松更新到新版本,则应仅使用这些功能)

  • 只有未标记为public="false"的服务
  • 只有标记有@api的类、接口和类方法
  • twig函数和标签
  • 控制台命令
  • 支持的DIC标签

例如,如果只有类方法标记为@api,则不应扩展该类,因为构造函数可能在任何版本中更改。

有关API中可以更改和不能更改的基本信息,请参阅Symfony BC规则。请注意,在此包中,默认情况下所有内容都是@internal

更新此包后,您应重新运行maba:webpack:setup命令并审查文件中的更改,将它们合并到您自己的文件中。此包可能假设已安装所有所需的依赖项。由于编译是在部署步骤之前进行的,因此您应注意到在预发布环境中可能出现的任何错误。

替代方案?

有几种方法可以集成webpack。

简单的webpack命令

我强烈建议这种方法 - 仅将前端代码(HTML、CSS、JS)与后端代码(PHP + 一些HTTP API)分开。

特别是如果您有单页应用程序,将webpack工作流程与Symfony集成几乎没有意义。

在这种情况下,您可以使用html-webpack-plugin生成包含正确URL的HTML文件,以便指向打包的javascript文件。

ju1ius/WebpackAssetsBundle

这是一个最小的包,用于将编译后的文件名提供给您的twig模板。它还使用了assets-webpack-plugin

与此包相比缺少的功能 - 收集所有入口点。您必须手动在webpack配置中设置它们。如果只有少数几个,通常不难维护。

Webpack配置完全是手动的,并且不与您的Symfony应用程序集成。

hostnet/webpack-bundle

此包收集所有入口点,但不会提供用于在twig模板中使用的生成URL。它通过添加修改时间戳来解决缓存失效问题。

Webpack配置完全集成到您的Symfony应用程序中,并且需要自定义PHP代码进行任何自定义配置更改。

在开发环境中,它在请求时生成资产。这可能比在后台运行特定命令更方便,但通常速度较慢。此外,此时很难将其与webpack-dev-server集成。

它有更多的twig标签,如内联脚本。一个例子是内联splitpoint生成,它允许您为每个文件生成简单的splitpoints。

运行测试

Travis status

composer install
vendor/bin/codecept run