Skip to content

Initial bundle setup & feature implementation #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 21, 2018

Conversation

weaverryan
Copy link
Member

@weaverryan weaverryan commented Sep 9, 2018

Hi guys!

This adds all the low-level details (composer, travis, etc) + the features themselves, which the README describes. Notes:

  • Bundle supports PHP 7.1 and above

Why this bundle?

An optional feature in Webpack 4 allows Webpack to "split" an entry (e.g. app.js) into multiple, smaller files for performance. But, this means that you need multiple <script> tags for each entry... but these are dynamically created and changing. To help with that, Encore dumps a new entrypoints.json file, which describes which JS (or CSS) files are needed for each entry. This bundle adds a feature to read those. That's described in the README below (I'll likely move most of the README into the official docs).

Cheers!

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it looks good. Just found some minors


private $entriesData;

private $returnedFiles = [];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

array()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or, we might be okey with [] since fabbot is not active here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, not sure. We use [] on MakerBundle, but were forced to not use fabbot due to this :/. Using fabbot is ideal.

Copy link
Member

@nicolas-grekas nicolas-grekas Sep 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no reason to use array() here, as there is no merge conflict to save us from

@@ -0,0 +1,46 @@
<?php

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we declare classes as strict?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with that, but we're not using them in symfony/symfony yet - I'm not sure if that's a policy, or for other reasons (that don't apply here)

Copy link
Member

@nicolas-grekas nicolas-grekas Sep 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I don't see the benefit of strict mode: it provides no benefit for the "public" facing APIs.
Of course strict mode can help spot some errors inside the boundaries of the facing API, but anyway, this is covered by community work+tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolas-grekas

it provides no benefit for the "public" facing APIs.

Doesn't it? Does it not trigger type errors if the API is misused from userland?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, not any, see also discussion in symfony/symfony#28423

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, I misunderstood this comment. 🙈 Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

triggering such error is what types are doing, not strict mode (strict mode in userland makes type stricter for arguments)

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

random comments :)

.travis.yml Outdated
# Test the latest stable release
- php: 5.5
- php: 5.6
- php: 7.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed, minimum php is 7.1, isn't it?

.travis.yml Outdated
# Test LTS versions. This makes sure we do not use Symfony packages with version greater
# than 3. Read more at https://github.com/symfony/lts
- php: 7.2
env: DEPENDENCIES="symfony/lts:^3"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

going to be deprecated, better use global flex + SYMFONY_REQUIRE (see symfony's .travis.yml)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should update our docs for "best practices for reusable bundles"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a LOT of custom code in symfony's .travis.yml file - I'm not sure what's needed. I see the install flex part - https://github.com/symfony/symfony/blob/master/.travis.yml#L198-L205 - I need that, makes sense. But what about the big "running tests" block? https://github.com/symfony/symfony/blob/master/.travis.yml#L216-L244

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, only L198-L205, the rest is too specific

.gitignore Outdated
@@ -0,0 +1,3 @@
composer.lock
phpunit.xml
vendor/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing EOL (there are more in the PR)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about adding a .editorconfig to the project? This would reduce these kinds of errors.

.travis.yml Outdated
# Minimum supported dependencies with the latest and oldest PHP version
- php: 7.2
env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" SYMFONY_DEPRECATIONS_HELPER="weak_vendors"
- php: 7.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed

.travis.yml Outdated
# Test LTS versions. This makes sure we do not use Symfony packages with version greater
# than 3. Read more at https://github.com/symfony/lts
- php: 7.2
env: DEPENDENCIES="symfony/lts:^3"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, only L198-L205, the rest is too specific

}
}

return isset($this->manifestData[$path]) ? $this->manifestData[$path] : null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return $this->manifestData[$path] ?? null;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that the same? Does your version not throw a warning about a non-existent key?

Copy link
Member

@chalasr chalasr Sep 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not, that's the same :)

"type": "symfony-bundle",
"license": "MIT",
"authors": [
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add yourself, that's deserved IMHO

README.md Outdated

This bundle allows you to use the `splitEntryChunks()` feature
from [Webpack Encore](https://symfony.com/doc/current/frontend.html)
by reading an `entrypoins.json` file and helping you render all of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo in the file name

private function getAssetPath(string $assetPath, string $packageName = null): string
{
if (null === $this->packages) {
throw new \Exception('To render the script or link tags, run "composer require symfony/asset".');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All public APIs of this class are reaching this validation. So why is the Packages dependency an optional one in the constructor ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. And, there may be a better solution. It's so that I can have:

<argument type="service" id="assets.packages" on-invalid="null" />

For this service's definition. I suppose I could remove this service definition entirely in a compiler pass if assets.packages is not present. However, this TagRenderer service is itself required by the Twig extension. So it would need on-invalid="null" and to have some code to throw an exception in the correct situation. I'm not sure if one solution is absolutely better than another, or if there's a general standard.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or remove also the Twig extension when it does not have the needed dependency, which is what we do in symfony itself.

foreach ($this->entrypointLookup->getCssFiles($entryName) as $filename) {
$scriptTags[] = sprintf(
'<link rel="stylesheet" href="%s" />',
$this->getAssetPath($filename, $packageName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is missing HTML escaping.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right. But, this is tricky: the asset path needs the equivalent of html_attr escaping from Twig. However, this bundle currently does not rely on Twig, and the logic for this escaping is too big to copy (https://github.com/twigphp/Twig/blob/84b2eb541026dbd39590ba80269ae7676b1bfc46/lib/Twig/Extension/Core.php#L1033) and it's not a good idea anyways, since it's security-related.

The only solution I can think of is to couple the bundle to Twig (no huge deal), and either use that twig_escape_filter function directly (bit hacky) or render Twig templates inside of TagRenderer.

Any other ideas?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, at first, you can still apply normal PHP escaping. As you put this inside a quoted HTML attribute, things are fine (most of the escaping performed by html_attr is to allow to use it outside quotes, so for attribute names or unquoted attribute values).

Not doing any escaping can lead to broken HTML here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, ok. I've just used htmlentities and added a test. If you know of any issues with that, please let me know!

foreach ($this->entrypointLookup->getJavaScriptFiles($entryName) as $filename) {
$scriptTags[] = sprintf(
'<script src="%s"></script>',
$this->getAssetPath($filename, $packageName)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is missing HTML escaping.

],
"autoload": {
"psr-4": {
"Symfony\\WebpackEncoreBundle\\": "src"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't there be a trailing / after src?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed. Composer would trim it if it exists.

}

$this->manifestData = json_decode(file_get_contents($this->manifestPath), true);
if (0 < json_last_error()) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about making this JSON_ERROR_NONE !== json_last_error()? It would make it more clear what is happening

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree here

@weaverryan
Copy link
Member Author

Updated! In a few days (and after the tests are working), I'll merge this. So, any additional feedback is warmly appreciated :).

@stof
Copy link
Member

stof commented Oct 16, 2018

This should wait for symfony/webpack-encore#410 which changes a bit the structure of the entrypoints file (CSS becomes a string rather than an array of strings)

.php_cs.dist Outdated
$finder = PhpCsFixer\Finder::create()
->in(__DIR__.'/src')
// the PHP template files are a bit special
->notName('*.tpl.php')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have such files ?

.php_cs.dist Outdated

if (\PHP_VERSION_ID < 70100) {
// EntityRegenerator works only with PHP 7.1+
$finder->notName('EntityRegenerator.php');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that looks wrong here. Bad copy-paste ?

.php_cs.dist Outdated
'semicolon_after_instruction' => false,
'header_comment' => [
'header' => <<<EOF
This file is part of the Symfony MakerBundle package.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong

simple-phpunit Outdated

error_reporting(-1);

$getEnvVar = function ($name, $default = false) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file looks wrong. Install the phpunit-bridge instead of duplicating its code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temporary code - debugging a weird Travis-only phpunit issue :/

@Nyholm
Copy link
Member

Nyholm commented Oct 20, 2018

Since this is the first lines of code to repo, I suggest we should merge it now. It may not be perfect but it does not have to be perfect now.

If this is merged now we all can help to make it better.

👍 good job

@weaverryan weaverryan force-pushed the first-implementation branch from 0ca2ab2 to 6eecd88 Compare October 21, 2018 18:56
@weaverryan weaverryan merged commit 6eecd88 into master Oct 21, 2018
weaverryan added a commit that referenced this pull request Oct 21, 2018
This PR was merged into the master branch.

Discussion
----------

Initial bundle setup & feature implementation

Hi guys!

This adds all the low-level details (composer, travis, etc) + the features themselves, which the README describes. Notes:

* Bundle supports PHP 7.1 and above

**Why this bundle?**

An optional feature in Webpack 4 allows Webpack to "split" an entry (e.g. `app.js`) into multiple, smaller files for performance. But, this means that you need multiple `<script>` tags for each entry... but these are dynamically created and changing. To help with that, Encore dumps a new `entrypoints.json` file, which describes which JS (or CSS) files are needed for each entry. This bundle adds a feature to read those. That's described in the README below (I'll likely move most of the README into the official docs).

Cheers!

Commits
-------

6eecd88 Initial bundle setup & feature implementation
@weaverryan weaverryan deleted the first-implementation branch October 21, 2018 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants