DEV Community

Cover image for Phoenix : changer de bundler
jean-smaug
jean-smaug

Posted on • Updated on • Originally published at maximeblanc.fr

Phoenix : changer de bundler

Depuis sa version 1.4, Phoenix embarque Webpack pour bundler les différentes dépendances. Nous allons voir qu'il est facile de changer d'outil en prenant Parcel comme exemple.
Cet outil a l'avantage de ne pas nécessiter de configuration pour fonctionner.

Initialisation

Créons un nouveau projet, sans "ecto" pour ne pas avoir besoin de configurer une base de données.

mix phx.new app --no-ecto

Lançons le serveur de Phoenix.

mix phx.server

Phoenix exécute Webpack pour nous et écoute les changements de fichiers pour nous apporter les modifications en hot reload.

phoenix-launch-webpack

Si j'édite le fichier assets/css/app.css pour changer la couleur de fond du body on peut voir le changement sans recharger la page.

/* This file is for your main application css. */

@import "./phoenix.css";

body {
  background: darkgray;
}

webpack-change-color

Notre but est donc de garder ce comportement, qui offre un confort de développement, mais en utilisant un autre outil.

Webpack build nos assets à destination de priv/static. Phoenix nécessite que nos fichiers statiques soient buildés à destination de ce dossier. Cela reste néanmoins configurable

webpack-build

Avant de continuer coupons notre serveur et supprimons le dossier généré par Webpack pour partir sur une base propre

rm -rf priv/static

Configuration de Parcel au sein de Phoenix

Installons Parcel ainsi qu'un plugin magique dont le détail ne rentre pas dans le cadre de cet article.

cd assets/ && npm install --save-dev parcel-bundler parcel-plugin-static-files-copy

Dans le fichiers config/dev.exs il faut remplacer

config :app, AppWeb.Endpoint,
  http: [port: 4000],
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: [
    node: [
      "node_modules/webpack/bin/webpack.js",
      "--mode",
      "development",
      "--watch-stdin",
      cd: Path.expand("../assets", __DIR__)
    ]
  ]

par

config :app, AppWeb.Endpoint,
  http: [port: 4000],
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: [
    node: [
      "node_modules/.bin/parcel",
      "watch",
      "js/app.js",
      "-d",
      "../priv/static",
      cd: Path.expand("../assets", __DIR__)
    ]
  ]

Désormais lorsque nous lançons un mix phx.server nous pouvons voir que Phoenix lance désormais Parcel.

phoenix-launch-parcel

Et le dossier de destination est bien priv/static

build-parcel-priv

Mais malheureusement, nos css et js ne sont plus chargés

broken-page

Webpack générait un dossier css et un dossier js contenant chacun leur bundle. Parcel se passe des dossiers intermédiaires. Il faut donc aller mettre à jour les chemins des fichiers importés dans le template lib/app_web/templates/layout/app.html.eex.

On remplace

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
  </head>
  <body>
    ###
    <script type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
  </body>
</html>

par

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="<%= Routes.static_path(@conn, "/app.css") %>"/>
  </head>
  <body>
    ###
    <script type="text/javascript" src="<%= Routes.static_path(@conn, "/app.js") %>"></script>
  </body>
</html>

Et 🎉, ça ne marche pas 😢.

Ce comportement vient du fait que Phoenix autorise uniquement les fichiers respectant certains patterns à être servi comme fichiers statiques. Ces patterns sont configurables dans le fichiers lib/app_web/endpoint.ex

  plug Plug.Static,
    at: "/",
    from: :app,
    gzip: false,
    only: ~w(css fonts images js favicon.ico robots.txt)

Cette configuration signifie que seul les fichiers présents dans les dossiers css fonts images js ou les fichiers favicon.ico et robots.txt sont autorisés à être servi par Phoenix. Ces dossiers doivent bien entendu être présent dans priv/static 😉.

  plug Plug.Static,
    at: "/",
    from: :app,
    gzip: false,
    only: ~w(app.css fonts images app.js favicon.ico robots.txt)

Comme nous n'avons pas de dossiers intermédiaires css et js nous les remplaçons par les fichiers app.css et app.js généré par Parcel.

Maintenant l'application fonctionne correctement. Si j'édite le fichier assets/js/app.js pour y ajouter un console.log

import "phoenix_html"
import css from "../css/app.css"

console.log("Meeeeeeeeh")

Un "Meeeeeeeeh" apparait dans la console de notre navigateur sans avoir besoin de recharger la page 🎉.

meeeeeh

Nettoyage

Maintenant que nous avons ajouté Parcel il ne nous reste plus qu'a supprimer les vestiges de Webpack :

cd assets && npm uninstall babel-loader copy-webpack-plugin css-loader mini-css-extract-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin webpack webpack-cli && rm webpack.config.js

Conclusion

Peut importe que vous choisissiez de garder Webpack, d'utiliser Rollup, Parcel… Si vous choisissez de modifier la configuration de votre bundler, il faut penser à :

  • configurer correctement son bundler (facile avec Parcel)
  • changer le script surveillant les modifications de fichiers (dev.exs)
  • veiller à ce que le fichiers statiques puissent être servi correctement (endpoint.ex)
  • modifier les chemins dans les templates (app.html.eex)

Liens utiles

Top comments (4)

Collapse
 
martinjeremyl profile image
martinjeremyl

Bonjour, pourquoi Parcel alors que webpack existe ? On change de bundler et on se sent disruptif ?

Bien à vous :)

Collapse
 
jeansmaug profile image
jean-smaug

Bonsoir,

Mon but est clairement de ne rien apporter de constructif mais de soigner mon image de marque afin de prouver à un futur recruteur que je sais aligner 3 phrases dans un jargon technique.

Je souhaite aussi a travers ce post faire de la propagandevangélisation d'Elixir, langage qui permet de résoudre des problématiques intéressantes.

Enfin concernant Parcel, il permet de présenter les concepts de Phoenix.

Mange ta DDB

Bonne soirée :)

Cordialement

Collapse
 
martinjeremyl profile image
martinjeremyl

Pardonne ma médisance stp, après relecture j'utiliserai ta stack technique sur un mort et sans vergogne :)

Sans rigoler.

Je pratique le développement web depuis maintenant 6 ans, du devops en parallèle depuis 7 ans, je pourrai.

Ainsi que le datascientisme depuis 4 ans, 1m87 pour 86 kg

J'ai une vitesse de fou, et des compétences algorithmiques identiques à ma vitesse.

Thread Thread
 
jeansmaug profile image
jean-smaug • Edited

Parfois quand je suis dans l'open space j'enfile mes écouteurs et ma capuche.

Lorsqu'une lady passe, je lache un "okamari no sql", ça ne veut rien dire mais ça a un côté mystérieux, les filles aiment bien.

Enfin lorsque vient le moment de partir je mets mes bras en arrière et je cours a toute vitesse sur les murs. Mes collègues sont impressionnés par ces capacités hors du commun.

Rasengan no sozuki