{"id":15524777,"url":"https://github.com/sabbelasichon/typo3_encore","last_synced_at":"2025-05-15T20:07:39.138Z","repository":{"id":34594688,"uuid":"180458559","full_name":"sabbelasichon/typo3_encore","owner":"sabbelasichon","description":"Use Webpack Encore within TYPO3","archived":false,"fork":false,"pushed_at":"2025-05-01T07:23:19.000Z","size":533,"stargazers_count":107,"open_issues_count":10,"forks_count":22,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-05-15T11:43:14.724Z","etag":null,"topics":["encore","es6","hacktoberfest","javascript","typo3","webpack"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sabbelasichon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"sabbelasichon","custom":"https://paypal.me/schreiberten"}},"created_at":"2019-04-09T22:25:30.000Z","updated_at":"2025-02-10T15:26:57.000Z","dependencies_parsed_at":"2023-11-24T17:28:34.571Z","dependency_job_id":"df780de0-07f7-44e2-ba86-93b8ef416fc4","html_url":"https://github.com/sabbelasichon/typo3_encore","commit_stats":{"total_commits":234,"total_committers":19,"mean_commits":12.31578947368421,"dds":0.2991452991452992,"last_synced_commit":"ce46b74ea6deffabe3963f7a7ea97e08c8dfb272"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sabbelasichon%2Ftypo3_encore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sabbelasichon%2Ftypo3_encore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sabbelasichon%2Ftypo3_encore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sabbelasichon%2Ftypo3_encore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sabbelasichon","download_url":"https://codeload.github.com/sabbelasichon/typo3_encore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254414501,"owners_count":22067272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["encore","es6","hacktoberfest","javascript","typo3","webpack"],"created_at":"2024-10-02T10:53:10.296Z","updated_at":"2025-05-15T20:07:34.081Z","avatar_url":"https://github.com/sabbelasichon.png","language":"PHP","funding_links":["https://github.com/sponsors/sabbelasichon","https://paypal.me/schreiberten"],"categories":[],"sub_categories":[],"readme":"[![Downloads](https://img.shields.io/packagist/dt/ssch/typo3-encore.svg?style=flat-square)](https://packagist.org/packages/ssch/typo3-encore)\n\nTYPO3 integration with Webpack Encore!\n======================================\n\nThis extension allows you to use the `splitEntryChunks()` feature\nfrom [Webpack Encore](https://symfony.com/doc/current/frontend.html)\nby reading an `entrypoints.json` file and helping you render all of\nthe dynamic `script` and `link` tags needed.\n\n```\ncomposer require ssch/typo3-encore\n```\n\n## How to use\n\n1. First of all install Webpack Encore as stated in the [documentation](https://symfony.com/doc/current/frontend.html).\nYou should really be able to use all of the things described in the documentation.\nLike Sass-Loader, Vue-Loader etc. These things are completely independent from this little extension.\n\nYou can also use the enableVersioning() of files (mostly used only in production context).\nYou can also use the enableIntegrityHashes(). This is taking into account if the files are included.\n\n2. Define your entry path(s) and the output path (usually your Resource/Public/ folder in your Package extension) in the webpack.config.js\n\n3. Afterwards set the two TypoScript constants to point to the manifest.json and the entrypoints.json located in the configured output folder\n```php\nplugin.tx_typo3encore {\n    settings {\n        entrypointJsonPath = EXT:typo3_encore/Resources/Public/entrypoints.json\n        manifestJsonPath = EXT:typo3_encore/Resources/Public/manifest.json\n    }\n}\n```\n\n4. In your Page templates/layout you can then use the ViewHelpers to integrate the CSS- and JS-Files in your website\n```html\n{namespace encore = Ssch\\Typo3Encore\\ViewHelpers}\n\n\u003cencore:renderWebpackLinkTags entryName=\"app\"/\u003e\n\u003cencore:renderWebpackScriptTags entryName=\"app\"/\u003e\n```\n\nIf you have defined multiple entries you can define the desired entryName in the ViewHelpers\n```html\n{namespace encore = Ssch\\Typo3Encore\\ViewHelpers}\n\n\u003cencore:renderWebpackLinkTags entryName=\"secondEntryName\"/\u003e\n\u003cencore:renderWebpackScriptTags entryName=\"secondEntryName\"/\u003e\n```\n\n\nAlternatively you can also include the files via TypoScript\n\n```php\npage.includeCSS {\n    # Pattern typo3_encore:entryName\n    app = typo3_encore:app\n    # If you want to ensure that this file is loaded first uncomment the next line\n    # app.forceOnTop = 1\n}\n\npage.includeJS {\n    # Pattern typo3_encore:entryName\n    app = typo3_encore:app\n    # If you want to ensure that this file is loaded first uncomment the next line\n    # app.forceOnTop = 1\n}\n\npage.includeJSFooter {\n    # Pattern typo3_encore:entryName\n    app = typo3_encore:app\n}\n```\n\nNote the prefix typo3_encore: This is important in order to render the files correctly.\nYou can then use all other known settings to include your files.\n\nYou don´t have to care about including it only once. This will not happen during one request cycle unless you want to.\n\nIt is also possible to use the inclusion via the prefix typo3_encore in backend specific contexts. For example like so:\n\n```html\n\u003cf:be.container includeCssFiles=\"{0: 'typo3_encore:backend'}\" includeJsFiles=\"{0: 'typo3_encore:backend'}\"\u003e\n\n\u003c/f:be.container\u003e\n```\n\n### HTTP/2 Preloading\n\nAll css and javascript files managed by the extension will be added to the AssetRegistry class during rendering.\nFor 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.\n\nTechnically this is done by a PSR-15 Middleware.\n\nIf you want to add additional files to the AssetRegistry you can use the PreloadViewHelper:\n\n```html\n{namespace encore = Ssch\\Typo3Encore\\ViewHelpers}\n\n\u003cencore:preload attributes=\"{type: 'font/woff2', crossOrigin: 'anonymous'}\" as=\"font\" uri=\"{encore:asset(pathToFile: 'EXT:typo3_encore/Resources/fonts/webfont.woff2')}\" /\u003e\n```\n\nWatch out, the example also uses the AssetViewHelper. The AssetViewHelper behind the scenes makes a look up to the manifest.json file.\nSo you can also leverage the versioning feature provided by Webpack.\n\n### Static assets\n\nSometimes 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).\n\nTo 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).\n\nNote 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:\n\n```\n{namespace encore = Ssch\\Typo3Encore\\ViewHelpers}\n\n\n\u003cimg class=\"my-image\" src=\"{encore:asset(pathToFile: 'EXT:my_extension/Resources/Public/Build/images/my_image.jpg')}\" alt=\"My image\" /\u003e\n```\n\nThis way of using the AssetViewHelper is similar to the `asset` function used in Twig templates with Symfony.\n\n## Additional\n\n1. If you are in production mode and set enableVersioning(true) then you should set the option\n\n```php\n$GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename'] = ''\n```\n\n2. Defining Multiple Webpack Configurations ([see](https://symfony.com/doc/current/frontend/encore/advanced-config.html#defining-multiple-webpack-configurations))\n\nThen you have to define your builds in your TypoScript-Setup:\n\n```php\nplugin.tx_typo3encore {\n    settings {\n        builds {\n            firstBuild = EXT:typo3_encore/Resources/Public/FirstBuild\n            secondBuild = EXT:typo3_encore/Resources/Public/SecondBuild\n        }\n    }\n}\n```\n\nFinally, you can specify which build to use:\n\n```php\npage.includeCSS {\n    # Pattern typo3_encore:buildName:entryName\n    app = typo3_encore:firstBuild:app\n}\n```\n\n```html\n{namespace encore = Ssch\\Typo3Encore\\ViewHelpers}\n\n\u003cencore:renderWebpackLinkTags entryName=\"app\" buildName=\"firstBuild\"/\u003e\n```\n\n### CSS for CKEditor\n\nIt 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.\nTwo steps are required to do so:\n\n1. Define an entrypoint for the RTE in your `webpack.config.js`, e.g.\n```js\nEncore\n    .addStyleEntry('rte', './assets/rte.scss')\n```\n\n2. Add in the CKEditor yaml configuration\n\n```yaml\neditor:\n  config:\n    contentsCss: \"typo3_encore:rte\"\n```\n\n## Getting Started with Webpack Encore\n\nAlthough the documentation of Webpack Encore is awesome, i am going to provide a minimalistic how to install the frontend related things.\nI assume some basic knowledge of modern frontend development.\n\n### Install Encore into your project via Yarn or Npm:\nFirst, make sure you install [Node.js](https://nodejs.org/en/download/) and also the [Yarn](https://yarnpkg.com/lang/en/docs/install/) or [npm](https://www.npmjs.com/get-npm) package manager.\n\n\n```cli\nyarn add @symfony/webpack-encore --dev\n```\n\nThis command creates or modifies a package.json file and downloads dependencies into a node_modules/ directory.\nYarn also creates/updates a yarn.lock (called package-lock.json if you use npm).\n\nYou should commit package.json and yarn.lock (or package-lock.json if using npm) to version control, but ignore the node_modules/ folder.\n\n### Creating the webpack.config.js File\nNext, we are going to create a webpack.config.js file at the root of our project.\nThis is the main config file for both Webpack and Webpack Encore:\n\n```javascript\nvar Encore = require('@symfony/webpack-encore');\n\nEncore\n    // the directory where compiled assets will be stored\n    .setOutputPath('public/typo3conf/ext/my_sitepackage/Resources/Public/')\n\n    // public path used by the web server to access the output path\n    .setPublicPath('/typo3conf/ext/my_sitepackage/Resources/Public/')\n\n    // only needed for CDN's or sub-directory deploy\n    // .setManifestKeyPrefix('build/')\n\n    // Copy some static images to your -\u003e https://symfony.com/doc/current/frontend/encore/copy-files.html\n    .copyFiles({\n        from: './src/images',\n        // Optional target path, relative to the output dir\n        to: 'images/[path][name].[ext]',\n        includeSubdirectories: false,\n        // if versioning is enabled, add the file hash too\n        to: 'images/[path][name].[hash:8].[ext]',\n        // only copy files matching this pattern\n        pattern: /\\.(png|jpg|jpeg)$/\n    })\n\n    /*\n     * ENTRY CONFIG\n     *\n     * Add 1 entry for each \"page\" of your app\n     * (including one that's included on every page - e.g. \"app\")\n     *\n     * Each entry will result in one JavaScript file (e.g. app.js)\n     * and one CSS file (e.g. app.css) if you JavaScript imports CSS.\n     */\n    .addEntry('app', './src/js/app.js')\n    .addEntry('homepage', './src/js/homepage.js')\n\n    // will require an extra script tag for runtime.js\n    // but, you probably want this, unless you're building a single-page app\n    .enableSingleRuntimeChunk()\n\n    .cleanupOutputBeforeBuild()\n    .enableSourceMaps(!Encore.isProduction())\n\n    // enables hashed filenames (e.g. app.abc123.css)\n    .enableVersioning(Encore.isProduction())\n\n    // uncomment if you use TypeScript -\u003e https://symfony.com/doc/current/frontend/encore/typescript.html\n    // .enableTypeScriptLoader()\n\n    // uncomment if you are using Sass/SCSS files -\u003e https://symfony.com/doc/current/frontend/encore/css-preprocessors.html\n    // .enableSassLoader()\n\n    // uncomment if you're having problems with a jQuery plugin -\u003e https://symfony.com/doc/current/frontend/encore/legacy-applications.html\n    // .autoProvidejQuery()\n\n    // uncomment if you use the postcss -\u003e https://symfony.com/doc/current/frontend/encore/postcss.html\n    // .enablePostCssLoader()\n\n\n    // uncomment if you want to use vue -\u003e https://symfony.com/doc/current/frontend/encore/vuejs.html\n    // .enableVueLoader()\n\n    // uncomment if you´re want to lint your sources\n    // .enableEslintLoader()\n\n    // uncomment if you´re want to have integrity hashes for your script tags, the extension takes care of it\n    // .enableIntegrityHashes()\n\n    // uncomment if you´re want to share general code for the different entries -\u003e https://symfony.com/doc/current/frontend/encore/split-chunks.html\n    // .splitEntryChunks()\n    ;\n\n// Uncomment if you are going to use a CDN -\u003e https://symfony.com/doc/current/frontend/encore/cdn.html\n// if (Encore.isProduction()) {\n    //Encore.setPublicPath('https://my-cool-app.com.global.prod.fastly.net');\n\n    // guarantee that the keys in manifest.json are *still*\n    // prefixed with build/\n    // (e.g. \"build/dashboard.js\": \"https://my-cool-app.com.global.prod.fastly.net/dashboard.js\")\n    // Encore.setManifestKeyPrefix('build/');\n// }\n\nmodule.exports = Encore.getWebpackConfig();\n```\n\n### Working with Watcher \u0026 TYPO3 with Content Security Policy\n\nIf you encounter problems with Content Security Policy and watcher add the following to your additional.php\n\n```php\n// disable CSP if \"npm run watch\" is used\nif (strpos(file_get_contents(\\TYPO3\\CMS\\Core\\Core\\Environment::getPublicPath() . '/build/entrypoints.json'), 'build/vendors-node_modules') !== false) {\n    $GLOBALS['TYPO3_CONF_VARS']['SYS']['features']['security.frontend.enforceContentSecurityPolicy'] = false;\n}\n```\n\n### Working with typo3/cms-composer-installers 4+ or TYPO3 12\n\nThe `typo3/cms-composer-installers` library takes care of moving TYPO3-specific assets in the right place\nin Composer-based installations, like copying extensions to `typo3conf/ext`. Starting with version 4.0\n(currently at RC1 stage), the extensions will remain in `vendor/vendor_name`. The `Resources/Public`\ndirectory of each extension is symlinked from the `public/assets` directory using hashes. While it is\npossible to target the symlink, the fact that it is a hash makes it a bit flaky.\n\nThe recommendation is to use another build directory, not located inside an extension.\nAs an example, asuming that you use `public/build`, the configuration in `webpack.config.js`\nwould be modified as follows:\n\n```javascript\nvar Encore = require('@symfony/webpack-encore');\n\nEncore\n    .setOutputPath('../../public/build')\n    .setPublicPath('/build')\n    ...\n```\n\nThe TypoScript constants have to be modified accordingly:\n\n```typo3_typoscript\nplugin.tx_typo3encore {\n    settings {\n        # These paths are relative to the web root (public) directory\n        entrypointJsonPath = build/entrypoints.json\n        manifestJsonPath = build/manifest.json\n    }\n}\n```\n\nIf 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.\nThis can be done in your \"Configure Installation-Wide Options\" (TYPO3 \u003c= 11: `typo3conf/LocalConfiguration.php`; TYPO3 \u003e= 12: `config/system/settings.php`)\n```\n    [FE][additionalAbsRefPrefixDirectories]: build\n```\n\n### The realm of Webpack plugins\nEncore already ships with a lot of useful plugins for the daily work.\nBut someday you are gonna get to the point where you need more.\n\n#### Generating icons and inject them automatically\n\nInstall [webapp-webpack-plugin](https://github.com/brunocodutra/webapp-webpack-plugin) and [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin).\n\n```javascript\nconst WebappWebpackPlugin = require('webapp-webpack-plugin');\nconst HtmlWebpackPlugin = require('html-webpack-plugin');\n\nEncore.addPlugin(new HtmlWebpackPlugin(\n            {\n                inject: false,\n                minify: false,\n                template: 'public/typo3conf/ext/typo3_encore/Resources/Private/Templates/Favicons.html',\n                filename: 'favicons.html',\n            }\n        ))\n        .addPlugin(new WebappWebpackPlugin({\n            inject: htmlPlugin =\u003e htmlPlugin.options.filename === 'favicons.html',\n            logo: './src/images/logo.png',\n            force: true,\n            favicons: {\n                start_url: null,\n                lang: null,\n                icons: {\n                    android: true,\n                    appleIcon: true,\n                    appleStartup: true,\n                    windows: true,\n                    yandex: true,\n                    favicons: true,\n                    coast: true,\n                    firefox: true,\n                    opengraph: false,\n                    twitter: false\n                }\n            }\n        }))\n```\n\nIn order to inject the html file in the header of your TYPO3 just include the template file:\n\n```php\npage.headerData.2039 = FLUIDTEMPLATE\npage.headerData.2039 {\n    file = EXT:typo3_encore/Resources/Public/favicons.html\n}\n```\n\n#### Generating a svg sprite\n\nInstall [svg-sprite-loader](https://github.com/kisenka/svg-sprite-loader#installation)\n```javascript\nconst SpritePlugin = require('svg-sprite-loader/plugin');\n\nEncore.addLoader({\n    test: /\\src\\/icons\\/.svg$/,\n    loader: 'svg-sprite-loader',\n    options: {\n        extract: true,\n    }\n}).addPlugin(new SpritePlugin())\n\n```\n\nNow you have to import all your svg files in your javascript\n\n```\nfunction requireAll(r) {\n    r.keys().forEach(r);\n}\nrequireAll(require.context('./relative-path-to-svg-folder/svg-sprite/', true, /\\.svg$/));\n```\n\nThe extension ships with a SvgViewHelper in order to simplify the usage of svg in fluid.\n\n```html\n{namespace encore = Ssch\\Typo3Encore\\ViewHelpers}\n\n\u003cencore:svg title=\"Title\" description=\"Description\" src=\"EXT:typo3_encore/Resources/Public/sprite.svg\" name=\"icon-fax-contact\"/\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsabbelasichon%2Ftypo3_encore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsabbelasichon%2Ftypo3_encore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsabbelasichon%2Ftypo3_encore/lists"}