Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way of adding CSS or JS libraries as dependencies with Composer in Symfony2?

In the Symfony 2 docs it's said:

A bundle should not embed third-party libraries written in JavaScript, CSS, or any other language.

Then how should I do that? I want to install Twitter Bootstrap, DataTables, and many other things as dependencies using Composer. But the only way I can think of is creating a bundle and embedding them.

What is the correct way to do this?

like image 776
ChocoDeveloper Avatar asked Jul 24 '12 01:07

ChocoDeveloper


People also ask

How do I create a Composer json file?

To configure Composer for your PHP app json file specifies required packages. Verify that a composer. json file is present in the root of your git repository. Run composer install (on your local machine) to install the required packages and generate a composer.

What is the use of Composer json file?

composer. json is a JSON file placed in the root folder of PHP project. Its purpose is to specify a common project properties, meta data and dependencies, and it is a part of vast array of existing projects.

What is Composer json file in laravel?

json. The composer. json file also allows you to give your project a name, version and a few other details, which can be used to publish your own Composer packages to Packagist. Once you're happy with the dependencies you have defined; it's time to install them. Go to your command line and type composer install.

Where is Composer json located?

Composer. json - this file is the configuration for your project. This is usually best located at the top level of your project. Ideally this is a directory outside the scope of your web server - so that it will never be exposed or served.


2 Answers

You should use Bower by Twitter. It is a package manager for HTML, CSS and Javascript. It was created to address this very issue you are having.

like image 127
Joshua Pekera Avatar answered Oct 19 '22 10:10

Joshua Pekera


EDIT: As of now, there are very good package managers for JS Libraries such as Bower, Jam or Component.

Versioning system

Semantic Versioning - Composer advises to use the semantic versioning system. It uses a X.Y.Z setting, in which X is the major version, Y is the minor version and Z is the patch version. Y and Z should always be backwards compatible while X reflects changes in code which MIGHT break backwards compatibility.

Embeding

Embeding should be read as copy and pasting the code (and binary) as part of your library, rather then requiring it as a third party (vendor) package/bundle. Its like including query.js in a resource folder or copying and pasting propel code to a folder inside your bundle.

Why not embed 3rd party libs

A bundle should not embed third-party libraries written in JavaScript, CSS, or any other language.

This statement comes from a best practice point of view. Embeding (as in copy/paste) third party libraries of any kind (PHP libs especially) is usually not a good idea. For instance, imagine that BUNDLE A uses LIBRARY FOO v1.4.1, and BUNDLE B also uses LIBRARY FOO but with a different version v1.5.2. If any of the BUNDLES (A or B) embeds FOO lib, they might (most probably will) become incompatible. For instance, php classes and functions cannot be redeclared. Any of the bundles can, of course, use workarounds to mitigate this problem, such as namespacing their version of FOO or autoloading rules, but this can rise other problems as well besides surely increasing memory usage as there are 2 versions of the same thing parsed by PHP.

If a PHP package does not follow this best practice, the errors that arise are usually easy to spot (with error: cannot redeclcare function blablabla). With Javascript Libraries, however, that is not true. You can redeclare functions (as they are object properties). So if now FOO is a JS Lib instead, and BUNDLE A and B embed them into their libraries, when they are included, strange problems can arise. For instance, a function can be redeclared that lacks a crucial functionality for one of the bundles and break it.

Symfony is a PHP framework.

It deals with PHP libraries/bundles. Symfony advises to require a library as dependency instead of embedding it since it uses Composer as a Package manager, which takes care of downloading and loading the require packages. As far as I remember, when 2 bundles/packages use the same library, if they have different version requirements, the most actual is used, unless its backwards incompatible. Composer then reports a conflict that you have to manually resolve.

However... There is no way to handle javascript libraries properly. That's because Composer is a package for PHP libraries. You can workaround this in two ways I can think of: (there are probably more and best ways to handle this, I just thought of these two, read them as suggestions)

  1. Create a PHP wrapper around the javascript library and including it (although this potentially creates the same problem if another bundle decides to do the same thing but giving the package a different name)
  2. Creating a bundle which requires the javascript library as a third party dependency through composer. Since the javascript library won't probably have a composer.json file in it's repository (sometimes they live as a standalone minified file), this can be accomplished by creating a custom composer installer, forking the javascript repository (in gitHub for instance) adding a composer.json to it, etc... However, you will need to constantly maintain and upgrade the said library, which can be troublesome.

You will have to keep in mind that:

  1. JS and CSS libs have to be exposed publicly, so that the client can access it (security considerations)
  2. Symfony is a PHP framework and deals with server-side packages. JS/CSS are client side. This as to be taken in consideration so it works properly.
  3. One of the main ideas behind symfony (as with other PHP Frameworks) is code reusability within and between projects. Pure Javascript Library are reusable in themselves. They are usually self contained. Besides, there is no real gain in "bundling" a JS library from the server side. You don't need any kind of bundle to achieve reusability.

My Approach

Since the composer system is so appealing, specially when deploying bundles/packages/libraries to other people, my approach to using third party javascript/css libraries was to create a dependency manager specific to JS/CSS that other packages/bundles could rely on to take care of their JS/CSS dependencies without worrying about this.

My sugestion

If you are planing to release your project to the public, namely as a symfony bundle, you should plan carefully how to approach this. If your project is self contained (personal use or to a client, not widespread use) then this has much less relevancy since you (the programmer) have total control in what third party tools you use and include in your project. These are just best practice "suggestions" to avoid future problems.

like image 44
Tivie Avatar answered Oct 19 '22 09:10

Tivie