Skip to content
New issue

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

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

Already on GitHub? # to your account

Switch from fxp assets plugin? #8688

Closed
alexandernst opened this issue Jun 7, 2015 · 163 comments
Closed

Switch from fxp assets plugin? #8688

alexandernst opened this issue Jun 7, 2015 · 163 comments

Comments

@alexandernst
Copy link

I have been using fxp and until now I had only trouble with it. It feels like it's flawed by design and makes managing the bower/npm assets a real PITA. The idea is extremely awesome, but this plugin is just near to useless.

I have been patching some very big issues it has with npm/bower/git, but issues keep popping and it just feels that the entire plugin was badly designed and that those issues won't be fixed ever or will require major changes.

Is it time to switch to something else? Or maybe invest some time working on that plugin?

@cebe
Copy link
Member

cebe commented Jun 7, 2015

the plugin was mainly used to allow requiring js and PHP dependencies together, we will need to find a better solution for 2.1. The plugin works fine for simple cases but if you have a complex bower/npm setup in your application you should consider using it natively. It was mainly ment to make it easier for unexperienced users.

@alexandernst
Copy link
Author

I guess I'll do as you say and switch to npm/bower instead of using composer for js/css deps.

@samdark samdark added this to the 2.1.x milestone Jun 8, 2015
@alexandernst
Copy link
Author

I wanted to share how I'll be switching awaay from fxp. After hitting a wall with NPM's useless prefix and .npmrc, I decided that running commands from composer.json isn't a bad idea at all:

"scripts": {
    "post-install-cmd": [
        "npm install",
        "bower install",
        "rsync -aX node_modules/ vendor/npm/",
        "rsync -aX bower_components/ vendor/bower/",
        "rm -rf node_modules bower_components"
    ],
    "post-update-cmd": [
        "php composer.phar run-script post-install-cmd"
    ]
},

@yurii-github
Copy link
Contributor

you should remove it completely. it's useless piece of garbage.
jquery and other projects are available via packagist now. if not, you can make it on your own.
In my view, the best way is you can simply use distributions like ajax.googleapis.com for demonstration purposes and leave choice for end user

also, this plugin requires you make it global or install before yii2 installation via composer, otherwise you are stuck with 2.0.xbeta with very strange errors!

by now, i'm forced to get useless jquery files etc etc. and composer doesnt have option to ignore dependencies or i don't know it. i use something like this so far to suppress useless stuff

"replace": {
    "bower-asset/jquery" : "*"
},

regards

@nsams
Copy link

nsams commented Jun 8, 2015

You might want to evaluate https://github.com/koala-framework/composer-extra-assets, we wrote it for our cms and it does the job for us.

@alexandernst
Copy link
Author

@nsams Does it work? Or it's the same shit as FXP? And by "work" I mean does it handle:

  • all npm/bower version formats (including 1, 5 || 6 || 7, 3.x, etc...)
  • recursive dependencies
  • cases when package A depends on package B with a specific version, package B is dragging package C which depends on a different version of package A

A quick test is trying to install jsonpath, which has the 3rd and the 2nd point, and "npmconf" which contains the 1st point.

@cebe
Copy link
Member

cebe commented Jun 8, 2015

Please keep your words calm, fxp plugin is not shit, it serves well for its purpose, which is to make it easy to simply require bower/npm packages with composer, it is not meant to replace more complex use cases of bower/npm. It is mainly useful to get a quick start where you do not have to setup a set of different tools to make a basic app work. When you want all the features of npm/bower, you should use them directly. Coupling this extension so tight to yii2 was a mistake which we have to fix in 2.1.

@samdark
Copy link
Member

samdark commented Jun 8, 2015

@yurii-github you're wrong about packages availability from packagist. There are some packages but the number is nothing like the number of packages available from bower. Also, most of these libraries maintained in bower only so you have to do extra work of maintaining your own composer mirror which isn't really good.

Anyway, as @cebe said, we'll, most probably, use bower/npm directly in 2.1 or even won't stick to any method of getting client packages leaving it to end user.

@nsams
Copy link

nsams commented Jun 9, 2015

@alexandernst: yes that all works:

{
    "require": {
        "koala-framework/composer-extra-assets": "*"
    },
    "extra": {
        "require-npm": {
            "jsonpath": "0.1.7",
            "npmconf": "2.1.2"
        }
    }
}

...simply because native npm is used.

@alexandernst
Copy link
Author

Then I'd vote to switch from FXP to Koala

@nsams
Copy link

nsams commented Jun 9, 2015

  • One thing koala-framework/composer-extra-assets doesn't support is composer.lock (because native bower also doesn't)
  • nodejs is required (automatically downloaded if not found globally)

@alexandernst
Copy link
Author

Both things sound reasonable, imho.

@trntv
Copy link
Contributor

trntv commented Jun 9, 2015

imho, we should use different package managers for different languages. I didn't saw any "plugins" to install php packages with npm or bower... Or we should ask @Seldaek to handle any package from github, not only those who have composer.json inside, like go language does.

@alexandernst
Copy link
Author

@trntv Koala (from what I understand) is using NPM and Bower. The benefit from using a plugin is that you can have all your libs in a single file, instead of fighting with 3 different files.

About the other thing... That won't happen. Composer devs refuse to even modify the SAR logic so that composer can handle upper/lowercase names. Making George R. R. Martin finish the last 2 books of "Song of Ice and Fire" before the end of 2015 would be easier than making composer devs even think about what you suggest.

@trntv
Copy link
Contributor

trntv commented Jun 9, 2015

we can always fork composer project or create own package manager - this is opensource world.
just dreaming :-) But, imho, we still can use different package managers for different languages, this is ugly, but faster and more reliable than fxp plugin.... and someone using php framework to create application rather than CMS should be familiar npm or bower etc.

@omnilight
Copy link
Contributor

One of the main thing we should not forget about assets: we should give developers the way to submit assets with their composer packages.

Currently FXP gives us ability to define bower or npm assets in composer.json not only for root project, but also for dependencies. We should keep this ability. I mean not to include them via composer.json, but may be some other way.

@adiramardiani
Copy link

One of the main thing we should not forget about assets: we should give developers the way to submit assets with their composer packages.
Currently FXP gives us ability to define bower or npm assets in composer.json not only for root project, but also for dependencies. We should keep this ability. I mean not to include them via composer.json, but may be some other way.

👍

@nkovacs
Copy link
Contributor

nkovacs commented Dec 9, 2015

One of the main thing we should not forget about assets: we should give developers the way to submit assets with their composer packages.
Currently FXP gives us ability to define bower or npm assets in composer.json not only for root project, but also for dependencies. We should keep this ability. I mean not to include them via composer.json, but may be some other way.

I agree. For Yii extensions, there needs to be a way to define a bower or npm asset as a dependency.

There's also the issue that two extensions can require two different, incompatible versions of a bower asset, and since koala-framework/composer-extra-assets uses the post-install hook, I don't think it can solve this.

The FXP plugin converts the bower package to a composer package, so it can influence dependency resolution, and composer can either figure out how to satisfy all the dependencies (e.g. install an older version of one extension that depends on a compatible asset), or abort the whole installation. I think koala will just fail to install the bower packages: koala-framework/composer-extra-assets#8 (comment)

@samdark
Copy link
Member

samdark commented Dec 9, 2015

Nope, it will install both versions.

@nkovacs
Copy link
Contributor

nkovacs commented Dec 9, 2015

Are you sure? It merges the versions as "somepackage": "2.0.* 3.0.*", which is an intersection: https://github.com/npm/node-semver#ranges

Comparators can be joined by whitespace to form a comparator set, which is satisfied by the intersection of all of the comparators it includes.

If it installs both, then where does it install them? They can't both be in vendor/bower-asset/somepackage, but both Yii extensions will expect to find them there.

@samdark
Copy link
Member

samdark commented Dec 9, 2015

Are we talking about bower or npm?

@nkovacs
Copy link
Contributor

nkovacs commented Dec 9, 2015

bower. koala installs npm packages into the package folder, so that shouldn't be a problem.

However, the problem then becomes that different versions of the same npm package are installed multiple times.

@resurtm
Copy link
Contributor

resurtm commented Dec 14, 2015

I don't like it either, I also vote to remove it from 2.1, and just use plain old bower.json.

@nkovacs
Copy link
Contributor

nkovacs commented Dec 14, 2015

Plain old bower.json isn't a solution for Yii extensions. What fxp/composer-asset-plugin aims to do is great: it allows a Yii extension to depend on a bower or npm asset, which gets installed globally, so in a large project you don't end up with three copies of a jquery plugin in three different places in three different yii extensions, which are then all loaded together and conflict with each other.

You also have to consider that if you remove the asset plugin, you'll break all the Yii extensions that depend on a bower or npm asset.

@samdark
Copy link
Member

samdark commented Dec 14, 2015

Breaking extensions isn't a huge issue since 2.1 would be incompatible in terms of API (at least in some cases).

@nkovacs
Copy link
Contributor

nkovacs commented Dec 14, 2015

That doesn't mean you have to break compatibility.

I don't like all the problems this plugin causes either, but I don't see a better solution to the problem that it fixes. Just throwing it out isn't a solution.

@rob006
Copy link
Contributor

rob006 commented Dec 14, 2015

Plain old bower.json isn't a solution for Yii extensions. What fxp/composer-asset-plugin aims to do is great: it allows a Yii extension to depend on a bower or npm asset, which gets installed globally, so in a large project you don't end up with three copies of a jquery plugin in three different places in three different yii extensions, which are then all loaded together and conflict with each other.

It's not great, it's annoying. Right now you need install bower packages even if you don't use it. It's always should be a app decision which frontend dependencies should use, not extension.

I think this can be solved by composer post-install command which will search bower.json files in dependencies, simple merge it and save to project bower.json or display some instructions how to deal with it.

@samdark
Copy link
Member

samdark commented Sep 10, 2016

There's bower PHP port: https://bowerphp.org/

@nkovacs
Copy link
Contributor

nkovacs commented Sep 10, 2016

@klimov-paul

Consider the following scenario:

  • Project depends on yii2-ext-a:1.* and yii2-ext-b:1.*.
  • yii2-ext-a version 1.0 depends on awesomejs:1.*.
  • yii2-ext-b version 1.0 depends on awesomejs:1.*.
  • yii2-ext-b version 1.1 depends on awesomejs:2.*.
  1. Run composer install on the project, no plugin, no asset-packagegist, loading all dependencies

yii2-ext-a:1.0 and yii2-ext-b:1.1 are installed.

  1. After composer install traverse over vendor directory in search of bower.json files by pattern vendor///bower.json
  2. collect all bower requirements and compose them into the single bower.json at the project root.
  3. Now bower.json amy be processed by native bower client or in other way, as well as it may be ignored at all.

The dependencies are merged, and bower is asked to install awesomejs:1.* and awesomejs:2.*. This is impossible.

Although there could be a problem with the asset versions conflict between different extensions, I suppose it could be handled somehow.

The only way to handle this is to inject the bower dependencies into composer's resolution algorithm so that it can figure out the solution: install yii2-ext-a:1.0 and yii2-ext-b:1.0.

@klimov-paul
Copy link
Member

The only way to handle this is to inject the bower dependencies into composer's resolution algorithm so that it can figure out the solution: install yii2-ext-a:1.0 and yii2-ext-b:1.0.

Can not we just use Composer API inside yii2-composer for this task?

@nkovacs
Copy link
Contributor

nkovacs commented Sep 10, 2016

That's why composer-asset-plugin has to be installed globally. If it isn't installed, the dependency resolution will fail (bower-asset/jquery won't be found, for example), so the plugin won't be installed either into the project.

@klimov-paul
Copy link
Member

PHP and asset-packages belong together, you need both for your application, despite the fact there's no common package manager.

It is a pity that composer core team does share your opinion. Our original hope was the composer will adopt the asset-plugin functionality into the core, and we will not have all these troubles. However, they have not considering those packages are not bound together.

The dependencies are merged, and bower is asked to install awesomejs:1.* and awesomejs:2.*. This is impossible.

Since composer somehow merges versions and its API is already exposed for yii2-composer perhaps we can do the same thing.

Personally, I have never encountered the situation assets from different extensions have a comflict or even the situation, where same bower package is requested in 2 different Yii extensions used together at the same project. It is of course possible in theory, but this is not the main our concern.
Besides I propose to generate the output file, which then can be reviewed and reedited by developer, thus he can always make some adjustments into it.

One more thing to think about: I wonder how does the Ruby solve this puzzle?

@nkovacs
Copy link
Contributor

nkovacs commented Sep 10, 2016

Since composer somehow merges versions and its API is already exposed for yii2-composer perhaps we can do the same thing.

It does this by generating a huge dependency graph and then finding a solution that satisfies all dependencies. For that to work, you have to inject all the bower dependencies (and their dependencies etc.) into the graph before the dependency resolution. To do that, you have to install a plugin globally.

It also needs to parse all the versions of bower packages and convert all of them (and their dependencies and so on) to composer packages, which is why it's slow.

Once you've already decided to install yii2-ext-b:1.1, you can't go back and change that decision because you now know that this causes a bower conflict.

If it was possible to do this in a better way, composer-asset-plugin would be doing that.

Personally, I have never encountered the situation assets from different extensions have a comflict or even the situation, where same bower package is requested in 2 different Yii extensions used together at the same project.

What about jquery? What if one extension requests 2.*, and the other requests 3.*?

Besides I propose to generate the output file, which then can be reviewed and reedited by developer, thus he can always make some adjustments into it.

This isn't a good idea. The developer probably has no idea how the extensions use the asset.

One more thing to think about: I wonder how does the Ruby solve this puzzle?

Looks like there's a very similar solution (convert bower packages to gems): https://rails-assets.org/#/
But that's not the only option.

Anyway, maybe it would be better to use npm and something like browserify or webpack. That way you could use two different versions of an asset, the only drawback would be that you'd potentially have multiple versions of an npm package sent to the client.

@schmunk42
Copy link
Contributor

@nkovacs Thanks for your comment, I wanted to write the same things (mostly).

@klimov-paul See https://gist.github.com/schmunk42/d5d192a5e727f4262507cffe84a650a4 for an example of a bit larger project ... first command is "composer show outdated", second is "composer why is jquery installed" - That's just an example of how complex things can become.

@klimov-paul
Copy link
Member

klimov-paul commented Sep 11, 2016

It does this by generating a huge dependency graph and then finding a solution that satisfies all dependencies. For that to work, you have to inject all the bower dependencies (and their dependencies etc.) into the graph before the dependency resolution.

No, no, no. You are mixing 2 different things here. With the approach I propose we do NOT need to process the depenency graph - it will be done by Bower client via its native functionality.

For example: consider we have a project which have following require section in composer.json:

"require": {
        "yiisoft/yii2": "~2.0.5",
        "yiisoft/yii2-bootstrap": "~2.0.0",
},

After installation it will load 2 libraries in the vendor each of which have its own bower.json.

1)vendor\yiisoft\yii2\bower.json contains:

"require": {
        "jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
},

2)vendor\yiisoft\yii2-bootstrap\bower.json contains:

"require": {
    "bootstrap": "3.3.* | 3.2.* | 3.1.*"
},

Although bootstrap Bower package may also specify its own dependency on jquery - we have no need to process it. We just merge 2 bower.json files into a single one, which will look like following:

"require": {
        "jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
        "bootstrap": "3.3.* | 3.2.* | 3.1.*"
},

If there is a conflict in jquery package it will be found and resolved by Bower client once it processes the file we have created.

The only trouble will be if we add some another package in our project composer.json, which will have either jquery or bootstrap inside its bower.json:

"require": {
        "jquery": ">2.2.0",
},

Only then we have to merge >2.2.0 with 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable somehow.

We do NOT load a Bower packages in this flow and thus we do NOT care about thier dependencies - this will be done by Bower client and the end of the process.

@nkovacs
Copy link
Contributor

nkovacs commented Sep 11, 2016

The only trouble will be if we add some another package in our project composer.json, which will have either jquery or bootstrap inside its bower.json:

But what if that other package requires jquery 3.*?

You can't merge that with "2.2.@stable | 2.1.@stable | 1.11.@stable | 1.12.@stable".

@klimov-paul
Copy link
Member

Yes, that is the problem, which should be resolved: we should check if version constraits can be merged and then - merge them, if they can not - we should trigger an error.

@francoispluchino
Copy link

@klimov-paul It is an approach that I had considered, see fxpio/composer-asset-plugin#93, but this merge is complex and you break the compatibility.

@klimov-paul
Copy link
Member

klimov-paul commented Sep 11, 2016

It is an approach that I had considered

Perhaps, It is, at least, similar.

you break the compatibility

I am aware of that. That is why it is only an option for Yii 2.1.x but not fot 2.0.x.

@nkovacs
Copy link
Contributor

nkovacs commented Sep 11, 2016

It's not just about breaking compatibility. You're also losing functionality.

@klimov-paul
Copy link
Member

The only loose in functionality is that conflict in bower packages version will no longer break the composer installation. While the in oppisite - you can use the features Bower native client provides like processing via Grunt.

I just try to find the solution for the question posted at this issue titile: 'Switch from fxp assets plugin'.
Unless you can convince the Composer core team to build Bower/NPM client inside their product by default we do not have much options.

@francoispluchino
Copy link

This question has already been treated by the Composer core team, and the answer is: No. So no chance for this solution.

@klimov-paul
Copy link
Member

klimov-paul commented Sep 11, 2016

I do know that.

Personally, I do not think myself to be wiser then Composer core team on this matter. I suppose if they consider bower/npm can not be processed with the composer packages at the same time - it must be some valid reason for this.

That is why I think that instead of struggeling against this restiction, we should find a walk around and process composer and bower dependencies as separated ones.

@francoispluchino
Copy link

@klimov-paul The reason is quite justified: they would not add a compatibility layer for another dependency management tools, because, in early of Composer, the system of versions management was very different from SemVer 2.0 in the syntax of dependencies (this is less the case now), and the Composer packages are case insensitive. Also , they consider that this feature can be managed in a plugin, and it's the case with my plugin. You can add the fact that some NPM or Bower packages may require a "compilation" to build a dist. You'll have more details after the section 'Proposal' of fxpio/composer-asset-plugin#93.

In my approach to the v2.0 and therefore using Nodejs, I do not know if the approach is the one you want, but I want to use all the possibilities of NPM, Bower and Nodejs, using native bower.json and package.json files (always more details in this issue, and especially why the other approaches are not appropriate in my view, in this comment).

@schmunk42
Copy link
Contributor

@klimov-paul

We do NOT load a Bower packages in this flow and thus we do NOT care about thier dependencies - this will be done by Bower client and the end of the process.

IMHO, that's a huge step in the wrong direction.

There's not only bower, but also npm. I recently had an issue with a package which dropped bower support. With c-a-p I was able to switch to npm.
I would even say that c-a-p's dependency resolution with composer is superior to native bower and npm.


but ... Coming back to #8688 (comment)

It may be useful to return to the beginning with this issue.

Let's do that, I'd even vote for closing this issue and start with a fresh one.

Because, honestly, I don't even see anymore what's problematic right now. Issues of the original post are resolved, performance has been vastly improved, ... Yes, there's still the global installation - but compared to all other solutions proposed in this thread this "problem" looks minimal to me.

I think c-a-p and Yii 2.0 are still having the best approach for asset handling. It's the best concept I've seen so far, across all frameworks and languages - and yes it's hard to make it work 100%, but there's no free lunch :)

@rob006
Copy link
Contributor

rob006 commented Sep 11, 2016

@klimov-paul

You could have 2 packages:

  1. Package A that have two branches: 2.0 that require twitter bootstrap 3.* and 2.1 that require twitter bootstrap 4.*
  2. Package B that works only with twitter bootstrap 3.*

If in composer.json you have dependencies like:

"A": "2.*",
"B": "1.*"

composer will install A@2.1.x and B@1.0.x which are incompatible. You can avoid this if you consider assets dependencies on composer update. This functionality is lost if you separate assets and composer dependencies.

@klimov-paul
Copy link
Member

Documentation issue created #13064

I am closing this issue, as complete.

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests