ssch/typo3-encore

在TYPO3环境中使用Webpack Encore

安装次数: 296,666

依赖项: 4

建议者: 0

安全: 0

星标: 106

关注者: 8

分支: 19

开放问题: 13

类型:typo3-cms-extension

v5.0.6 2023-05-15 14:04 UTC

README

Downloads

将TYPO3与Webpack Encore集成!

此扩展允许您通过读取entrypoints.json文件并帮助您渲染所有动态的scriptlink标签来使用Webpack Encore的splitEntryChunks()功能。

composer require ssch/typo3-encore

如何使用

  1. 首先,按照文档中的说明安装Webpack Encore。您应该能够使用文档中描述的所有功能。例如Sass-Loader、Vue-Loader等。这些功能完全独立于这个小扩展。

您还可以使用文件的enableVersioning()功能(通常仅在生产环境中使用)。您还可以使用enableIntegrityHashes()。这将考虑是否包含文件。

  1. 在webpack.config.js中定义您的入口路径(通常为您的Package扩展中的Resource/Public/文件夹)和输出路径。

  2. 之后,将两个TypoScript常量设置为指向配置的输出文件夹中位于manifest.json和entrypoints.json的位置。

plugin.tx_typo3encore {
    settings {
        entrypointJsonPath = EXT:typo3_encore/Resources/Public/entrypoints.json
        manifestJsonPath = EXT:typo3_encore/Resources/Public/manifest.json
    }
}
  1. 然后,您可以在页面模板/布局中使用ViewHelpers将CSS和JS文件集成到您的网站中。
{namespace encore = Ssch\Typo3Encore\ViewHelpers}

<encore:renderWebpackLinkTags entryName="app"/>
<encore:renderWebpackScriptTags entryName="app"/>

如果您定义了多个入口,您可以在ViewHelpers中定义所需的entryName。

{namespace encore = Ssch\Typo3Encore\ViewHelpers}

<encore:renderWebpackLinkTags entryName="secondEntryName"/>
<encore:renderWebpackScriptTags entryName="secondEntryName"/>

或者,您也可以通过TypoScript包含文件

page.includeCSS {
    # Pattern typo3_encore:entryName
    app = typo3_encore:app
    # If you want to ensure that this file is loaded first uncomment the next line
    # app.forceOnTop = 1
}

page.includeJS {
    # Pattern typo3_encore:entryName
    app = typo3_encore:app
    # If you want to ensure that this file is loaded first uncomment the next line
    # app.forceOnTop = 1
}

page.includeJSFooter {
    # Pattern typo3_encore:entryName
    app = typo3_encore:app
}

注意前缀typo3_encore:这对于正确渲染文件很重要。然后,您可以使用所有其他已知设置来包含您的文件。

您不需要担心只包含一次。除非您想要,否则这不会在一个请求周期中发生。

您还可以在特定的后端上下文中使用通过前缀typo3_encore的包含。例如,如下所示

<f:be.container includeCssFiles="{0: 'typo3_encore:backend'}" includeJsFiles="{0: 'typo3_encore:backend'}">

</f:be.container>

HTTP/2 预加载

此扩展管理的所有CSS和JavaScript文件将在渲染过程中添加到AssetRegistry类中。对于这些资源,将创建一个Link HTTP头,这是在使用HTTP/2和现代网络浏览器的预加载功能时优化应用程序性能的关键。

技术上这是通过PSR-15 Middleware实现的。

如果您想向AssetRegistry添加其他文件,可以使用PreloadViewHelper。

{namespace encore = Ssch\Typo3Encore\ViewHelpers}

<encore:preload attributes="{type: 'font/woff2', crossOrigin: 'anonymous'}" as="font" uri="{encore:asset(pathToFile: 'EXT:typo3_encore/Resources/fonts/webfont.woff2')}" />

注意,示例还使用了AssetViewHelper。AssetViewHelper在幕后会查找manifest.json文件。因此,您也可以利用Webpack提供的版本控制功能。

静态资源

有时您可能需要在流体模板中直接引用静态资源(如图像文件)。您可以使用Encore的copyFiles函数来指示Webpack将静态资源复制到您的输出文件夹(请参阅https://symfony.ac.cn/doc/current/frontend/encore/copy-files.html#referencing-image-files-from-a-template)。

然后,您可以使用AssetViewHelper从流体模板中引用静态资源文件以获取文件路径(如果启用版本控制,包括哈希)。

请注意,AssetViewHelper不会渲染任何内容,只是返回文件路径,因此您可能需要使用内联标记来显示图像等。

{namespace encore = Ssch\Typo3Encore\ViewHelpers}


<img class="my-image" src="{encore:asset(pathToFile: 'EXT:my_extension/Resources/Public/Build/images/my_image.jpg')}" alt="My image" />

使用AssetViewHelper的方式与在Symfony的Twig模板中使用的asset函数类似。

其他

  1. 如果在生产模式下设置了enableVersioning(true),则应设置选项
$GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename'] = ''
  1. 定义多个Webpack配置(查看

然后您需要在TypoScript-Setup中定义您的构建

plugin.tx_typo3encore {
    settings {
        builds {
            firstBuild = EXT:typo3_encore/Resources/Public/FirstBuild
            secondBuild = EXT:typo3_encore/Resources/Public/SecondBuild
        }
    }
}

最后,您可以指定要使用哪个构建

page.includeCSS {
    # Pattern typo3_encore:buildName:entryName
    app = typo3_encore:firstBuild:app
}
{namespace encore = Ssch\Typo3Encore\ViewHelpers}

<encore:renderWebpackLinkTags entryName="app" buildName="firstBuild"/>

CKEditor的CSS

可以配置Encore,以便您可以使用由Webpack生成的CSS文件来为CKEditor提供样式,即使启用了版本控制也可以。为此需要两步操作

  1. webpack.config.js中为RTE定义入口点,例如:
Encore
    .addStyleEntry('rte', './assets/rte.scss')
  1. 在CKEditor的yaml配置中添加
editor:
  config:
    contentsCss: "typo3_encore:rte"

Webpack Encore入门指南

尽管Webpack Encore的文档很棒,但我将提供一个简约的安装前端相关内容的指南。我假设您对现代前端开发有一些基本了解。

通过Yarn或Npm将Encore安装到您的项目中

首先,确保您已安装Node.js以及Yarnnpm包管理器。

yarn add @symfony/webpack-encore --dev

此命令创建或修改package.json文件,并将依赖项下载到node_modules/目录中。Yarn还会创建/更新yarn.lock(如果您使用npm,则称为package-lock.json)。

应将package.json和yarn.lock(如果使用npm,则为package-lock.json)提交到版本控制,但忽略node_modules/文件夹。

创建webpack.config.js文件

接下来,我们将在项目的根目录中创建一个webpack.config.js文件。这是Webpack和Webpack Encore的主要配置文件。

var Encore = require('@symfony/webpack-encore');

Encore
    // the directory where compiled assets will be stored
    .setOutputPath('public/typo3conf/ext/my_sitepackage/Resources/Public/')

    // public path used by the web server to access the output path
    .setPublicPath('/typo3conf/ext/my_sitepackage/Resources/Public/')

    // only needed for CDN's or sub-directory deploy
    // .setManifestKeyPrefix('build/')

    // Copy some static images to your -> https://symfony.ac.cn/doc/current/frontend/encore/copy-files.html
    .copyFiles({
        from: './src/images',
        // Optional target path, relative to the output dir
        to: 'images/[path][name].[ext]',
        includeSubdirectories: false,
        // if versioning is enabled, add the file hash too
        to: 'images/[path][name].[hash:8].[ext]',
        // only copy files matching this pattern
        pattern: /\.(png|jpg|jpeg)$/
    })

    /*
     * ENTRY CONFIG
     *
     * Add 1 entry for each "page" of your app
     * (including one that's included on every page - e.g. "app")
     *
     * Each entry will result in one JavaScript file (e.g. app.js)
     * and one CSS file (e.g. app.css) if you JavaScript imports CSS.
     */
    .addEntry('app', './src/js/app.js')
    .addEntry('homepage', './src/js/homepage.js')

    // will require an extra script tag for runtime.js
    // but, you probably want this, unless you're building a single-page app
    .enableSingleRuntimeChunk()

    .cleanupOutputBeforeBuild()
    .enableSourceMaps(!Encore.isProduction())

    // enables hashed filenames (e.g. app.abc123.css)
    .enableVersioning(Encore.isProduction())

    // uncomment if you use TypeScript -> https://symfony.ac.cn/doc/current/frontend/encore/typescript.html
    // .enableTypeScriptLoader()

    // uncomment if you are using Sass/SCSS files -> https://symfony.ac.cn/doc/current/frontend/encore/css-preprocessors.html
    // .enableSassLoader()

    // uncomment if you're having problems with a jQuery plugin -> https://symfony.ac.cn/doc/current/frontend/encore/legacy-applications.html
    // .autoProvidejQuery()

    // uncomment if you use the postcss -> https://symfony.ac.cn/doc/current/frontend/encore/postcss.html
    // .enablePostCssLoader()


    // uncomment if you want to use vue -> https://symfony.ac.cn/doc/current/frontend/encore/vuejs.html
    // .enableVueLoader()

    // uncomment if you´re want to lint your sources
    // .enableEslintLoader()

    // uncomment if you´re want to have integrity hashes for your script tags, the extension takes care of it
    // .enableIntegrityHashes()

    // uncomment if you´re want to share general code for the different entries -> https://symfony.ac.cn/doc/current/frontend/encore/split-chunks.html
    // .splitEntryChunks()
    ;

// Uncomment if you are going to use a CDN -> https://symfony.ac.cn/doc/current/frontend/encore/cdn.html
// if (Encore.isProduction()) {
    //Encore.setPublicPath('https://my-cool-app.com.global.prod.fastly.net');

    // guarantee that the keys in manifest.json are *still*
    // prefixed with build/
    // (e.g. "build/dashboard.js": "https://my-cool-app.com.global.prod.fastly.net/dashboard.js")
    // Encore.setManifestKeyPrefix('build/');
// }

module.exports = Encore.getWebpackConfig();

使用typo3/cms-composer-installers 4+或TYPO3 12

typo3/cms-composer-installers库负责将TYPO3特定的资产移动到基于Composer的安装的正确位置,例如将扩展复制到typo3conf/ext。从版本4.0开始(目前处于RC1阶段),扩展将保留在vendor/vendor_name中。每个扩展的Resources/Public目录通过hash从public/assets目录进行符号链接。虽然可以针对符号链接,但由于它是hash,因此可能会有些不稳定。

建议使用另一个位于扩展之外的构建目录。例如,假设您使用public/build,则需要在webpack.config.js中的配置修改如下:

var Encore = require('@symfony/webpack-encore');

Encore
    .setOutputPath('../../public/build')
    .setPublicPath('/build')
    ...

必须相应地修改TypoScript常量

plugin.tx_typo3encore {
    settings {
        # These paths are relative to the web root (public) directory
        entrypointJsonPath = build/entrypoints.json
        manifestJsonPath = build/manifest.json
    }
}

如果站点base配置(config/sites/yoursite/config.yaml)是您的域的子目录/子路径,则需要将您的新“构建”目录添加为附加的绝对目录。这可以在您的“配置安装全局选项”中完成(TYPO3 <= 11: typo3conf/LocalConfiguration.php;TYPO3 >= 12: config/system/settings.php

    [FE][additionalAbsRefPrefixDirectories]: build

Webpack插件的领域

Encore已经预装了许多用于日常工作的实用插件。但总有一天您会需要更多。

生成图标并自动注入

安装webapp-webpack-pluginhtml-webpack-plugin

const WebappWebpackPlugin = require('webapp-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

Encore.addPlugin(new HtmlWebpackPlugin(
            {
                inject: false,
                minify: false,
                template: 'public/typo3conf/ext/typo3_encore/Resources/Private/Templates/Favicons.html',
                filename: 'favicons.html',
            }
        ))
        .addPlugin(new WebappWebpackPlugin({
            inject: htmlPlugin => htmlPlugin.options.filename === 'favicons.html',
            logo: './src/images/logo.png',
            force: true,
            favicons: {
                start_url: null,
                lang: null,
                icons: {
                    android: true,
                    appleIcon: true,
                    appleStartup: true,
                    windows: true,
                    yandex: true,
                    favicons: true,
                    coast: true,
                    firefox: true,
                    opengraph: false,
                    twitter: false
                }
            }
        }))

为了在TYPO3的头部注入HTML文件,只需包含模板文件即可

page.headerData.2039 = FLUIDTEMPLATE
page.headerData.2039 {
    file = EXT:typo3_encore/Resources/Public/favicons.html
}

生成SVG精灵

安装svg-sprite-loader

const SpritePlugin = require('svg-sprite-loader/plugin');

Encore.addLoader({
    test: /\src\/icons\/.svg$/,
    loader: 'svg-sprite-loader',
    options: {
        extract: true,
    }
}).addPlugin(new SpritePlugin())

现在您需要在JavaScript中导入所有SVG文件

function requireAll(r) {
    r.keys().forEach(r);
}
requireAll(require.context('./relative-path-to-svg-folder/svg-sprite/', true, /\.svg$/));

此扩展程序附带SvgViewHelper,以简化在Fluid中使用SVG的方法。

{namespace encore = Ssch\Typo3Encore\ViewHelpers}

<encore:svg title="Title" description="Description" src="EXT:typo3_encore/Resources/Public/sprite.svg" name="icon-fax-contact"/>