Avec Ruby On Rails 6, celui-ci dispose d'une fonctionnalité majeur et non négligeable à savoir Webpack. Mais il faut savoir que Webpack n'est pas uniquement prévu pour du Javascript car,  vous pouvez également y ajouter vos images, polices, stylesheet. Ici le but de ce billets c'est de vous montrer comment réorganiser votre application RoR en utilisant pleinement Webpack et délaissant complètement le dossier assets (ou presque).

Structure des fichiers

Voici la structure que nous allons utiliser avec Webpack. Simple mais efficace.

app/javascript
├── components
│   └── Taco.js
├── css
│   ├── main.css
├── images
│   ├── burritos.jpg
│   ├── guacamole.jpg
│   └── tacos.jpg
└── packs
    └── application.js
Je sais ce que vous vous dites à ce moment là, mettre des images / feuilles css dans un dossier javascript au lieu de assets ? Really? Avec une approche à la manière de Webpack en faite, ce n'est pas du tout étrange. Si vraiment cela vous dérange vous pouvez renommer le dossier app/javascript

Les images depuis le JS

Pour référencer une image depuis javascript dans votre le build Webpack, il faut tout simplement importer comme si c'était un simple module, l'image souhaitée.

// app/javascripts/components/Taco.js
import TacoImage from '../images/tacos.jpg'

export default function({ title }) {
  return `
  <div>
    <h1>${title}</h1>
    <p><img src=${TacoImage} alt="Tacos, yum" /></p>
  </div>
  `
}

Dans l'exemple ci-dessus, Webpack va importer TacoImage comme un lien vers le fichier. Le lien en question ressemblera à quelque chose comme cela  packs/media/images/tacos-abcd1234.jpg

Importer une image fonctionne aussi si vous utilisez du CSS dans votre code Javascript comme l'exemple ci-dessous.

import React from 'react'

import TacoImage from '../images/tacos.jpg'

const styles = {
  backgroundImage: `url(${TacoImage})`,
}

export default function ({ title }) {
  return (
    <div style={styles}>
      {title}!
    </div>
  )
}

 

Les images depuis le CSS

Si vous vous souvenez bien de Rails, à la base pour appeler une image depuis une feuille SCSS, il suffisait d'utiliser l'helper image-url(). Avec Webpack nous allons simplement utiliser le standard CSS à savoir url() avec le chemin de l'image.

/* app/javascript/css/main.css */
.burritos {
  background-image: url("../images/burritos.jpg");
}

 

Et pour les images incluses dans les fichiers CSS des modules installé via NPM ?

Si vous avez comme moi installé plusieurs plugins via yarn/npm vous avez sans doute eu l'erreur suivante :

Module not found: Error: Can't resolve '../img/controls.png'

 On en parle également sur Stackoverflow.

Pour résoudre ce soucis en réalité il suffit d'installer le plugin suivant :

yarn add resolve-url-loader

Ensuite, il va nous falloir configurer Webpack, dans le fichier config/webpack/environment.js il vous faudra ajouter ce petit bout de code.

// config/webpack/environment.js
const { environment } = require('@rails/webpacker')

// resolve-url-loader must be used before sass-loader
environment.loaders.get('sass').use.splice(-1, 0, {
  loader: 'resolve-url-loader'
})

Cette règle de chargement, s'assure que le bon lien est utilisé dans le fichier de sortie CSS par Webpack.

Images dans une vue

Pour afficher une image contenue dans le dossier assets, auparavant il nous suffisait simplement d'utiliser ce petit bout de code <%= image_tag 'tacos.jpg' %> mais maintenant, étant donné que nos images ne sont plus dans ce dossier, Webpack a sa propre fonction, il vous suffit de faire comme ceci : 

<%= image_pack_tag 'media/images/guacamole.jpg' %>

Note: depuis Webpacker 4, le préfix media/ est nécessaire pour afficher une image.

Voilà, je pense que nous avons fait le tour du sujet, j'espère que ce billet vous sera utile :)

Source: https://dev.to/rossta/importing-images-with-webpacker-2302