Fusionner des feuilles de styles css et less

Comment générer un seul css à partir de plusieurs fichiers css et less situés dans des répertoires différents ?

23 novembre 2014

Rappels

css est un langage informatique qui permet de formater l'affichage des documents html.

less est un pré-processeur de css, c'est-à-dire qu'il permet d'étendre le langage css, en ajoutant des fonctionnalités comme la possibilité d'utiliser des variables, des fonctions et bien d'autres fonctionnalités qui permettent de fabriquer des css de manière plus confortable, less est par exemple utilisé par bootstrap pour générer son css.

grunt est un outil libre qui permet d'automatiser des tâches répétitives, par exemple, compiler less en css, et fusionner les css.

Exemple d'utilisation

Nous avons utilisé cette méthode pour des questions pratiques de maintenance dans notre projet lyon.glicer.com. Notre besoin était de générer automatiquement un seul css à partir des fichiers less de bootstrap et de plusieurs css d'autres composants.

Pré-requis

node.js doit être installé, ce logiciel libre permet d'exécuter du javascript côté serveur, il est nécessaire au fonctionnement de grunt.

Installer grunt-cli

grunt-cli est l'interface de commande.

grunt-cli permet d'exécuter la version de grunt qui a été configurée dans un fichier gruntfile.js. Ceci permet d'utiliser différentes versions de grunt installées sur une même machine.

En mode administrateur, exécuter la ligne de commande ci-dessous :

npm install -g grunt-cli

Cela affiche :

C:\Users\GLICER\AppData\Roaming\npm\grunt -> C:\Users\GLICER\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt
grunt-cli@0.1.13 C:\Users\GLICER\AppData\Roaming\npm\node_modules\grunt-cli
├── resolve@0.3.1
├── nopt@1.0.10 (abbrev@1.0.5)
└── findup-sync@0.1.3 (lodash@2.4.1, glob@3.2.11)

Préparer un nouveau projet grunt

grunt a besoin d'un fichier package.json et d'un fichier gruntfile.js qui doivent être situés dans le même répertoire.

package.json : Contient la liste des composants grunt nécessaires.

gruntfile.js : Contient la liste des tâches à exécuter.

Nos fichiers sont organisés comme ci-dessous :

├───bootstrap-3.3.1
│   └───less
│           bootstrap.less

├───gruntproject
│       gruntfile.js
│       package.json

├───import
│       solver-codes.css
│       style.less

└───src
        nom-du-fichier-source.less

package.json

Dans notre cas nous avons besoin du composant grunt-contrib-less qui permet de compiler un fichier less en css.

{
    "name": "nom-du-projet",
    "version": "0.1.0",
    "devDependencies": {
        "grunt": "~0.4.2",
        "grunt-contrib-less": "~0.9.0"
    }
}

gruntfile.js

Nous devons configurer les options du composant grunt-contrib-less.

module.exports = function (grunt)
{
    // Configuration
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        less: {
            development: {
                src: '../src/nom-du-fichier-source.less',  // fichier less à compiler contenant la liste des fichiers à fusionner
                dest: '../build/nom-du-fichier-destination.css' // fichier css compilé
            }
        }
    });

    // Charge le composant qui permet de compiler le less en css
    grunt.loadNpmTasks('grunt-contrib-less');

    // Tâches à exécuter par défaut
    grunt.registerTask('default', ['less']);
};

Installer les composants

En mode administrateur, depuis le même répertoire que le fichier package.json, exécuter la ligne de commande ci-dessous :

npm install

Cela affiche :

npm WARN package.json nom-du-projet@0.1.0 No description
npm WARN package.json nom-du-projet@0.1.0 No repository field.
npm WARN package.json nom-du-projet@0.1.0 No README data
grunt@0.4.5 node_modules\grunt
├── dateformat@1.0.2-1.2.3
├── eventemitter2@0.4.14
├── which@1.0.5
├── lodash@0.9.2
├── getobject@0.1.0
├── async@0.1.22
├── hooker@0.2.3
├── colors@0.6.2
├── rimraf@2.2.8
├── grunt-legacy-util@0.2.0
├── exit@0.1.2
├── nopt@1.0.10 (abbrev@1.0.5)
├── coffee-script@1.3.3
├── iconv-lite@0.2.11
├── minimatch@0.2.14 (sigmund@1.0.0, lru-cache@2.5.0)
├── underscore.string@2.2.1
├── glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.3)
├── findup-sync@0.1.3 (lodash@2.4.1, glob@3.2.11)
├── grunt-legacy-log@0.1.1 (underscore.string@2.3.3, lodash@2.4.1)
└── js-yaml@2.0.5 (esprima@1.0.4, argparse@0.1.15)

grunt-contrib-less@0.9.0 node_modules\grunt-contrib-less
├── chalk@0.4.0 (ansi-styles@1.0.0, has-color@0.1.7, strip-ansi@0.1.1)
├── grunt-lib-contrib@0.6.1 (zlib-browserify@0.0.1)
└── less@1.6.3 (mkdirp@0.3.5, mime@1.2.11, clean-css@2.0.8, source-map@0.1.40, request@2.48.0)

Lister les fichiers css et less à fusionner

Créer un fichier less et y lister tous les fichiers. Le nom de ce fichier correspond à celui configuré comme source dans gruntfile.js (../src/nom-du-fichier-source.less)

@import '../bootstrap-3.3.1/less/bootstrap.less';
@import (inline) '../import/solver-codes.css'; //permet de copier le contenu du fichier sans le compiler
@import '../import/style.less';

Exécuter les tâches

Depuis le même répertoire que gruntfile.js, exécuter la ligne de commande ci-dessous :

grunt

Cela affiche :

Running "less:development" (less) task
File ../build/nom-du-fichier-destination.css created.

Done, without errors.

ou en spécifiant le chemin du fichier gruntfile.js :

grunt --gruntfile gruntproject/gruntfile.js

Arborescence finale

├───bootstrap-3.3.1
│   └───less
│           bootstrap.less

├───build
│       nom-du-fichier-destination.css

├───gruntproject
│   │   gruntfile.js
│   │   package.json
│   │
│   └───node_modules
│       ├───grunt
│       └───grunt-contrib-less
├───import
│       solver-codes.css
│       style.less

└───src
        nom-du-fichier-source.less

Versions des logiciels et langages utilisés