From 09d13b61e952bb8d564114e2618c72dfcea8626d Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Sat, 25 Apr 2020 21:39:55 +0300 Subject: [PATCH 01/16] Add inline to webpack_entry_js --- .../TokenParser/EntryTokenParserJs.php | 32 ++++++++++++++++--- tests/Resource/main.js | 1 + tests/TokenParser/EntryTokenParserJsTest.php | 16 ++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 tests/Resource/main.js diff --git a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php index 7d69a5f..adfd805 100644 --- a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php +++ b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php @@ -34,6 +34,7 @@ public function parse(Token $token) $entryName = $stream->expect(Token::STRING_TYPE)->getValue(); $defer = $stream->nextIf(/* Token::NAME_TYPE */ 5, 'defer'); $async = $stream->nextIf(/* Token::NAME_TYPE */ 5, 'async'); + $inline = $stream->nextIf(/* Token::NAME_TYPE */ 5, 'inline'); $stream->expect(Token::BLOCK_END_TYPE); if (!\file_exists($this->manifestFile)) { @@ -49,17 +50,38 @@ public function parse(Token $token) $entryPath = $this->publicPath.$manifest[$manifestIndex]; - $tag = \sprintf( - '', - $entryPath, - $defer + if ($inline) { + $tag = \sprintf( + '', + $this->getEntryContent($this->manifestFile, $manifest[$manifestIndex]) + ); + } else { + $tag = \sprintf( + '', + $entryPath, + $defer ? ' defer' : ($async ? ' async' : '') - ); + ); + } return new TextNode($tag, $token->getLine()); } + /** + * @throws Exception if file does not exists + */ + public function getEntryContent(string $manifestFile, string $entryFile): ?string + { + $dir = \dirname($manifestFile); + + if (!\file_exists($dir.'/'.$entryFile)) { + throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $dir.'/'.$entryFile)); + } + + return \file_get_contents($dir.'/'.$entryFile); + } + /** * {@inheritdoc} */ diff --git a/tests/Resource/main.js b/tests/Resource/main.js new file mode 100644 index 0000000..3d0c6cc --- /dev/null +++ b/tests/Resource/main.js @@ -0,0 +1 @@ +alert('foo'); diff --git a/tests/TokenParser/EntryTokenParserJsTest.php b/tests/TokenParser/EntryTokenParserJsTest.php index 073d940..9bf7084 100644 --- a/tests/TokenParser/EntryTokenParserJsTest.php +++ b/tests/TokenParser/EntryTokenParserJsTest.php @@ -72,6 +72,22 @@ public function testGenerateAsync() ); } + public function testGenerateInline() + { + $env = $this->getEnv(__DIR__.'/../Resource/manifest.json', '/build/'); + $parser = new Parser($env); + $source = new Source("{% webpack_entry_js 'main' inline %}", ''); + $stream = $env->tokenize($source); + + $expected = new TextNode("", 1); + $expected->setSourceContext($source); + + $this->assertEquals( + $expected, + $parser->parse($stream)->getNode('body')->getNode('0') + ); + } + private function getEnv(string $manifest, string $publicPath): Environment { $env = new Environment( From 9ae32d65262cbdb2e6ca5ce79323f90709b552d9 Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Sat, 25 Apr 2020 21:40:23 +0300 Subject: [PATCH 02/16] Add inline to webpack_entry_css --- .../TokenParser/EntryTokenParserCss.php | 30 ++++++++++++++++--- tests/Resource/main.css | 1 + tests/TokenParser/EntryTokenParserCssTest.php | 16 ++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 tests/Resource/main.css diff --git a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php index 092abe7..0cfaaa5 100644 --- a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php +++ b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php @@ -32,6 +32,7 @@ public function parse(Token $token) { $stream = $this->parser->getStream(); $entryName = $stream->expect(Token::STRING_TYPE)->getValue(); + $inline = $stream->nextIf(/* Token::NAME_TYPE */ 5, 'inline'); $stream->expect(Token::BLOCK_END_TYPE); if (!\file_exists($this->manifestFile)) { @@ -47,14 +48,35 @@ public function parse(Token $token) $entryPath = $this->publicPath.$manifest[$manifestIndex]; - $tag = \sprintf( - '', - $entryPath - ); + if ($inline) { + $tag = \sprintf( + '', + $this->getEntryContent($this->manifestFile, $manifest[$manifestIndex]) + ); + } else { + $tag = \sprintf( + '', + $entryPath + ); + } return new TextNode($tag, $token->getLine()); } + /** + * @throws Exception if file does not exists + */ + public function getEntryContent(string $manifestFile, string $entryFile): ?string + { + $dir = \dirname($manifestFile); + + if (!\file_exists($dir.'/'.$entryFile)) { + throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $dir.'/'.$entryFile)); + } + + return \file_get_contents($dir.'/'.$entryFile); + } + /** * {@inheritdoc} */ diff --git a/tests/Resource/main.css b/tests/Resource/main.css new file mode 100644 index 0000000..b91f59e --- /dev/null +++ b/tests/Resource/main.css @@ -0,0 +1 @@ +div { color: green; } diff --git a/tests/TokenParser/EntryTokenParserCssTest.php b/tests/TokenParser/EntryTokenParserCssTest.php index 1d36050..3a49a66 100644 --- a/tests/TokenParser/EntryTokenParserCssTest.php +++ b/tests/TokenParser/EntryTokenParserCssTest.php @@ -41,6 +41,22 @@ public function testGenerate() ); } + public function testGenerateInline() + { + $env = $this->getEnv(__DIR__.'/../Resource/manifest.json', '/build/'); + $parser = new Parser($env); + $source = new Source("{% webpack_entry_css 'main' inline %}", ''); + $stream = $env->tokenize($source); + + $expected = new TextNode("", 1); + $expected->setSourceContext($source); + + $this->assertEquals( + $expected, + $parser->parse($stream)->getNode('body')->getNode('0') + ); + } + public function testItThrowsExceptionIfNoManifest() { $this->expectException(LoaderError::class); From ea2fecbf4d5e43eac3e2ccc39ddf34a4c9b8402c Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Sat, 25 Apr 2020 22:36:46 +0300 Subject: [PATCH 03/16] bug fix --- example/composer.json | 4 +++- example/templates/base.html.twig | 4 ++-- .../TokenParser/EntryTokenParserCss.php | 13 +++++++------ .../TokenParser/EntryTokenParserJs.php | 9 +++++---- tests/Resource/manifest.json | 6 +++--- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/example/composer.json b/example/composer.json index f8f6c35..7805307 100644 --- a/example/composer.json +++ b/example/composer.json @@ -1,11 +1,13 @@ { + "name": "twig-webpack-extension-example", + "description": "", "type": "project", "license": "proprietary", "require": { "php": "^7.1.3", "ext-ctype": "*", "ext-iconv": "*", - "fullpipe/twig-webpack-extension": "dev-master", + "fullpipe/twig-webpack-extension": "dev-add-inline", "symfony/console": "4.4.*", "symfony/dotenv": "4.4.*", "symfony/flex": "^1.3.1", diff --git a/example/templates/base.html.twig b/example/templates/base.html.twig index 29c7455..286d9bf 100644 --- a/example/templates/base.html.twig +++ b/example/templates/base.html.twig @@ -4,14 +4,14 @@ {% block title %}Welcome!{% endblock %} {% block stylesheets %} - + {% webpack_entry_css 'main' inline %} {% webpack_entry_css 'main' %} {% endblock %} {% block body %}{% endblock %} {% block javascripts %} - {% webpack_entry_js 'vendor' defer %} + {% webpack_entry_js 'vendor' inline %} {% webpack_entry_js 'main' defer %} {% endblock %} diff --git a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php index 0cfaaa5..05f2bfc 100644 --- a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php +++ b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php @@ -12,12 +12,12 @@ class EntryTokenParserCss extends AbstractTokenParser /** * @var string */ - protected $manifestFile; + private $manifestFile; /** * @var string */ - protected $publicPath; + private $publicPath; public function __construct(string $manifestFile, string $publicPath) { @@ -46,12 +46,12 @@ public function parse(Token $token) throw new LoaderError('Webpack css entry '.$entryName.' not exists.', $token->getLine(), $stream->getSourceContext()); } - $entryPath = $this->publicPath.$manifest[$manifestIndex]; + $entryPath = $manifest[$manifestIndex]; if ($inline) { $tag = \sprintf( '', - $this->getEntryContent($this->manifestFile, $manifest[$manifestIndex]) + $this->getEntryContent($entryPath) ); } else { $tag = \sprintf( @@ -66,9 +66,10 @@ public function parse(Token $token) /** * @throws Exception if file does not exists */ - public function getEntryContent(string $manifestFile, string $entryFile): ?string + private function getEntryContent(string $entryFile): ?string { - $dir = \dirname($manifestFile); + $dir = \dirname($this->manifestFile); + $entryFile = \str_replace($this->publicPath, '', $entryFile); if (!\file_exists($dir.'/'.$entryFile)) { throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $dir.'/'.$entryFile)); diff --git a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php index adfd805..3a2000b 100644 --- a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php +++ b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php @@ -48,12 +48,12 @@ public function parse(Token $token) throw new LoaderError('Webpack js entry '.$entryName.' not exists.', $token->getLine(), $stream->getSourceContext()); } - $entryPath = $this->publicPath.$manifest[$manifestIndex]; + $entryPath = $manifest[$manifestIndex]; if ($inline) { $tag = \sprintf( '', - $this->getEntryContent($this->manifestFile, $manifest[$manifestIndex]) + $this->getEntryContent($entryPath) ); } else { $tag = \sprintf( @@ -71,9 +71,10 @@ public function parse(Token $token) /** * @throws Exception if file does not exists */ - public function getEntryContent(string $manifestFile, string $entryFile): ?string + private function getEntryContent(string $entryFile): ?string { - $dir = \dirname($manifestFile); + $dir = \dirname($this->manifestFile); + $entryFile = \str_replace($this->publicPath, '', $entryFile); if (!\file_exists($dir.'/'.$entryFile)) { throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $dir.'/'.$entryFile)); diff --git a/tests/Resource/manifest.json b/tests/Resource/manifest.json index b69e981..b139f2b 100644 --- a/tests/Resource/manifest.json +++ b/tests/Resource/manifest.json @@ -1,5 +1,5 @@ { - "main.js": "main.js", - "main.css": "main.css", - "foo.png": "bar.png" + "main.js": "/build/main.js", + "main.css": "/build/main.css", + "foo.png": "/build/bar.png" } From 01498f50b2a08607df65fa85a517b4faf3bc9e94 Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Sat, 25 Apr 2020 22:38:58 +0300 Subject: [PATCH 04/16] Update composer.json --- example/composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/example/composer.json b/example/composer.json index 7805307..8c3a325 100644 --- a/example/composer.json +++ b/example/composer.json @@ -1,5 +1,4 @@ { - "name": "twig-webpack-extension-example", "description": "", "type": "project", "license": "proprietary", From 3d5dd474afaea6abc8542c6ca2020c7c83871515 Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Mon, 27 Apr 2020 09:19:17 +0300 Subject: [PATCH 05/16] Fix bug with publicPath --- example/config/services.yaml | 20 ++++---------------- example/frontend/src/index.js | 7 +------ example/frontend/src/second.js | 8 ++++++++ example/frontend/webpack.config.js | 21 +++++++++++---------- example/templates/base.html.twig | 4 ++-- 5 files changed, 26 insertions(+), 34 deletions(-) create mode 100644 example/frontend/src/second.js diff --git a/example/config/services.yaml b/example/config/services.yaml index 654d1f0..e7dc3a8 100644 --- a/example/config/services.yaml +++ b/example/config/services.yaml @@ -1,27 +1,17 @@ -# This file is the entry point to configure your own services. -# Files in the packages/ subdirectory configure your dependencies. - -# Put parameters here that don't need to change on each machine where the app is deployed -# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration parameters: webpack.manifest: "%kernel.root_dir%/../public/build/manifest.json" #should be absolute - webpack.public_path_js: "" - webpack.public_path_css: "" + webpack.public_path_js: "/build/" + webpack.public_path_css: "/build/" services: - # default configuration for services in *this* file _defaults: - autowire: true # Automatically injects dependencies in your services. - autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. + autowire: true + autoconfigure: true - # makes classes in src/ available to be used as services - # this creates a service per class whose id is the fully-qualified class name App\: resource: '../src/*' exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' - # controllers are imported separately to make sure services can be injected - # as action arguments even if you don't extend any base controller class App\Controller\: resource: '../src/Controller' tags: ['controller.service_arguments'] @@ -35,5 +25,3 @@ services: - "%webpack.public_path_css%" tags: - { name: twig.extension } - # add more service definitions when explicit configuration is needed - # please note that last definitions always *replace* previous ones diff --git a/example/frontend/src/index.js b/example/frontend/src/index.js index b3d84bc..559dac4 100644 --- a/example/frontend/src/index.js +++ b/example/frontend/src/index.js @@ -7,10 +7,5 @@ $(() => { const $element = $("
"); $element.text(_.join(["Hello", "from", "index.js"], " ")); - $element - .hide() - .appendTo($(".content")) - .fadeIn("slow"); - - // $("body").append($element); + $element.hide().appendTo($(".content")).fadeIn("slow"); }); diff --git a/example/frontend/src/second.js b/example/frontend/src/second.js new file mode 100644 index 0000000..9e6a412 --- /dev/null +++ b/example/frontend/src/second.js @@ -0,0 +1,8 @@ +import $ from "jquery"; + +$(() => { + const $element = $("
"); + + $element.text(_.join(["Hello", "from", "second.js"], " ")); + $element.hide().appendTo($(".content")).fadeIn("slow"); +}); diff --git a/example/frontend/webpack.config.js b/example/frontend/webpack.config.js index d6aeb0b..018ffec 100644 --- a/example/frontend/webpack.config.js +++ b/example/frontend/webpack.config.js @@ -6,23 +6,24 @@ const ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { vendor: ["jquery", "lodash"], - main: "./src/index.js" + main: "./src/index.js", + second: "./src/second.js", }, output: { filename: "js/[name].js", path: path.resolve(__dirname, "../public/build"), - publicPath: "/build/" + publicPath: "/build/", }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: "vendor", - minChunks: Infinity + minChunks: Infinity, }), new ManifestPlugin(), new ExtractTextPlugin({ filename: "css/[name].css", - publicPath: "/build/" - }) + publicPath: "/build/", + }), ], module: { rules: [ @@ -30,9 +31,9 @@ module.exports = { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", - use: "css-loader" - }) - } - ] - } + use: "css-loader", + }), + }, + ], + }, }; diff --git a/example/templates/base.html.twig b/example/templates/base.html.twig index 286d9bf..becf8cc 100644 --- a/example/templates/base.html.twig +++ b/example/templates/base.html.twig @@ -5,14 +5,14 @@ {% block title %}Welcome!{% endblock %} {% block stylesheets %} {% webpack_entry_css 'main' inline %} - {% webpack_entry_css 'main' %} {% endblock %} {% block body %}{% endblock %} {% block javascripts %} - {% webpack_entry_js 'vendor' inline %} + {% webpack_entry_js 'vendor' %} {% webpack_entry_js 'main' defer %} + {% webpack_entry_js 'second' async %} {% endblock %} From c9bb46e36b5d9d56e70b3d5cd25f263bd33b7438 Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 21:54:10 +0300 Subject: [PATCH 06/16] Fix test --- .../TokenParser/EntryTokenParserCss.php | 9 ++- .../TokenParser/EntryTokenParserJs.php | 9 ++- tests/Resource/main.css | 1 - tests/Resource/main.js | 1 - tests/Resource/manifest.json | 5 -- tests/TokenParser/EntryTokenParserCssTest.php | 18 +++--- tests/TokenParser/EntryTokenParserJsTest.php | 57 +++++++++++++------ 7 files changed, 64 insertions(+), 36 deletions(-) delete mode 100644 tests/Resource/main.css delete mode 100644 tests/Resource/main.js delete mode 100644 tests/Resource/manifest.json diff --git a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php index 05f2bfc..cd43e3e 100644 --- a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php +++ b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php @@ -64,7 +64,7 @@ public function parse(Token $token) } /** - * @throws Exception if file does not exists + * @throws LoaderError if file does not exists or not readable */ private function getEntryContent(string $entryFile): ?string { @@ -75,7 +75,12 @@ private function getEntryContent(string $entryFile): ?string throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $dir.'/'.$entryFile)); } - return \file_get_contents($dir.'/'.$entryFile); + $content = \file_get_contents($dir.'/'.$entryFile); + if (false === $content) { + throw new LoaderError(\sprintf('Unable to read file "%s".', $dir.'/'.$entryFile)); + } + + return $content; } /** diff --git a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php index 3a2000b..6ce4d4c 100644 --- a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php +++ b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php @@ -69,7 +69,7 @@ public function parse(Token $token) } /** - * @throws Exception if file does not exists + * @throws LoaderError if file does not exists or not readable */ private function getEntryContent(string $entryFile): ?string { @@ -80,7 +80,12 @@ private function getEntryContent(string $entryFile): ?string throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $dir.'/'.$entryFile)); } - return \file_get_contents($dir.'/'.$entryFile); + $content = \file_get_contents($dir.'/'.$entryFile); + if (false === $content) { + throw new LoaderError(\sprintf('Unable to read file "%s".', $dir.'/'.$entryFile)); + } + + return $content; } /** diff --git a/tests/Resource/main.css b/tests/Resource/main.css deleted file mode 100644 index b91f59e..0000000 --- a/tests/Resource/main.css +++ /dev/null @@ -1 +0,0 @@ -div { color: green; } diff --git a/tests/Resource/main.js b/tests/Resource/main.js deleted file mode 100644 index 3d0c6cc..0000000 --- a/tests/Resource/main.js +++ /dev/null @@ -1 +0,0 @@ -alert('foo'); diff --git a/tests/Resource/manifest.json b/tests/Resource/manifest.json deleted file mode 100644 index b139f2b..0000000 --- a/tests/Resource/manifest.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "main.js": "/build/main.js", - "main.css": "/build/main.css", - "foo.png": "/build/bar.png" -} diff --git a/tests/TokenParser/EntryTokenParserCssTest.php b/tests/TokenParser/EntryTokenParserCssTest.php index 3a49a66..8caf7d6 100644 --- a/tests/TokenParser/EntryTokenParserCssTest.php +++ b/tests/TokenParser/EntryTokenParserCssTest.php @@ -16,23 +16,23 @@ class EntryTokenParserCssTest extends TestCase { public function testItIsAParser() { - $this->assertInstanceOf(AbstractTokenParser::class, new EntryTokenParserCss(__DIR__.'/../Resource/manifest.json', '/build/')); + $this->assertInstanceOf(AbstractTokenParser::class, new EntryTokenParserCss(__DIR__.'/../Resource/build/manifest.json', '/build/')); } public function testGetTag() { - $parser = new EntryTokenParserCss(__DIR__.'/../Resource/manifest.json', '/build/'); + $parser = new EntryTokenParserCss(__DIR__.'/../Resource/build/manifest.json', '/build/'); $this->assertEquals('webpack_entry_css', $parser->getTag()); } - public function testGenerate() + public function testBasicParse() { - $env = $this->getEnv(__DIR__.'/../Resource/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); $parser = new Parser($env); $source = new Source("{% webpack_entry_css 'main' %}", ''); $stream = $env->tokenize($source); - $expected = new TextNode('', 1); + $expected = new TextNode('', 1); $expected->setSourceContext($source); $this->assertEquals( @@ -41,9 +41,9 @@ public function testGenerate() ); } - public function testGenerateInline() + public function testInline() { - $env = $this->getEnv(__DIR__.'/../Resource/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); $parser = new Parser($env); $source = new Source("{% webpack_entry_css 'main' inline %}", ''); $stream = $env->tokenize($source); @@ -72,7 +72,7 @@ public function testItThrowsExceptionIfEntryNotExists() { $this->expectException(LoaderError::class); - $env = $this->getEnv(__DIR__.'/../Resource/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); $parser = new Parser($env); $source = new Source("{% webpack_entry_css 'not_exists' %}", ''); $stream = $env->tokenize($source); @@ -82,7 +82,7 @@ public function testItThrowsExceptionIfEntryNotExists() private function getEnv(string $manifest, string $publicPath): Environment { $env = new Environment( - $this->getMockBuilder(LoaderInterface::class)->getMock(), + $this->createMock(LoaderInterface::class), ['cache' => false, 'autoescape' => false, 'optimizations' => 0] ); $env->addTokenParser(new EntryTokenParserCss($manifest, $publicPath)); diff --git a/tests/TokenParser/EntryTokenParserJsTest.php b/tests/TokenParser/EntryTokenParserJsTest.php index 9bf7084..44f74c9 100644 --- a/tests/TokenParser/EntryTokenParserJsTest.php +++ b/tests/TokenParser/EntryTokenParserJsTest.php @@ -5,6 +5,7 @@ use Fullpipe\TwigWebpackExtension\TokenParser\EntryTokenParserJs; use PHPUnit\Framework\TestCase; use Twig\Environment; +use Twig\Error\LoaderError; use Twig\Loader\LoaderInterface; use Twig\Node\TextNode; use Twig\Parser; @@ -15,23 +16,23 @@ class EntryTokenParserJsTest extends TestCase { public function testItIsAParser() { - $this->assertInstanceOf(AbstractTokenParser::class, new EntryTokenParserJs(__DIR__.'/../Resource/manifest.json', '/build/')); + $this->assertInstanceOf(AbstractTokenParser::class, new EntryTokenParserJs(__DIR__.'/../Resource/build/manifest.json', '/build/')); } public function testGetTag() { - $parser = new EntryTokenParserJs(__DIR__.'/../Resource/manifest.json', '/build/'); + $parser = new EntryTokenParserJs(__DIR__.'/../Resource/build/manifest.json', '/build/'); $this->assertEquals('webpack_entry_js', $parser->getTag()); } - public function testGenerate() + public function testBasic() { - $env = $this->getEnv(__DIR__.'/../Resource/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); $parser = new Parser($env); $source = new Source("{% webpack_entry_js 'main' %}", ''); $stream = $env->tokenize($source); - $expected = new TextNode('', 1); + $expected = new TextNode('', 1); $expected->setSourceContext($source); $this->assertEquals( @@ -40,14 +41,14 @@ public function testGenerate() ); } - public function testGenerateDefer() + public function testDefer() { - $env = $this->getEnv(__DIR__.'/../Resource/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); $parser = new Parser($env); $source = new Source("{% webpack_entry_js 'main' defer %}", ''); $stream = $env->tokenize($source); - $expected = new TextNode('', 1); + $expected = new TextNode('', 1); $expected->setSourceContext($source); $this->assertEquals( @@ -56,14 +57,14 @@ public function testGenerateDefer() ); } - public function testGenerateAsync() + public function testAsync() { - $env = $this->getEnv(__DIR__.'/../Resource/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); $parser = new Parser($env); $source = new Source("{% webpack_entry_js 'main' async %}", ''); $stream = $env->tokenize($source); - $expected = new TextNode('', 1); + $expected = new TextNode('', 1); $expected->setSourceContext($source); $this->assertEquals( @@ -72,14 +73,14 @@ public function testGenerateAsync() ); } - public function testGenerateInline() + public function testInline() { - $env = $this->getEnv(__DIR__.'/../Resource/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); $parser = new Parser($env); - $source = new Source("{% webpack_entry_js 'main' inline %}", ''); + $source = new Source("{% webpack_entry_js 'second' inline %}", ''); $stream = $env->tokenize($source); - $expected = new TextNode("", 1); + $expected = new TextNode("", 1); $expected->setSourceContext($source); $this->assertEquals( @@ -88,10 +89,34 @@ public function testGenerateInline() ); } + public function testItThrowsExceptionIfManifestIsUnreadable() + { + $env = $this->getEnv(__DIR__.'/../Resource/build/no_manifest.json', '/build/'); + $parser = new Parser($env); + $source = new Source("{% webpack_entry_js 'second' inline %}", ''); + $stream = $env->tokenize($source); + + $this->expectException(LoaderError::class); + + $parser->parse($stream)->getNode('body')->getNode('0'); + } + + public function testItThrowsExceptionIfEntryIsUnreadable() + { + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/fake_build/'); + $parser = new Parser($env); + $source = new Source("{% webpack_entry_js 'second' inline %}", ''); + $stream = $env->tokenize($source); + + $this->expectException(LoaderError::class); + + $parser->parse($stream)->getNode('body')->getNode('0'); + } + private function getEnv(string $manifest, string $publicPath): Environment { $env = new Environment( - $this->getMockBuilder(LoaderInterface::class)->getMock(), + $this->createMock(LoaderInterface::class), ['cache' => false, 'autoescape' => false, 'optimizations' => 0] ); $env->addTokenParser(new EntryTokenParserJs($manifest, $publicPath)); From 9fdc632c231246d9fa9f60e1e46cf22b9585bc5f Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 21:57:18 +0300 Subject: [PATCH 07/16] Fix test resourses --- .gitignore | 4 ++-- tests/Resource/build/css/main.css | 1 + tests/Resource/build/js/main.js | 1 + tests/Resource/build/js/second.js | 1 + tests/Resource/build/manifest.json | 6 ++++++ 5 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 tests/Resource/build/css/main.css create mode 100644 tests/Resource/build/js/main.js create mode 100644 tests/Resource/build/js/second.js create mode 100644 tests/Resource/build/manifest.json diff --git a/.gitignore b/.gitignore index 0123e16..e8d60c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .idea/ composer.lock vendor/ -build/ -.phpunit.result.cache \ No newline at end of file +example/public/build/ +.phpunit.result.cache diff --git a/tests/Resource/build/css/main.css b/tests/Resource/build/css/main.css new file mode 100644 index 0000000..b91f59e --- /dev/null +++ b/tests/Resource/build/css/main.css @@ -0,0 +1 @@ +div { color: green; } diff --git a/tests/Resource/build/js/main.js b/tests/Resource/build/js/main.js new file mode 100644 index 0000000..9ea37c7 --- /dev/null +++ b/tests/Resource/build/js/main.js @@ -0,0 +1 @@ +alert("foo"); diff --git a/tests/Resource/build/js/second.js b/tests/Resource/build/js/second.js new file mode 100644 index 0000000..a1ad347 --- /dev/null +++ b/tests/Resource/build/js/second.js @@ -0,0 +1 @@ +alert("second"); diff --git a/tests/Resource/build/manifest.json b/tests/Resource/build/manifest.json new file mode 100644 index 0000000..585e191 --- /dev/null +++ b/tests/Resource/build/manifest.json @@ -0,0 +1,6 @@ +{ + "main.js": "/build/js/main.js", + "main.css": "/build/css/main.css", + "second.js": "/build/js/second.js", + "foo.png": "/build/bar.png" +} From 82d2ff2788e91191e6aa080992d3a80d4a593f1d Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 22:03:16 +0300 Subject: [PATCH 08/16] Update symfony.lock --- example/symfony.lock | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/example/symfony.lock b/example/symfony.lock index 5fcf4ed..48d7ef3 100644 --- a/example/symfony.lock +++ b/example/symfony.lock @@ -92,6 +92,9 @@ "src/Kernel.php" ] }, + "symfony/http-client-contracts": { + "version": "v2.3.1" + }, "symfony/http-foundation": { "version": "v4.4.3" }, @@ -104,6 +107,9 @@ "symfony/polyfill-intl-idn": { "version": "v1.13.1" }, + "symfony/polyfill-intl-normalizer": { + "version": "v1.18.1" + }, "symfony/polyfill-mbstring": { "version": "v1.13.1" }, @@ -113,6 +119,9 @@ "symfony/polyfill-php73": { "version": "v1.13.1" }, + "symfony/polyfill-php80": { + "version": "v1.18.1" + }, "symfony/routing": { "version": "4.2", "recipe": { From be982f4985280efb269d84bec77d142372e422e0 Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 22:23:33 +0300 Subject: [PATCH 09/16] Update test example --- example/frontend/src/index.css | 4 ++++ example/frontend/src/index.js | 2 +- example/frontend/src/inline.css | 3 +++ example/frontend/src/inline.js | 9 +++++++++ example/frontend/src/second.js | 2 +- example/frontend/webpack.config.js | 5 +++-- example/templates/base.html.twig | 4 +++- 7 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 example/frontend/src/inline.css create mode 100644 example/frontend/src/inline.js diff --git a/example/frontend/src/index.css b/example/frontend/src/index.css index c1534be..b4fa77f 100644 --- a/example/frontend/src/index.css +++ b/example/frontend/src/index.css @@ -14,3 +14,7 @@ body { left: 50%; transform: translate(-50%, -50%); } + +div.second { + color: bisque; +} diff --git a/example/frontend/src/index.js b/example/frontend/src/index.js index 559dac4..0e58a84 100644 --- a/example/frontend/src/index.js +++ b/example/frontend/src/index.js @@ -4,7 +4,7 @@ import _ from "lodash"; import $ from "jquery"; $(() => { - const $element = $("
"); + const $element = $(`
`); $element.text(_.join(["Hello", "from", "index.js"], " ")); $element.hide().appendTo($(".content")).fadeIn("slow"); diff --git a/example/frontend/src/inline.css b/example/frontend/src/inline.css new file mode 100644 index 0000000..1bc4877 --- /dev/null +++ b/example/frontend/src/inline.css @@ -0,0 +1,3 @@ +div.inline { + color: aquamarine; +} diff --git a/example/frontend/src/inline.js b/example/frontend/src/inline.js new file mode 100644 index 0000000..4ee86b4 --- /dev/null +++ b/example/frontend/src/inline.js @@ -0,0 +1,9 @@ +import "./inline.css"; +import $ from "jquery"; + +$(() => { + const $element = $(`
`); + + $element.text(_.join(["Hello", "from", "inline.js"], " ")); + $element.hide().appendTo($(".content")).fadeIn("slow"); +}); diff --git a/example/frontend/src/second.js b/example/frontend/src/second.js index 9e6a412..2eafcc5 100644 --- a/example/frontend/src/second.js +++ b/example/frontend/src/second.js @@ -1,7 +1,7 @@ import $ from "jquery"; $(() => { - const $element = $("
"); + const $element = $(`
`); $element.text(_.join(["Hello", "from", "second.js"], " ")); $element.hide().appendTo($(".content")).fadeIn("slow"); diff --git a/example/frontend/webpack.config.js b/example/frontend/webpack.config.js index 018ffec..25efb83 100644 --- a/example/frontend/webpack.config.js +++ b/example/frontend/webpack.config.js @@ -8,9 +8,10 @@ module.exports = { vendor: ["jquery", "lodash"], main: "./src/index.js", second: "./src/second.js", + inline: "./src/inline.js", }, output: { - filename: "js/[name].js", + filename: "js/[name].[chunkhash].js", path: path.resolve(__dirname, "../public/build"), publicPath: "/build/", }, @@ -21,7 +22,7 @@ module.exports = { }), new ManifestPlugin(), new ExtractTextPlugin({ - filename: "css/[name].css", + filename: "css/[name].[chunkhash].css", publicPath: "/build/", }), ], diff --git a/example/templates/base.html.twig b/example/templates/base.html.twig index becf8cc..bef860e 100644 --- a/example/templates/base.html.twig +++ b/example/templates/base.html.twig @@ -4,7 +4,8 @@ {% block title %}Welcome!{% endblock %} {% block stylesheets %} - {% webpack_entry_css 'main' inline %} + {% webpack_entry_css 'main' %} + {% webpack_entry_css 'inline' inline %} {% endblock %} @@ -13,6 +14,7 @@ {% webpack_entry_js 'vendor' %} {% webpack_entry_js 'main' defer %} {% webpack_entry_js 'second' async %} + {% webpack_entry_js 'inline' inline %} {% endblock %} From d3bf6ae52d43041e355f8b2027105f8ecc8ed139 Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 22:39:58 +0300 Subject: [PATCH 10/16] Update README.md --- README.md | 82 +++++++++++++++++++++---------------------------------- 1 file changed, 31 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 32e8538..4a22545 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) [![Total Downloads](https://img.shields.io/packagist/dt/fullpipe/twig-webpack-extension.svg)](https://packagist.org/packages/fullpipe/twig-webpack-extension/stats) -> Inject your webpack entry points into twig templates with easy. +Inject your webpack entry points into twig templates with easy. This repo provides a Twig extension that joins Webpack resultant files with Twig template engine in an easy way. @@ -13,17 +13,21 @@ This approach allows the dynamic insertion of the css stylesheets and js scripts > Also works well with **extract-text-webpack-plugin** ## Install + ```bash -$ composer require fullpipe/twig-webpack-extension +composer require fullpipe/twig-webpack-extension ``` ### Set up Webpack + You need to install the `webpack-manifest-plugin` ```bash -$ npm install webpack-manifest-plugin --save-dev +npm install webpack-manifest-plugin --save +``` -# or with Yarn -$ yarn add webpack-manifest-plugin --dev +or with Yarn +```bash +yarn add webpack-manifest-plugin ``` Configure `webpack.config.js` @@ -31,32 +35,26 @@ Configure `webpack.config.js` // webpack.config.js var ManifestPlugin = require('webpack-manifest-plugin'); - -(...) +const path = require("path"); module.exports = { - - (...) - + ... entry: { vendor: ["jquery", "lodash"], main: './src/main.js' }, output: { - (...) - path: './js' - publicPath: '/', // required - - (...) + ... + filename: "js/[name].js", + path: path.resolve(__dirname, "../public/build"), + publicPath: '/build/', // required }, plugins: [ new ManifestPlugin(), new ExtractTextPlugin({ - filename: './../css/[name].css', - publicPath: '/' + filename: "css/[name].css", + publicPath: "/build/", }), - - (...) ] } ``` @@ -67,15 +65,11 @@ module.exports = { # app/config/services.yml parameters: - (...) - webpack.manifest: "%kernel.root_dir%/../web/build/manifest.json" #should be absolute - webpack.public_path_js: /js/ - webpack.public_path_css: /css/ + webpack.public_path_js: /build/ #same as output.publicPath + webpack.public_path_css: /build/ #same as ExtractTextPlugin.publicPath services: - (...) - twig_extension.webpack: class: Fullpipe\TwigWebpackExtension\WebpackExtension public: false @@ -92,29 +86,21 @@ services: ```twig {# app/Resources/views/base.html.twig #} -(...) - -(...) - + ... {% webpack_entry_css 'main' %} + {% webpack_entry_css 'inline' inline %} -(...) - + ... {% webpack_entry_js 'vendor' %} - {% webpack_entry_js 'main' %} + {% webpack_entry_js 'main' defer %} + {% webpack_entry_js 'second' async %} + {% webpack_entry_js 'inline' inline %} ``` -or user `defer/async` - -```twig - {% webpack_entry_js 'main' defer %} - {% webpack_entry_js 'not_main' async %} -``` - ### Example See working [example](example) with [webpack.config.js](example/frontend/webpack.config.js). @@ -125,25 +111,19 @@ If you use `[hash]` or `[chunkhash]`: ```js // webpack.config.js - -(...) - +... output: { - (...) - + ... filename: '[name].[chunkhash].js', chunkFilename: '[name].[chunkhash].js' }, plugins: [ - (...) - new ExtractTextPlugin({ - filename: './../css/[name].[contenthash].css', - publicPath: '/' + ... + filename: 'css/[name].[contenthash].css', }), - - (...) ] ``` -> You should clear twig cache after each webpack compilation. So for dev environment do not use `[hash]` or `[chunkhash]`. +You should clear twig cache after each webpack compilation. +So for dev environment do not use `[hash]` or `[chunkhash]`. From e023e256724faf55e71b84c9473c7f0cbb740931 Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 22:43:07 +0300 Subject: [PATCH 11/16] Update test.yml --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d03973..c7edb99 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: PHP Composer +name: Tests on: push: @@ -7,7 +7,7 @@ on: branches: [ master ] jobs: - build: + tests: runs-on: ubuntu-latest From 2f09d2f4b6d39723ab7e3237f77f1edb1c9ecfbe Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 23:10:46 +0300 Subject: [PATCH 12/16] Change publicPath to publicDir --- .../TokenParser/EntryTokenParserCss.php | 17 +++++++-------- .../TokenParser/EntryTokenParserJs.php | 17 +++++++-------- .../TwigWebpackExtension/WebpackExtension.php | 21 +++++-------------- tests/TokenParser/EntryTokenParserCssTest.php | 16 +++++++------- tests/TokenParser/EntryTokenParserJsTest.php | 20 +++++++++--------- tests/WebpackExtensionTest.php | 4 ++-- 6 files changed, 41 insertions(+), 54 deletions(-) diff --git a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php index cd43e3e..a22242b 100644 --- a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php +++ b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserCss.php @@ -17,12 +17,12 @@ class EntryTokenParserCss extends AbstractTokenParser /** * @var string */ - private $publicPath; + private $publicDir; - public function __construct(string $manifestFile, string $publicPath) + public function __construct(string $manifestFile, string $publicDir) { $this->manifestFile = $manifestFile; - $this->publicPath = $publicPath; + $this->publicDir = $publicDir; } /** @@ -68,16 +68,15 @@ public function parse(Token $token) */ private function getEntryContent(string $entryFile): ?string { - $dir = \dirname($this->manifestFile); - $entryFile = \str_replace($this->publicPath, '', $entryFile); + $entryFile = \trim($entryFile, '/'); - if (!\file_exists($dir.'/'.$entryFile)) { - throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $dir.'/'.$entryFile)); + if (!\file_exists($this->publicDir.'/'.$entryFile)) { + throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $this->publicDir.'/'.$entryFile)); } - $content = \file_get_contents($dir.'/'.$entryFile); + $content = \file_get_contents($this->publicDir.'/'.$entryFile); if (false === $content) { - throw new LoaderError(\sprintf('Unable to read file "%s".', $dir.'/'.$entryFile)); + throw new LoaderError(\sprintf('Unable to read file "%s".', $this->publicDir.'/'.$entryFile)); } return $content; diff --git a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php index 6ce4d4c..422af90 100644 --- a/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php +++ b/src/Fullpipe/TwigWebpackExtension/TokenParser/EntryTokenParserJs.php @@ -17,12 +17,12 @@ class EntryTokenParserJs extends AbstractTokenParser /** * @var string */ - private $publicPath; + private $publicDir; - public function __construct(string $manifestFile, string $publicPath) + public function __construct(string $manifestFile, string $publicDir) { $this->manifestFile = $manifestFile; - $this->publicPath = $publicPath; + $this->publicDir = $publicDir; } /** @@ -73,16 +73,15 @@ public function parse(Token $token) */ private function getEntryContent(string $entryFile): ?string { - $dir = \dirname($this->manifestFile); - $entryFile = \str_replace($this->publicPath, '', $entryFile); + $entryFile = \trim($entryFile, '/'); - if (!\file_exists($dir.'/'.$entryFile)) { - throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $dir.'/'.$entryFile)); + if (!\file_exists($this->publicDir.'/'.$entryFile)) { + throw new LoaderError(\sprintf('Entry file "%s" does not exists.', $this->publicDir.'/'.$entryFile)); } - $content = \file_get_contents($dir.'/'.$entryFile); + $content = \file_get_contents($this->publicDir.'/'.$entryFile); if (false === $content) { - throw new LoaderError(\sprintf('Unable to read file "%s".', $dir.'/'.$entryFile)); + throw new LoaderError(\sprintf('Unable to read file "%s".', $this->publicDir.'/'.$entryFile)); } return $content; diff --git a/src/Fullpipe/TwigWebpackExtension/WebpackExtension.php b/src/Fullpipe/TwigWebpackExtension/WebpackExtension.php index 0f45c28..c6d85f4 100644 --- a/src/Fullpipe/TwigWebpackExtension/WebpackExtension.php +++ b/src/Fullpipe/TwigWebpackExtension/WebpackExtension.php @@ -11,23 +11,12 @@ class WebpackExtension extends AbstractExtension /** * @var string */ - protected $manifestFile; + protected $publicDir; - /** - * @var string - */ - protected $publicPathJs; - - /** - * @var string - */ - protected $publicPathCss; - - public function __construct(string $manifestFile, string $publicPathJs = '/js/', string $publicPathCss = '/css/') + public function __construct(string $manifestFile, string $publicDir) { $this->manifestFile = $manifestFile; - $this->publicPathJs = $publicPathJs; - $this->publicPathCss = $publicPathCss; + $this->publicDir = $publicDir; } /** @@ -44,8 +33,8 @@ public function getName() public function getTokenParsers() { return [ - new EntryTokenParserJs($this->manifestFile, $this->publicPathJs), - new EntryTokenParserCss($this->manifestFile, $this->publicPathCss), + new EntryTokenParserJs($this->manifestFile, $this->publicDir), + new EntryTokenParserCss($this->manifestFile, $this->publicDir), ]; } } diff --git a/tests/TokenParser/EntryTokenParserCssTest.php b/tests/TokenParser/EntryTokenParserCssTest.php index 8caf7d6..d59bf56 100644 --- a/tests/TokenParser/EntryTokenParserCssTest.php +++ b/tests/TokenParser/EntryTokenParserCssTest.php @@ -16,18 +16,18 @@ class EntryTokenParserCssTest extends TestCase { public function testItIsAParser() { - $this->assertInstanceOf(AbstractTokenParser::class, new EntryTokenParserCss(__DIR__.'/../Resource/build/manifest.json', '/build/')); + $this->assertInstanceOf(AbstractTokenParser::class, new EntryTokenParserCss(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource')); } public function testGetTag() { - $parser = new EntryTokenParserCss(__DIR__.'/../Resource/build/manifest.json', '/build/'); + $parser = new EntryTokenParserCss(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource'); $this->assertEquals('webpack_entry_css', $parser->getTag()); } public function testBasicParse() { - $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource'); $parser = new Parser($env); $source = new Source("{% webpack_entry_css 'main' %}", ''); $stream = $env->tokenize($source); @@ -43,7 +43,7 @@ public function testBasicParse() public function testInline() { - $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource'); $parser = new Parser($env); $source = new Source("{% webpack_entry_css 'main' inline %}", ''); $stream = $env->tokenize($source); @@ -61,7 +61,7 @@ public function testItThrowsExceptionIfNoManifest() { $this->expectException(LoaderError::class); - $env = $this->getEnv(__DIR__.'/../Resource/not_exists.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/not_exists.json', __DIR__.'/../Resource'); $parser = new Parser($env); $source = new Source("{% webpack_entry_css 'main' %}", ''); $stream = $env->tokenize($source); @@ -72,20 +72,20 @@ public function testItThrowsExceptionIfEntryNotExists() { $this->expectException(LoaderError::class); - $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource'); $parser = new Parser($env); $source = new Source("{% webpack_entry_css 'not_exists' %}", ''); $stream = $env->tokenize($source); $parser->parse($stream); } - private function getEnv(string $manifest, string $publicPath): Environment + private function getEnv(string $manifest, string $publicDir): Environment { $env = new Environment( $this->createMock(LoaderInterface::class), ['cache' => false, 'autoescape' => false, 'optimizations' => 0] ); - $env->addTokenParser(new EntryTokenParserCss($manifest, $publicPath)); + $env->addTokenParser(new EntryTokenParserCss($manifest, $publicDir)); return $env; } diff --git a/tests/TokenParser/EntryTokenParserJsTest.php b/tests/TokenParser/EntryTokenParserJsTest.php index 44f74c9..2d83ce3 100644 --- a/tests/TokenParser/EntryTokenParserJsTest.php +++ b/tests/TokenParser/EntryTokenParserJsTest.php @@ -16,18 +16,18 @@ class EntryTokenParserJsTest extends TestCase { public function testItIsAParser() { - $this->assertInstanceOf(AbstractTokenParser::class, new EntryTokenParserJs(__DIR__.'/../Resource/build/manifest.json', '/build/')); + $this->assertInstanceOf(AbstractTokenParser::class, new EntryTokenParserJs(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource')); } public function testGetTag() { - $parser = new EntryTokenParserJs(__DIR__.'/../Resource/build/manifest.json', '/build/'); + $parser = new EntryTokenParserJs(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource'); $this->assertEquals('webpack_entry_js', $parser->getTag()); } public function testBasic() { - $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource'); $parser = new Parser($env); $source = new Source("{% webpack_entry_js 'main' %}", ''); $stream = $env->tokenize($source); @@ -43,7 +43,7 @@ public function testBasic() public function testDefer() { - $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource'); $parser = new Parser($env); $source = new Source("{% webpack_entry_js 'main' defer %}", ''); $stream = $env->tokenize($source); @@ -59,7 +59,7 @@ public function testDefer() public function testAsync() { - $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource'); $parser = new Parser($env); $source = new Source("{% webpack_entry_js 'main' async %}", ''); $stream = $env->tokenize($source); @@ -75,7 +75,7 @@ public function testAsync() public function testInline() { - $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource'); $parser = new Parser($env); $source = new Source("{% webpack_entry_js 'second' inline %}", ''); $stream = $env->tokenize($source); @@ -91,7 +91,7 @@ public function testInline() public function testItThrowsExceptionIfManifestIsUnreadable() { - $env = $this->getEnv(__DIR__.'/../Resource/build/no_manifest.json', '/build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/no_manifest.json', __DIR__.'/../Resource'); $parser = new Parser($env); $source = new Source("{% webpack_entry_js 'second' inline %}", ''); $stream = $env->tokenize($source); @@ -103,7 +103,7 @@ public function testItThrowsExceptionIfManifestIsUnreadable() public function testItThrowsExceptionIfEntryIsUnreadable() { - $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', '/fake_build/'); + $env = $this->getEnv(__DIR__.'/../Resource/build/manifest.json', __DIR__.'/../Resource/fake_public_dir'); $parser = new Parser($env); $source = new Source("{% webpack_entry_js 'second' inline %}", ''); $stream = $env->tokenize($source); @@ -113,13 +113,13 @@ public function testItThrowsExceptionIfEntryIsUnreadable() $parser->parse($stream)->getNode('body')->getNode('0'); } - private function getEnv(string $manifest, string $publicPath): Environment + private function getEnv(string $manifest, string $publicDir): Environment { $env = new Environment( $this->createMock(LoaderInterface::class), ['cache' => false, 'autoescape' => false, 'optimizations' => 0] ); - $env->addTokenParser(new EntryTokenParserJs($manifest, $publicPath)); + $env->addTokenParser(new EntryTokenParserJs($manifest, $publicDir)); return $env; } diff --git a/tests/WebpackExtensionTest.php b/tests/WebpackExtensionTest.php index 3b8b551..091fc00 100644 --- a/tests/WebpackExtensionTest.php +++ b/tests/WebpackExtensionTest.php @@ -11,13 +11,13 @@ class WebpackExtensionTest extends TestCase { public function testGetName() { - $extension = new WebpackExtension(__DIR__.'/Resource/manifest.json'); + $extension = new WebpackExtension(__DIR__.'/Resource/manifest.json', __DIR__.'/Resource'); $this->assertEquals('fullpipe.extension.webpack', $extension->getName()); } public function testGetFunctions() { - $extension = new WebpackExtension(__DIR__.'/Resource/manifest.json'); + $extension = new WebpackExtension(__DIR__.'/Resource/manifest.json', __DIR__.'/Resource'); $parsers = $extension->getTokenParsers(); $this->assertInstanceOf(EntryTokenParserJs::class, $parsers[0]); From cf7d262596f76abfc1278834f53b6f85b8b431cb Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 23:28:22 +0300 Subject: [PATCH 13/16] Update readme --- README.md | 8 +++----- example/config/services.yaml | 6 ++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4a22545..fc3d309 100644 --- a/README.md +++ b/README.md @@ -65,9 +65,8 @@ module.exports = { # app/config/services.yml parameters: - webpack.manifest: "%kernel.root_dir%/../web/build/manifest.json" #should be absolute - webpack.public_path_js: /build/ #same as output.publicPath - webpack.public_path_css: /build/ #same as ExtractTextPlugin.publicPath + webpack.manifest: "%kernel.root_dir%/../public/build/manifest.json" #should be absolute + webpack.public_dir: "%kernel.root_dir%/../public" #your public-dir services: twig_extension.webpack: @@ -75,8 +74,7 @@ services: public: false arguments: - "%webpack.manifest%" - - "%webpack.public_path_js%" - - "%webpack.public_path_css%" + - "%webpack.public_dir%" tags: - { name: twig.extension } ``` diff --git a/example/config/services.yaml b/example/config/services.yaml index e7dc3a8..446f5ca 100644 --- a/example/config/services.yaml +++ b/example/config/services.yaml @@ -1,7 +1,6 @@ parameters: webpack.manifest: "%kernel.root_dir%/../public/build/manifest.json" #should be absolute - webpack.public_path_js: "/build/" - webpack.public_path_css: "/build/" + webpack.public_dir: "%kernel.root_dir%/../public" services: _defaults: @@ -21,7 +20,6 @@ services: public: false arguments: - "%webpack.manifest%" - - "%webpack.public_path_js%" - - "%webpack.public_path_css%" + - "%webpack.public_dir%" tags: - { name: twig.extension } From 3ccde4491c61c4b83ebca177bd755453e179a5d1 Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 23:39:17 +0300 Subject: [PATCH 14/16] Add test badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fc3d309..3a09dd0 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Latest Version on Packagist](https://img.shields.io/github/release/fullpipe/twig-webpack-extension.svg)](https://packagist.org/packages/fullpipe/twig-webpack-extension) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) [![Total Downloads](https://img.shields.io/packagist/dt/fullpipe/twig-webpack-extension.svg)](https://packagist.org/packages/fullpipe/twig-webpack-extension/stats) - +[![Tests](https://github.com/fullpipe/twig-webpack-extension/workflows/test/badge.svg)](https://github.com/fullpipe/twig-webpack-extension/actions) Inject your webpack entry points into twig templates with easy. This repo provides a Twig extension that joins Webpack resultant files with Twig template engine in an easy way. From e515fe9f696835be5079eb04ea93954de2f79ff0 Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 23:41:49 +0300 Subject: [PATCH 15/16] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a09dd0..edd8774 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Latest Version on Packagist](https://img.shields.io/github/release/fullpipe/twig-webpack-extension.svg)](https://packagist.org/packages/fullpipe/twig-webpack-extension) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) [![Total Downloads](https://img.shields.io/packagist/dt/fullpipe/twig-webpack-extension.svg)](https://packagist.org/packages/fullpipe/twig-webpack-extension/stats) -[![Tests](https://github.com/fullpipe/twig-webpack-extension/workflows/test/badge.svg)](https://github.com/fullpipe/twig-webpack-extension/actions) +[![Tests](https://github.com/fullpipe/twig-webpack-extension/workflows/Tests/badge.svg)](https://github.com/fullpipe/twig-webpack-extension/actions) Inject your webpack entry points into twig templates with easy. This repo provides a Twig extension that joins Webpack resultant files with Twig template engine in an easy way. From cccfda5deba96ed441cb47d1f1f63c84f93ae8fa Mon Sep 17 00:00:00 2001 From: Eugene Bravov Date: Fri, 16 Oct 2020 23:42:26 +0300 Subject: [PATCH 16/16] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index edd8774..fb3cc47 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ [![Latest Version on Packagist](https://img.shields.io/github/release/fullpipe/twig-webpack-extension.svg)](https://packagist.org/packages/fullpipe/twig-webpack-extension) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) [![Total Downloads](https://img.shields.io/packagist/dt/fullpipe/twig-webpack-extension.svg)](https://packagist.org/packages/fullpipe/twig-webpack-extension/stats) -[![Tests](https://github.com/fullpipe/twig-webpack-extension/workflows/Tests/badge.svg)](https://github.com/fullpipe/twig-webpack-extension/actions) +[![Tests](https://github.com/fullpipe/twig-webpack-extension/workflows/Tests/badge.svg)](https://github.com/fullpipe/twig-webpack-extension/actions) + Inject your webpack entry points into twig templates with easy. This repo provides a Twig extension that joins Webpack resultant files with Twig template engine in an easy way.