kriswallsmith / assetic

Asset Management for PHP
MIT License
3.76k stars 580 forks source link

Assetic <3 Grunt, Require.JS, Almond... #529

Open guilhermeblanco opened 10 years ago

guilhermeblanco commented 10 years ago

It seems Assetic needs some love with these tools. =) So far the only way I could get to have Almond and/or Require.JS working is by hacking HearsayRequireJSBundle ( https://github.com/hearsayit/HearsayRequireJSBundle ).

kriswallsmith commented 10 years ago

I would love to see better support around these tools too. Can you be more specific about the role you would like Assetic to play when working with those tools?

l3l0 commented 10 years ago

Hello I just want to describe some problems I had with integrate some frontend stuff in Symfony.

Right now most of the time when we want to install some js lib we have to download files to web or to bundle resource js dir and we need to store it in our repo. Can manage those libs can be really painfull so we (in our current project) are using separate client side app (angularjs) with configuration taken base on ng-boilerplate. I would like to see some Symfony2 project with good frontend deps convention.

I would love to have something to install and require/use frontend libs in Symfony project (via integrate by bower or npm). I mean maybe some kind of assetic:install cmd which can take into account bower.json or some else installation file... It can be event better maybe we could install and dump our frontend deps using assetic

I am not sure about how we can integrate grunt... it can probably be used separately most of the time. For sure good option will be to integrate stuff like karma spec framework with assetic watch mode... so maybe we should be able to define some commands/frontend script which can be runned using grunt things...

docteurklein commented 10 years ago

@l3l0 It's interesting to see that grunt + bower already does all we need for frontend dev. I think those tools replaces very well assetic. Why calling an assetic command that would itself do nothing more than calling grunt + bower ? For the pleasure of php ? :)

Another advantage I see concerning usage of these tools instead of assetic is that they are frontend oriented. A frontend developer who will have to work on the project will not understand all these twig fuuuuu, use_controller, bundles?, template inheritance, blocks, the debug question mark,and other tricky stuff. He will however be more used to frontend specfic tools like bower.

To me, @willdurand resumed it very well.

willdurand commented 10 years ago

I can't agree with @docteurklein more.

ribeiropaulor commented 10 years ago

I agree with @docteurklein as well.

When working in the frontend of a single page app, it feels like a whole new world, different from Symfony/PHP one. It's more like consuming it like an API.

sandermarechal commented 10 years ago

@l3l0 I handle front-end libs with bower. I have a bower.json file in the root of my project. I have bower install all the packages in an assets directory so I can use them with Assetic. This is the setting in my bower.json:

"directory": "app/Resources/assets/bower"

Then I can use the packages in Symfony like:

    {% block javascripts %}
        {% javascripts
            '../app/Resources/assets/bower/jquery/jquery.js'
            '../app/Resources/assets/bower/foundation/js/foundation/foundation.js'
        %}
            <script src="{{ asset_url }}"></script>
        {% endjavascripts %}
    {% endblock %}

@kriswallsmith Perhaps Assetic can make it easier to use bower packages? Referring to files like this is verbose. Defining assets in the config manually for all these packages is equally verbose (plus, you have to split the js, css, scss, etcetera in different assets).

garak commented 10 years ago

My current solution for frontend libs is using composer with https://github.com/components Indeed, I'm not very happy with it, but it's better than including frontend libs in my repo

Spea commented 10 years ago

I created a bundle for a better bower integration with symfony2. Maybe it is of use for someone here.

willdurand commented 10 years ago

@garak you can just add a bower file to your repo ;-)

garak commented 10 years ago

Thanks @willdurand, I'm just exploring that way for projects in which node is not a problem. Looks good, but suggestion from @sandermarechal did not work for me, I had to add a .bowerrc file to specify "directory" option.

l3l0 commented 10 years ago

@sandermarechal oh seems to be really cool. I would like to read some blog post(s) with examples about it :) @docteurklein @willdurand yeah I agree as well. I just think that it not always needed to create separate client side app to have really nice and clean frontend stuff - I would like to see how it can looks in project without separate client app (I thought that Assetic can help ;) ). And @sandermarechal just show me one quite interesting thing :)

sandermarechal commented 10 years ago

@Spea Your bundle is pretty cool. But I wonder if it would be better to merge all the bower dependencies from the bundles into an app-specific bower.json and install that instead. I think front-end libs should be app-specific and not bundle-specific. Much like there's only one Composer vendor directory in an app. Bundles tell the app what front end libs are needed and the app makes sure they are all there.

Perhaps a similar approach would also work for Grunt? Combine all grunt tasks from all bundles into one app-level grunt file? I don't know Grunt so I may be talking nonsense.

Spea commented 10 years ago

I don't think it would be better to merge all of them, since you may have some bower dependencies in one bundle that you don't want to use in another. But I'm planing to support a "global" bower.json, which you will place in your root dir

webberig commented 10 years ago

I truely love working with Grunt and Bower for my own projects, but I have my doubts this is a good solution for opensource software.

I need to have some kind of distributable package that can easily be installed. I don't want my users to depend on Grunt and Bower to be able to use my bundles... That also means that making my software depend on @Spea 's bundle is a good idea...

I ideally want to use bower for asset management during development, but have the used files inside the repo for distribution...

docteurklein commented 10 years ago

@webberig this is as strange as saying you don't want to depend on composer, but prefer having all the php deps in the repo for distribution.

webberig commented 10 years ago

That's true. But using composer is already present when using Symfony in the first place - they are both PHP. If the software targets an audience already familiar with Symfony, composer should be familiar too... Using grunt and bower is a different story, you might end up explaining how to install node.js in your documentation.

I'm not saying it doesn't make sense to do this, but it's something I want to think (and discuss) about before blindly adding it to my software. I can't find a popular software package that doesn't include thirdparty JS plugins in its distribution package.

docteurklein commented 10 years ago

I can't find a popular software package that doesn't include thirdparty JS plugins in its distribution package.

That's why all these popular packages should use a popular js package mechanism (aka: bower).

garak commented 10 years ago

@webberig you don't need to install node.js anymore to use bower. See http://bowerphp.org/

henrypenny commented 10 years ago

Back to the original post and KWS's follow up.

Its seems to me that Assetic works fine on a compiled requirejs project (i.e. production), but there doesn't seem to be an easy way to develop with individual js files.

Symlinking the vendor and application folders from your project into web/ could be one solution, but that would probably only work with one bundle at a time. Developers may well be working in multiple bundles, possibly with different vendor folders.

One solution could be to provide a nice means to write a basePath global var into your HTML doc (most probably the head tag):

{% assetic_base_url '@MyBundle' %}
<script>
var MyBundle_base_path = '{{ asset_url }}/js/';
</script>
{% endassetic_base_url %}

In dev this would produce:

<script>
var mybundle_base_url= '/bundles/mybundle/js/';
</script>

This could then be used in your requirejs config as the basePath.

require.config({
    baseUrl: mybundle_base_url,
    paths: {
        jquery              : 'vendor/jquery/jquery',

In production this var would be unnecessary so the tag could produce an empty string.

This would allow multiple projects to live and work inside their own bundle subdirectories.

This following code already works for me in a production context:

<script
{% javascripts '@MyBundle/Resources/public/js/main.js' %}
data-main="{{ asset_url | slice(0, -3) }}"
{%endjavascripts %}
{% javascripts '@MyBundle/Resources/public/js/require.js' %}
src="{{ asset_url }}" >{% endjavascripts %}
</script>
henrypenny commented 10 years ago

Actually:

Its pretty easy to just hardcode the path to your symlinked project in your requirejs config:

baseUrl: '/bundles/mybundle/js/'

The config is only used in dev or while compiling. It doesn't matter what's in there in production.

A new tag is not really necessary since you'd only change that path if you changed your bundle name... which is not so common.

henrypenny commented 10 years ago

Adding symfony console commands into grunt is pretty easy too:


    grunt.loadNpmTasks('grunt-shell');

...

        shell : {
            assetic_dump : {
                options: {
                    stdout: true
                },
                command: 'app/console assetic:dump; '
            },
            assetic_watch : {
                options: {
                    stdout: true
                },
                command: 'app/console assetic:dump --watch &'
            },
ollietb commented 9 years ago

We've been using Gassetic with Symfony2 for a while now. It uses Grunt & Bower instead of Assetic, so it requires installing those packages outside of Symfony, but once it's set up it makes it much easier to manage our frontend workflow.

henrypenny commented 9 years ago

How do you manage assets from multiple bundles?

ollietb commented 9 years ago

@henrypenny Adding a javascript from a bundle is the same as adding any other path. In the example in the documentation there are javascript files from 2 different bundles.