Code Monkey home page Code Monkey logo

typo3_encore's Introduction

Downloads

TYPO3 integration with Webpack Encore!

This extension allows you to use the splitEntryChunks() feature from Webpack Encore by reading an entrypoints.json file and helping you render all of the dynamic script and link tags needed.

composer require ssch/typo3-encore

How to use

  1. First of all install Webpack Encore as stated in the documentation. You should really be able to use all of the things described in the documentation. Like Sass-Loader, Vue-Loader etc. These things are completely independent from this little extension.

You can also use the enableVersioning() of files (mostly used only in production context). You can also use the enableIntegrityHashes(). This is taking into account if the files are included.

  1. Define your entry path(s) and the output path (usually your Resource/Public/ folder in your Package extension) in the webpack.config.js

  2. Afterwards set the two TypoScript constants to point to the manifest.json and the entrypoints.json located in the configured output folder

plugin.tx_typo3encore {
    settings {
        entrypointJsonPath = EXT:typo3_encore/Resources/Public/entrypoints.json
        manifestJsonPath = EXT:typo3_encore/Resources/Public/manifest.json
    }
}
  1. In your Page templates/layout you can then use the ViewHelpers to integrate the CSS- and JS-Files in your website
{namespace encore = Ssch\Typo3Encore\ViewHelpers}

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

If you have defined multiple entries you can define the desired entryName in the ViewHelpers

{namespace encore = Ssch\Typo3Encore\ViewHelpers}

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

Alternatively you can also include the files via 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
}

Note the prefix typo3_encore: This is important in order to render the files correctly. You can then use all other known settings to include your files.

You don´t have to care about including it only once. This will not happen during one request cycle unless you want to.

It is also possible to use the inclusion via the prefix typo3_encore in backend specific contexts. For example like so:

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

</f:be.container>

HTTP/2 Preloading

All css and javascript files managed by the extension will be added to the AssetRegistry class during rendering. For these assets a Link HTTP header is created, which are the key to optimize the application performance when using HTTP/2 and preloading capabilities of modern web browsers.

Technically this is done by a PSR-15 Middleware.

If you want to add additional files to the AssetRegistry you can use the 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')}" />

Watch out, the example also uses the AssetViewHelper. The AssetViewHelper behind the scenes makes a look up to the manifest.json file. So you can also leverage the versioning feature provided by Webpack.

Static assets

Sometimes you might need to reference static assets (like image files) directly in your fluid templates. You can use the Encore copyFiles function to instruct Webpack to copy static assets to your output folder (see https://symfony.com/doc/current/frontend/encore/copy-files.html#referencing-image-files-from-a-template).

To reference a static asset file from a fluid template, you can then use the AssetViewHelper to get the file path (including the hash if versioning is enabled).

Note that the AssetViewHelper does not render anything but just returns the path to the file, so you will probably use inline notation to, e.g., display an image:

{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" />

This way of using the AssetViewHelper is similar to the asset function used in Twig templates with Symfony.

Additional

  1. If you are in production mode and set enableVersioning(true) then you should set the option
$GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename'] = ''
  1. Defining Multiple Webpack Configurations (see)

Then you have to define your builds in your TypoScript-Setup:

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

Finally, you can specify which build to use:

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

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

CSS for CKEditor

It is possible to configure encore so that you can use a CSS file for the CKEditor which is generated by webpack and even works with enabled versioning. Two steps are required to do so:

  1. Define an entrypoint for the RTE in your webpack.config.js, e.g.
Encore
    .addStyleEntry('rte', './assets/rte.scss')
  1. Add in the CKEditor yaml configuration
editor:
  config:
    contentsCss: "typo3_encore:rte"

Getting Started with Webpack Encore

Although the documentation of Webpack Encore is awesome, i am going to provide a minimalistic how to install the frontend related things. I assume some basic knowledge of modern frontend development.

Install Encore into your project via Yarn or Npm:

First, make sure you install Node.js and also the Yarn or npm package manager.

yarn add @symfony/webpack-encore --dev

This command creates or modifies a package.json file and downloads dependencies into a node_modules/ directory. Yarn also creates/updates a yarn.lock (called package-lock.json if you use npm).

You should commit package.json and yarn.lock (or package-lock.json if using npm) to version control, but ignore the node_modules/ folder.

Creating the webpack.config.js File

Next, we are going to create a webpack.config.js file at the root of our project. This is the main config file for both Webpack and 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.com/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.com/doc/current/frontend/encore/typescript.html
    // .enableTypeScriptLoader()

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

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

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


    // uncomment if you want to use vue -> https://symfony.com/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.com/doc/current/frontend/encore/split-chunks.html
    // .splitEntryChunks()
    ;

// Uncomment if you are going to use a CDN -> https://symfony.com/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();

Working with typo3/cms-composer-installers 4+ or TYPO3 12

The typo3/cms-composer-installers library takes care of moving TYPO3-specific assets in the right place in Composer-based installations, like copying extensions to typo3conf/ext. Starting with version 4.0 (currently at RC1 stage), the extensions will remain in vendor/vendor_name. The Resources/Public directory of each extension is symlinked from the public/assets directory using hashes. While it is possible to target the symlink, the fact that it is a hash makes it a bit flaky.

The recommendation is to use another build directory, not located inside an extension. As an example, asuming that you use public/build, the configuration in webpack.config.js would be modified as follows:

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

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

The TypoScript constants have to be modified accordingly:

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

If the site base configuration (config/sites/yoursite/config.yaml) is a subdirectory/subpath of your domain, it is required to add your new "build" directory as an additional absolute directory. This can be done in your "Configure Installation-Wide Options" (TYPO3 <= 11: typo3conf/LocalConfiguration.php; TYPO3 >= 12: config/system/settings.php)

    [FE][additionalAbsRefPrefixDirectories]: build

The realm of Webpack plugins

Encore already ships with a lot of useful plugins for the daily work. But someday you are gonna get to the point where you need more.

Generating icons and inject them automatically

Install webapp-webpack-plugin and html-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
                }
            }
        }))

In order to inject the html file in the header of your TYPO3 just include the template file:

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

Generating a svg sprite

Install 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())

Now you have to import all your svg files in your javascript

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

The extension ships with a SvgViewHelper in order to simplify the usage of svg in fluid.

{namespace encore = Ssch\Typo3Encore\ViewHelpers}

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

typo3_encore's People

Contributors

bjo3rnf avatar cweiske avatar dependabot[bot] avatar fpodschwadek avatar fsuter avatar georgringer avatar infabo avatar mueller-sebastian avatar rintisch avatar rvock avatar sabbelasichon avatar straschek-io avatar svenpet90 avatar thenaderio avatar tobi77 avatar websi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typo3_encore's Issues

Multiple Entrypoint.json

Maybe it is a conceptional problem on my part, but I have the following scenario:

I use Webpack Encore + Vue in some Backend Modules - in different standalone extensions. Right now I have to resort to squashing everything into one entry file (let's say mymodule.js and render that using the Page Renderer in my BE Module and I have to include a <script> Tag for the dev-server eith HMR as the PageRenderer struggles with http:// includes).

I'd love to use typo3_encore for this, but I already use it for my Frontend Build and therefore already have an entrypoints.json somewhere.

I can't include the BE sources in this as they are basically microbuilds for every different BE module.

It would therefore be awesome if I could specify multiple entrypoint.json instead of the single one in the constants. Then I could use typo3_encore to render my specific module entrypoints/manifests..

Am I missing something or could this be a useful feature request?

Order of includes changes when mixing typo3_encore and normal includes

When I have two CSS files on a page, the order is different when the first is included via typo3_encore and the other via TYPO3.

TypoScript without typo3 encore:

page {
	includeCSS {
		example = EXT:example/Resources/Public/static/example1.css
		example.disableCompression = 1
		example.excludeFromConcatenation = 1

		example2 = EXT:example/Resources/Public/static/example2.css
		example2.disableCompression = 1
		example2.excludeFromConcatenation = 1
	}
}

Output in HTML:

<link rel="stylesheet" href="/static/example1.css?1621689390">
<link rel="stylesheet" href="/static/example2.css?1621689423">

When the first CSS is included via typo3_encore:

page {
	includeCSS {
		example = typo3_encore:example1
		example = EXT:example/Resources/Public/static/example1.css
		example.disableCompression = 1
		example.excludeFromConcatenation = 1

		example2 = EXT:example/Resources/Public/static/example2.css
		example2.disableCompression = 1
		example2.excludeFromConcatenation = 1
	}
}

Now the order is different:

<link rel="stylesheet" href="/static/example2.css?1621689423">
<link rel="stylesheet" href="/static/example1.css">

This might break stuff, because the order is important.

This happens, because the PageRendererHooks::renderPreProcess adds the files at the end of the array instead of replacing the key.

The error also occurs with JavaScript files.

Using CSS for RTE in TYPO3 backend

Currently it's not possible to use CSS files generated by TYPO3 Encore as files for RTE.

The CSS for RTE is configured in Yaml-Files:

editor:
  config:
    # Include custom CSS
    contentsCss: "EXT:my_extension/Resources/Public/Css/rte.css"

TYPO3 Documentation for RTE
ckeditor Documentation regarding contentsCss

I would expect, that I can use typo3_encore:rte for the entrypoint rte. But this is not changed/processed by TYPO3 Encore.

I am not sure, if this is a bug or a feature request, because TYPO3 Encore should not be used for RTE CSS.

If it should work, I think the best way is to add a Form Data Provider, which changes the contentsCss value:

// ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord'][\Vendor\Example\Form\FormDataProvider\RichtextEncoreConfiguration::class] = [
	'depends' => [
		\TYPO3\CMS\Backend\Form\FormDataProvider\TcaText::class,
	],
];

The DataProvider could look like this:

<?php
declare(strict_types = 1);

namespace Vendor\Example\Form\FormDataProvider;

use Ssch\Typo3Encore\Asset\EntrypointLookupCollectionInterface;
use Ssch\Typo3Encore\Asset\EntrypointLookupInterface;
use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
 * Convert typo3_encore for contentCss
 */
class RichtextEncoreConfiguration implements FormDataProviderInterface {

	public function __construct(EntrypointLookupCollectionInterface $entrypointLookupCollection) {
		$this->entrypointLookupCollection = $entrypointLookupCollection;
	}

	/**
	 * @param array $result Given result array
	 * @return array Modified result array
	 */
	public function addData(array $result): array {
		foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
			if (empty($fieldConfig['config']['type']) || $fieldConfig['config']['type'] !== 'text') {
				continue;
			}

			if (!isset($fieldConfig['config']['enableRichtext']) || (bool)$fieldConfig['config']['enableRichtext'] !== true) {
				continue;
			}

			$rteConfiguration = $fieldConfig['config']['richtextConfiguration'];

			// replace contentsCss with correct path
			if ($rteConfiguration['editor']['config']['contentsCss']) {
				$contentsCss = $rteConfiguration['editor']['config']['contentsCss'];
				if (str_starts_with($contentsCss, 'typo3_encore:')) {
					// strip prefix
					$contentsCss = substr($contentsCss, strlen('typo3_encore:'));
					[$buildName, $entryName] = GeneralUtility::trimExplode(':', $contentsCss, true, 2);
					if (!$entryName) {
						$entryName = $buildName;
						$buildName = EntrypointLookupInterface::DEFAULT_BUILD;
					}

					$entryPointLookup = $this->entrypointLookupCollection->getEntrypointLookup($buildName);
					$contentsCss = $entryPointLookup->getCssFiles($entryName);
					$result['processedTca']['columns'][$fieldName]['config']['richtextConfiguration']['editor']['config']['contentsCss'] = $contentsCss;
				}
			}
		}

		return $result;
	}
}

Error on parsing new structure entrypoints.json

Since version 4 webpack-assets-manifest generate new structure:

⚠️ The structure of the entrypoints data has been updated to include preload and prefetch assets. Assets for an entrypoint are now included in an assets property under the entrypoint.

Example:

{
"entrypoints": {
"main": {
"assets": {
"css": [
"main.css"
],
"js": [
"main.js"
]
},
"prefetch": {
"js": [
"prefetch.js"
]
},
"preload": {
"js": [
"preload.js"
]
}
}
}
}

And typo3_encore don't parse this:

page.includeJS {
main = typo3_encore:main
}
page.includeCSS {
main = typo3_encore:main
}

HTTP/2 Push not working when using TYPO3 versioning

This issue is only related to dev-master.

When using $GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename'] = 'querystring', the frontend links assets with a version number added as query string. Since typo3-encore's middleware does not have the query string information at hand when creating the link HTTP-header, it's missing there. Thus, after downloading the document, the browser then loads the linked resource from the document, in addition to the pushed one because it treats them as two files.

In turn, disabling TYPO3 versioning in conjunction with active webpack versioning (changing filename) leads to problems with missing assets when using long-lasting (24h) document caching policies, because assets linked in the cached document are not available anymore on the server.

So ideally TYPO3 versioning by query string should be regarded when creating the push link. Or it must be disabled but then cannot not be used in conjunction with document caching.

Incompatibility with secure_downloads

If a TYPO3 installation has bitmotion/secure-downloads installed and the file is requested to download by an user an exception is thrown.
Asset manifest file "" does not exist.
in /typo3conf/ext/typo3_encore/Classes/Asset/JsonManifestVersionStrategy.php line 79

It seems like the needed TypoScript is not included.

allWrap should wrap all files for a single entrypoint

If I am using allWrap to wrap an entrypoint I might expect that the wrap is only generated once and wraps all script tags for a single entrypoint. That is currently not the case:

page {
    includeJS {
        example = typo3_encore:example1
        example.disableCompression = 1
        example.excludeFromConcatenation = 1
        example.allWrap = <!-- Before -->|<!-- After -->
    }
}

Generated HTML:

<!-- Before --><script src="/static/runtime.js"></script><!-- After -->
<!-- Before --><script src="/static/example1.js"></script><!-- After -->

Expected HTML:

<!-- Before --><script src="/static/runtime.js"></script>
<script src="/static/example1.js"></script><!-- After -->

This could be achieved, if the allWrap is split up into two parts and the first part is applied to the first script tag and the second part is applied to the last script tag like this:

page {
    includeJS {
        runtime = static/runtime.js
        runtime.disableCompression = 1
        runtime.excludeFromConcatenation = 1
        runtime.allWrap = <!-- Before -->|

        example1 = static/example1.js
        example1.disableCompression = 1
        example1.excludeFromConcatenation = 1
        example1.allWrap = |<!-- After -->
    }
}

Settings for Dev Hotreload server

For Dev Hotreload server i need set like this:

plugin.tx_typo3encore {
    settings {
        entrypointJsonPath = //dev.xxxxxx.com:8080/entrypoints.json
        manifestJsonPath = //dev.xxxxxx.com:8080/manifest.json
    }
}

By default this don't work.
How realize this idea?

Today iam use this hack:

[applicationContext == "Development"]
    page.includeJS {
        app = //dev.xxxxxx.com:8080/js/app.js
#       app = typo3_encore:app
        app.type = module
        app.external = 1
    }
    page.includeCSS {
    }
[end]

Specific configuration may break css classes

TYPO3 version: 10.4.18
Ext. version: 3.0.9

A maybe common configuration of this ext might lead to adding "/" prefix to attribute values.
Assuming there is an encore config that writes files to the js/ directory (see example below) inside the Resources/Public folder. When there is a css class named "js-toggle", that class would become "/js-toggle".
This is because of the Ssch\Typo3Encore\Asset\TagRenderer::addAdditionalAbsRefPrefixDirectories method.
I'm not quite sure, what this method should actually archive (except the obvious adding the relative path to additionalAbsRefPrefixDirectories) so I cannot provide a fix for this.

Steps to reproduce:

  1. Configure to write a JavaScript file to Resources/Public/js
  2. Add a class attribute so some element and put "js-toggle" in it (it needs to be the first class in it)
  3. When calling the page in the frontend, the class attribute will look like class="/js-toggle"

Example webpack configuration:

const Encore = require('@symfony/webpack-encore');
if (!Encore.isRuntimeEnvironmentConfigured()) {
  Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}
Encore
    .setOutputPath('packages/site/Resources/Public')
    .setPublicPath('/typo3conf/ext/site/Resources/Public')
    .setManifestKeyPrefix('');
Encore.addEntry('js/app', './packages/site/Resources/Private/Build/js/app.js');
module.exports = Encore.getWebpackConfig();

Viewhelper to generate Preload-Links to generated fonts

I would like to create preload links in my page's <head> to preload e.g. fonts which are deeply nested within my CSS and would therefore be loaded quite late.

Example:
<link rel="preload" href="fonts/cicle_fina-webfont.woff2" as="font" type="font/woff2" crossorigin>
(taken from here)

Unfortunately when using webpack-encore in production mode, font files are versioned, so the path to the built font asset cannot be hard-coded.

That's why it would be very useful to have a ViewHelper which I could feed e.g. the original file path and then it looks up the actual path to the built font and renders the link tag dynamically.

Note: Currently, as a workaround, I disabled versioning for fonts in my webpack.config to be able to hard-code preload tags.

    // disable versioning for fonts to allow preloading
    .configureFilenames({
        fonts: 'fonts/[name].[ext]'
    })

The build "_default" is not configured

Dear Sebastian,

I follwed your usage instructions step by step and I was able to run the encore command, outputting the compiled files. Unfortunately, when rendering the frontend of my TYPO3 site, an exception is thrown:

The build "_default" is not configured

Ssch\Typo3Encore\Asset\UndefinedBuildException thrown in file
/var/www/html/private/typo3conf/ext/typo3_encore/Classes/Asset/EntrypointLookupCollection.php in line 57.

Where has a "build" to be created and what does a "build" look like? Is it a folder or a file? I tried configuring it in the plugin settings and referencing to a EXT:EXTENSIONNAME/Resources/Public folder, but it still said that this build is not configured.

Thanks in advance,

Christian Rohleder

runtime.js is included at the wrong location

I have two JavaScript entrypoints. One in the header via includeJSLibs and one in the footer via includeJSFooter. Both Entrypoints require runtime.js. But this file is only included in the footer.

entrypoints.json

{
    "entrypoints": {
        "example1": {
            "js": [
                "/static/runtime.js",
                "/static/example1.js"
            ]
        },
        "example2": {
            "js": [
                "/static/runtime.js",
                "/static/example2.js"
            ]
        }
    }
}

TypoScript

page {
    includeJSLibs {
        example = typo3_encore:example1
        example.disableCompression = 1
        example.excludeFromConcatenation = 1
    }

    includeJSFooter {
        example2 = typo3_encore:example2
        example2.disableCompression = 1
        example2.excludeFromConcatenation = 1
    }
}

Generated HTML:

<!DOCTYPE html>
<html lang="en">
    <head>
    <script src="/static/example1.js"></script>
    </head>
    <body>
        <script src="/static/runtime.js"></script>
        <script src="/static/example2.js"></script>
    </body>
</html>

This is incorrect. runtime.js should only be included once, but in the header.

TYPO3 8.7 - Error in BackendModule (or nothing included, depending on method)

When I try to include js/css via EXT:typo3_encore in a BackendModule I get the following error (TYPO3 8.7):

#1476107295: PHP Warning: file_get_contents(/var/www/html/htdocs/typo3/typo3temp/assets/compressed/external-77c5661ecec798f0ac007291224fa800): failed to open stream: No such file or directory in /var/www/html/vendor/typo3/cms/typo3/sysext/core/Classes/Resource/ResourceCompressor.php line 287 (More information)

Happens using any of the methods mentioned below:

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

</f:be.container>

and

$pageRenderer->addJsFooterFile('typo3_encore:tx_myext_backendModule:backend-module')

If I try to include it using the ViewHelpers - nothing at all gets included:

<e:renderWebpackScriptTags entryName="backend-module" buildName="tx_myext_backendModule"></e:renderWebpackScriptTags>

TypoScript Setup (ext_typoscript_setup.txt):

module.tx_typo3encore {
	settings {
		builds {
			tx_myext_backendModule = EXT:my_ext/Resources/Public/Build
		}
	}
}

It does try to look it up, when I set an invalid build name or entryPoint the extension throws an exception like expected.

Any ideas?

Add option to select assets for http/2 push

In current dev-master, all entry point files are being pushed. However, if I use different entry points on one page, for example one which is critical and another one which is not, I would like an option to select which assets shall be pushed. Another use case is that I might want css to be pushed but not js.

So maybe an option to enable/disable pushing for an asset would be nice. This could be achieved by defining a boolean, e.g. enableHttp2Push (which defaults to true) that can be passed as "false" to additionalParameters in the ViewHelper to disable it.

Document the cache

thanks for the extension! one thing should be highlighted in the docs is the usage of the caching framework. switching different modes like dev, hotreload, production on same environment will lead to a broken frontend because the cache will still hold the previous paths which won't exist anymore.

One option is to use

$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][\Ssch\Typo3Encore\Integration\CacheFactory::CACHE_KEY]['backend'] = \TYPO3\CMS\Core\Cache\Backend\NullBackend::class;

or maybe even remove the cache completly? as it is a filecache anyway I don't see much benefits in getting the real entrypoint file or the file from the caching framework?

Release version doesn't match emconf version

The latest release is called v2.0.9 and comes with 'version' => '2.2.0', in the ext_emconf.php file.
Also the previous version v2.0.8 doesn't match the emconf version. That's confusing. It would be great if they match in future.

wrong copyright header

the header "This file is part of the TYPO3 CMS project." is not correct within this project

Add link header for cached pages

The link header is currently not passed when the page is generated from cache.

Steps to reproduce:

  1. Make sure that the link header is added to the response headers after clearing the TYPO3 cache
  2. Make sure the page is cacheable
  3. Call cached page in frontend and check the response headers. No link header is available.

TagRenderer throws exception (warning) in PHP 8

PHP Warning: Undefined array key "doctype" in /var/www/html/public/typo3conf/ext/typo3_encore/Classes/Asset/TagRenderer.php line 253

The Problem is already solved in dev-master, but not released.

Is there anything that should be tested for PHP 8 where I can eventually help to speed up the new version release?

Add a way to include css endpoint as inline css

hi

A question: is there a way to put some css endpoint as inline_css?

Why?

REASON 1:
The reason is the Google PageSpeed Insights test called "Preload key requests". Its telling about font preload.
I know I can use <link rel=preload> or push the fonts with http2 headers (I use it for woff2)

Unfortunately the problem is that Google PageSpeed Insights is also requesting other font types to be preloaded like woff, ttf, eof. This has no big sense to download all this font types if browser use only one.

I noticed that if I put in <head> a <style> with font-face definitions then Google PageSpeed Insights no longer require to preload any fonts. That has some sense because the information what to download is on the very beginning of HTML - no css file needs to be downloaded to start to download right font file.

REASON 2:
Sometimes there is a need to have critical inline css to draw a content as fast as possible (menu, header elements) to have good score on First Contentful Paint (FCP).

btw: thank you for this nice extension.

Different namespace for viewhelpers

I propose a different namespace for the viewhelpers by default. instead of e use encore.

advantages:

  • more speaking
  • less guessing

as those VH are not used that often in a project, the additional chars are IMO fine

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.