hostnet/webpack-bundle

此包已被弃用且不再维护。未建议替代包。

整合 Webpack 和 Symfony

安装次数: 41,098

依赖者: 0

建议者: 0

安全: 0

星标: 67

关注者: 8

分支: 18

公开问题: 4

类型:symfony-bundle

2.0.8 2020-03-23 08:10 UTC

README

弃用

此包已被弃用。请使用替代工具,如

hostnet/webpack-bundle

简介

本包假设您已经具备一些关于webpack的基本知识;它是什么以及它为您做了什么。如果不是这样,请先阅读此内容。这只需要一分钟,但值得。

本包不是将所有与包相关的资产放在一个位置,而是处理来自两个不同位置的资产。做出这个决定的原因是因为webpack的资产是在服务器上编译的,不应从浏览器访问。

  • Resources/assets 包含由webpack编译的文件。
  • Resources/public 包含符号链接或复制到 /<dump_path>/<lowercased_bundle_name>/ 的资产

当在 调试模式 下运行时,这两个目录都会被监视。当资产被添加、修改或删除时,编译源将直接更新。

本包包含两个 twig 函数

  • webpack_asset(url) : 解析编译后的资产文件。例如:webpack_asset('@AppBundle/app.js') 解析为 AppBundle 中的 Resources/assets/app.js
  • webpack_public(url): 解析从 Resources/public 目录中导出的公共资产。包引用的方式与 webpack_asset 相同。

请注意,webpack_asset 返回一个包含两个键的数组:jscss。更多关于此的信息可以在 快速入门 示例中找到。

安装

使用 composer 进行安装。

"require" : {
    "hostnet/webpack-bundle" : "1.*"
}

安装后,在 AppKernel 类中启用包 Hostnet\Bundle\WebpackBundle\WebpackBundle

警告:为了使webpack twig标签能够检测编译文件,webpack必须已经编译。因此,在缓存预热之前必须运行编译命令 webpack:compile

升级到 2.0

由于Twig的一些破坏性更改,webpack-bundle 2.0 已发布以与新的twig版本兼容。

为了确保平稳升级,请确保您的项目中具有以下内容

  • PHP 7.1 或更高版本
  • Symfony 3.3.0 或更高版本
  • Twig 2.4.0 或更高版本

本版本没有进行配置更改。如果您的项目使用上述版本,则在升级webpack-bundle到2.0时不应遇到任何问题。

以下版本中进行了以下额外更改:

  • 使用PHP 7严格类型声明
  • 使用命名空间化的Twig类,这些类是在Twig 2.4中引入的,以支持未来兼容性(例如使用\Twig\Environemnt而不是\Twig_Environment
  • 使用phpcs强制执行代码风格,并强制执行Hostnet指定的额外规则集
  • 由于我们的代码风格规则强制执行,将类CSSLoader重命名为CssLoader
  • 现在,用于内联javascript/css源文件的生成文件名来自TokenStream->getSourceContext()->getName()而不是TokenStream->getFilename()。后者函数已被从Twig中删除
  • 创建FCQN服务并添加别名以确保向后兼容
  • 使捆绑包与Symfony (3.)4兼容

快速入门

警告:默认情况下,该包假定nodewebpack以及任何其他模块已预安装在您的系统上。如果情况不是这样,您需要在启用捆绑包后,在您的config.yml文件中指定一些配置。有关更多详细信息,请参阅节点配置

想象一下,在您的应用程序中有以下文件

  • src/AppBundle/Resources/assets/app.js
  • src/AppBundle/Resources/assets/image.js
  • src/AppBundle/Resources/public/images/logo.png
  • src/AppBundle/Resources/views/base.html.twig

让我们从twig模板开始。

{# src/AppBundle/Resources/views/base.html.twig #}

The quick variant:
<script src="{{ webpack_asset('@AppBundle/app.js').js }}"></script>

The more maintainable variant: Store the result to a variable for easy access.
{% set asset = webpack_asset('@AppBundle/app.js') %}

<script src="{{ asset.js }}"></script>
{% if asset.css is not empty %}
    <link rel="stylesheet" href="{{ asset.css }}">
{% endif %}

在模板中使用twig函数webpack_asset(url)指定一个入口点。简而言之,入口点是一个将被编译并导出到输出路径的资产。此路径默认为%kernel.root_dir%/../web。默认情况下,编译后的文件将命名为app_bundle.app.js。这两个设置都是可配置的。

webpack_asset返回一个包含两个键的数组:js引用编译后的javascript文件,css引用编译后的css文件。请注意,如果此文件不存在,则css元素可能为空。后者会在引用的javascript文件(或其依赖项)不包含任何CSS类型文件时发生。

// src/AppBundle/Resources/assets/app.js
var image = require('@AppBundle/image.js');
document.write(image('/bundles/app/images/logo.png'));

任何webpack资产都可以使用webpack提供的requiredefine函数。Webpack允许以CommonJS和AMD样式加载文件。如您所注意到的,上面的示例通过简写名称@AppBundle引用了一个捆绑包。捆绑包会自动为您代理跟踪捆绑包,因此您可以在整个应用程序中自由使用此方法来引用依赖项。

位于Resources/public目录中的logo.png文件将自动软链接或复制到/<dump_path>/<lowercased_bundle_name>。您应将任何不需要处理的文件放置在公共目录中,以避免在调试模式(app_dev)中产生不必要的加载时间。

这是一个简单的图像模块,它返回一个图像HTML标签字符串。

// src/AppBundle/Resources/assets/image.js
module.exports = function (src) {
    return '<img src="' + src + '">';
};

Twig标签

除了webpack_asset twig函数外,您还可以使用webpack标签以更优雅的方式指定一个或多个入口点。此标签的语法如下

{% webpack <type: css|js> <list-of-javascript-files> %}
    {{ asset }}
{% endwebpack %}

或者,如果您想包含内联代码而不包含文件

{% webpack <type: inline> [file-type] %}
    <javascript, css, less, scss, ... code>
{% endwebpack %}

如果您想包含javascript文件,只需这样做

{% webpack js
   '@AppBundle/file1.js'
   '@AppBundle/file2.js'
%}
    <script src="{{ asset }}"></script>
{% endwebpack %}

或者内联版本

{% webpack inline %}
<script type="text/javascript">
    console.log("Hello world!");
</script>
{% endwebpack %}

相同的方法也可以应用于CSS文件。

{% webpack css '@AppBundle/file1.js' %}
    <link rel="stylesheet" href="{{ asset }}">
{% endwebpack %}

请注意,在CSS示例中,我们仍在引用JavaScript文件。这并不是一个错误。 Webpack从JavaScript文件中提取引用的CSS文件,并将它们放置在单独的CSS文件中 - 如果配置了这样做的话。如果您想包含一个已存在的CSS文件,只需使用常规方法即可。有关CSS文件导出的更多信息,请参阅CSS加载器配置

警告:由于分割点检测的特性,表达式不会被解析!只接受字符串类型。原因,如之前所述,是性能。所有Twing模板在调试模式下按请求进行标记化。仅标记化它们就比实际解析每一个都要快得多。

关于内联变体的更多信息

如上例所示,您可以可选地指定与inline类型一起的文件类型。这可以是任何类型的文件扩展名,只需确保您已启用相应的加载器。

例如,js默认情况下始终有效。但是,如果启用了css-loader,则css才有效。如果您已启用了less-loadersass-loader,您可以这样做:

Less版本

<section>
    {% webpack inline less %}
    <style>
    @color: #f00;
    @size: 42px;

    body {
        color: @color;
        section : {
            size: @size;
        }
    }
    </style>
    {% endwebpack %}
</section>

Sass版本

<section>
    {% webpack inline sass %}
    <style>
    $color: #f00;
    $size: 42px;

    body {
        color: $color;
        section : {
            size: $size;
        }
    }
    </style>
    {% endwebpack %}
</section>

编译器会自动去除<style>和/或<script>标签,并将块的正文保存到文件中。然后,该文件将通过使用指向编译文件的link标签或script标签来包含到模板中。

配置

此包的配置选项相当多,但所有设置都是可选的,并带有合理的默认值。

以下配置选项直接从webpack本身复制,并可以按照这种方式进行配置。需要注意的是,键是用下划线而不是驼峰命名法编写的。

例如,在webpack中配置output.publicPath设置将写作

webpack:
    output:
       public_path: '/public'

以下"webpack"部分可以通过config.yml进行配置

选项entryresolve.rootresolve.aliasresolveModule.modulesDirectories将根据分割点(入口点)、跟踪的包和指定的(或检测到的)node_modules目录自动配置。如果您指定了这些选项中的任何一个,其值将被附加到生成的值。

Node

为了使此包正常工作,它需要知道nodejs的安装位置以及在哪里可以找到其node_modules目录。如果node在您的服务器上全局安装,则可以省略此设置。

# config.yml
webpack:
    node:
        binary: '/path/to/node-binary'
        node_modules_path: '/path/to/node_modules'

多平台配置

由于您的应用程序可能同时运行在windows、linux和mac上,您可能需要指定不同的node二进制文件。如果是这种情况,您可以将一个字符串引用node二进制文件传递给node.binary选项,而不是传递一个数组。

webpack:
    node:
       binary:
          win32: 'C:\\path\\to\\node32.exe'
          win64: 'C:\\path\\to\\node64.exe'
          linux_x32: '/usr/bin/node32'
          linux_x64: '/usr/bin/node64'
          darwin: '/path/to/node'
          fallback: '/if/os/detection/fails/path/to/node'

再次强调,所有设置都是可选的。如果没有指定键,则默认为"node"。这仅当node全局安装时才有效。

包配置

默认情况下,所有启用的包都会被跟踪。但是,出于性能或安全原因,您也可以明确指定一组要跟踪的包。

webpack:
    bundles: ['AppBundle', 'YourBundle']

将应用程序资源添加到跟踪资产中

如果您决定将资源添加到app/Resources/assets,您只需要添加一个别名,然后就可以通过webpack加载机制进行加载。

webpack:
    resolve:
        alias:
            app: %kernel.root_dir%/Resources/assets
# can be loaded via
require('app/base.js');

共享依赖

如果指定了选项output.common_id,共享依赖将被写入一个独立的javascript或css文件。

例如,以下配置将输出一个shared.js和一个shared.css文件。

webpack:
    output:
        common_id: 'shared'

在您的模板中,您可以通过webpack_common_js()webpack_common_css()获取到您的公共javascript文件的路径。

<script src="{{ webpack_common_js() }}"></script>
<link rel="stylesheet" href="{{ webpack_common_css() }}">

{# will give the following output based on output.common_id #}
<script src="/compiled/shared.js"></script>
<link rel="stylesheet" href="/compiled/shared.css">

资产输出目录

  • 从"public"目录中导出的资产将链接或复制到<output.dump_dir>目录。
  • 从"assets"目录编译的资产将被写入到<output.path>目录。
  • twig函数webpack_asset返回以<output.public_path>目录为前缀的编译文件名。
webpack:
    output:
        path: '%kernel.root_dir%/../web/compiled/'
        dump_path: '%kernel.root_dir%/../web/bundles/'
        public_path: '/compiled/'

path值代表从客户端视角的资产路径。因此,它必须指定您的app(_dev).php的路径,例如,somedomain.com/my-web/app.php将使其变为%kernel.root_dir%/../web/my-app/compiled/,如上例所示。

如果output.path的值是%kernel.root_dir/../web/packed/,则必须将output.public_path的值设置为/packed/

理想配置

以下配置要求您的node_modules目录中存在以下模块。

  • extract-text-webpack-plugin
  • style-loader
  • css-loader
  • less-loader
  • sass-loader
  • url-loader
  • babel-loader
  • ts-loader

由于我们正在创建javascript文件的共享块,您需要手动在基本模板中包含'/compiled/shared.js'。对于CSS文件也是如此,具体取决于您包含的内容以及包含的位置。

config.yml

webpack:
    node:
        binary: '/path/to/node'
        node_modules_path: '%kernel.root_dir%/../node_modules'
    output:
        path: '%kernel.root_dir%/../web/compiled/'
        dump_path: '%kernel.root_dir%/../web/bundles/'
        public_path: '/compiled/'
        common_id: 'shared'
    loaders:
        css:
            all_chunks: true
            filename: '[name].css'
        less:
            all_chunks: true
            filename: '[name].css'
        sass:
            all_chunks: true
            filename: '[name].css'
        url: ~
        babel: ~
        typescript: ~

base.html.twig

<head>
    <script src="/compiled/shared.js"></script>
</head>

在您的twig模板的某个地方

{% webpack js "@YourBundle/SomeModule.js" %}
    <script src="{{ asset }}"></script>
{% endwebpack %}

{% webpack css "@YourBundle/SomeModule.js" %}
    <link rel="stylesheet" href="{{ asset }}">
{% endwebpack %}

编译超时

默认情况下,webpack只有60秒的时间来执行。在webpack需要更多时间的情况下,您可以更新compile_timeout选项。

webpack:
    compile_timeout: 60

加载器

加载器允许您require除javascript以外的文件。本包包含7个默认加载器。

  • CssLoader : 包含CSS文件
  • UrlLoader : 包含图片(转换为base64)
  • LessLoader : 包含less文件。
  • SassLoader : 包含sass文件。
  • BabelLoader : 包含ES6文件。
  • TypeScriptLoader: 包含TypeScript文件。
  • CoffeeScriptLoader: 包含CoffeeScript文件。

每个加载器在loaders部分下都有自己的配置。

CSS

启用加载CSS文件。

您需要 css-loaderstyle-loader 节点模块才能使此功能正常工作。

webpack:
    loaders:
        css:
            filename: '[name].css'
            all_chunks: true

如果省略了 filenameall_chunks,则任何 CSS 都会转换为文档中的 style 标签,而不是导出到单独的 CSS 文件中。如果指定了 output.common_id 设置(允许提取共享代码),则将自动使用 CommonsChunkPlugin

根据指定的配置,可能需要一个或多个节点模块。

  • enabled:true : style-loader, css-loader
  • filename : extract-text-webpack-plugin

Less

启用加载 less 文件。

此插件与 CSS 加载器具有完全相同的配置设置。

您需要 less-loadercss-loaderstyle-loader 节点模块才能使此功能正常工作。

webpack:
    loaders:
       less:
           filename: '[name].css'
           all_chunks: true

Sass

启用加载 sass 文件。

此插件与 CSS 加载器具有完全相同的配置设置。

您需要 sass-loadercss-loaderstyle-loader 节点模块才能使此功能正常工作。

webpack:
    loaders:
       sass:
           filename: '[name].css'
           all_chunks: true
           include_paths:
               - [include dirs for node-sass]

URL

将图像转换为 base64 代码,并将其嵌入到javascript中。

此插件仅有一个 enabled 设置。默认情况下是禁用的。

webpack:
    loaders:
       url: ~

Babel

Babel 加载器将 ECMAScript 6 代码转换为 ECMAScript 5 代码,允许它在旧浏览器中运行。加载器编译 .jsx 文件而不是 .js 文件,因为并非所有文件都需要编译。一旦 ES6 成为主流,您只需逐步将 JSX 文件重命名为 js 文件,一切应该仍然可以正常工作。

您需要 babel-loader 节点模块才能使此功能正常工作。

webpack:
    loaders:
        babel: ~

TypeScript

TypeScript 加载器将 TypeScript 2 代码转换为 JavaScript 代码,允许它在所有浏览器中运行。加载器编译 .ts 文件。

您需要 ts-loader 节点模块才能使用默认配置使此功能正常工作。

webpack:
    loaders:
        typescript: ~

您也可以配置自己的加载器

webpack:
    loaders:
        typescript:
            loader: some-other-typescript-loader

CoffeeScript

CoffeeScript 加载器将 CoffeeScript 转换为可移植的 (.js),允许 CoffeeScript 在每个浏览器中运行。加载器加载 .coffee 文件。

您需要 coffee-loader

webpack:
    loaders:
        coffee: ~

loader 字段可以指定任何其他 CoffeeScript 加载器,请参阅 TypeScript

插件

webpack-bundle 软件包提供了一个简单的方法来开发和使用插件。插件简单地向生成的 webpack 配置文件中写入一些代码,通过这样做,它应该可以启用更多功能。

DefinePlugin

Define 插件允许您在应用程序中声明全局变量。有关更多信息,请参阅 defineplugin 文档

以下示例中,假设有一个名为 "environment" 的参数,其值为 "dev"。

webpack:
    plugins:
        constants:
            ENVIRONMENT: %environment%

稍后,在某处资产...

// start
if (ENVIRONMENT === 'dev') {
    console.log('Hello World!');
}
// end

这些变量声明由 webpack 解析。一旦代码编译并压缩,这些变量将完全从最终代码中删除。

这意味着您的开发机器上的代码会产生类似这样的结果

// start
console.log('Hello World');
// end

在生产环境中

// start
// end

请注意,这些注释仅用于说明此示例。编译和压缩后的代码将不包含这些注释。

提供插件

自动加载模块并将其分配给全局变量,例如 $(用于jQuery)。有关更多信息,请参阅提供插件文档

在下面的示例中,假设您想通过 "$" 或 "jQuery" 访问 jQuery。您只需添加此配置,插件就会为您完成剩余工作。

plugins:
    provides:
        '$': 'jquery'
        'jQuery': 'jquery'

现在,您可以在内联脚本中添加您的 JavaScript 代码,Webpack 将自动为您要求 "jquery"。

{% webpack inline %}
<script type="text/javascript">
    $(function () {
        $('[data-toggle="tooltip"]').tooltip()
    })
</script>
{% endwebpack %}

重要

不要忘记通过 npm 安装 jQuery npm install jquery。由于所有 node_modules 都在 webpack.config.js 中解析,它将自动找到它。

UglifyJS

在 JS 输出上运行 UglifyJS,创建更小、更优化的 JS 文件。有关更多信息,请参阅uglifyjs 文档

plugins:
    uglifyjs:
        mangle_except: ['$super', '$', 'exports', 'require']  # Variable names to not mangle
        source_map: true             # Generate a source map for tracking errors in compressed files.
        test: '/\.js($|\?)/i'        # RegExp to filter processed files
        minimize: true               # Whether to minimize or not
        
        # Options to set which optimizations UglifyJS will perform.
        compress:
            sequences: true              # Join consecutive statements with the "comma operator"
            properties: true             # Optimize property access: a["foo"] → a.foo
            dead_code: true              # Discard unreachable code
            drop_debugger: true          # Discard "debugger" statements
            unsafe: false                # Perform unsafe optimizations
            conditionals: true           # Optimize ifs and conditional expressions
            comparisons: true            # Optimize comparisons
            evaluate: true               # Evaluate constant expressions
            booleans: true               # Optimize boolean expressions
            loops: true                  # Optimize loops
            unused: true                 # Drop unused variables/functions
            hoist_funs: true             # Hoist function declarations
            hoist_vars: false            # Hoist variable declarations
            if_return: true              # Optimize if-s followed by return/continue
            join_vars: true              # Join var declarations
            cascade: true                # Try to cascade `right` into `left` in sequences
            side_effects: true           # Drop side-effect-free statements
            warnings: false              # Warn about potentially dangerous optimizations/code

现在,当您的 JS 文件构建完成后,将使用 UglifyJS 进行压缩和优化。