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.
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;
}
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
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.
Et le dossier de destination est bien priv/static
Mais malheureusement, nos css et js ne sont plus chargés
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 🎉.
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
- Je me suis inspiré de ce dépôt Github. La base de code reprend la structure d'une ancienne version de Phoenix, ne l'utilisez pas tel quel si vous voulez être à jour.
- Mon ancien article
- La documentation sur la configuration du Endpoint
Top comments (4)
Bonjour, pourquoi Parcel alors que webpack existe ? On change de bundler et on se sent disruptif ?
Bien à vous :)
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
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.
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