web-dev-qa-db-fra.com

Utiliser webpack avec un projet existant PHP et JS

J'ai un projet PHP existant avec jquery et bootstrap, n'utilisant aucun framework frontal.

J'essaie d'utiliser l'assembleur de modules de Webpack afin de créer un point d'entrée unique pour les ressources de mon projet, de gérer les dépendances de js avec le gestionnaire de package de noeud js, d'exécuter des tâches telles que minify js css, le redimensionnement d'images, etc. Et améliorez le temps de chargement du navigateur requis pour charger une seule page.

Je suis tombé sur les tutoriels du webpack et je l’ai installé ainsi que son serveur de développement, mais le problème est que je ne suis pas en mesure de comprendre comment je vais convertir tous mes scripts js actuels et mes liens css dans le projet (où j’ai beaucoup des bibliothèques jquery et CSS utilisées pour fournir plusieurs fonctionnalités dans le projet) pour utiliser webpack.

Dois-je réécrire tous mes fichiers JS et CSS de manière à correspondre à webpack? Comment réussir une migration?

En outre, je ne parviens pas à exécuter mon application php actuelle sur le serveur de développement webpack. Est-il censé y être exécuté en premier lieu? Il ne fait qu'énumérer les répertoires du projet entre-temps.

J'ai créé un test index.js fichier et utilisé la configuration webpack suivante:

var path = require('path');
var webpack = require('webpack');

module.exports =
{
    entry: [
        './public/js/index.js',
        'webpack/hot/dev-server',
        'webpack-dev-server/client?http://localhost:8080'
    ],
    plugins: [
      new webpack.HotModuleReplacementPlugin()
    ],
    output: {
        path: path.join(__dirname, "public/dist/js"),
        publicPath : "http://localhost:8080/my_proj/public/dist/js",
        filename: "bundle.js"
    }

};

J'ai ajouté le bundle.js mon script se charge uniquement pour les tests, dans l’espoir que l’application s’exécutera sur le serveur de développement webpack:

<script type="text/javascript" src="public/dist/js/bundle.js"></script>
<script type="text/javascript" src="public/js/jquery.min.js"></script>
<script type="text/javascript" src="public/js/jquery.migrate.js"></script>
<script type="text/javascript" src="public/js/jquery.bxslider.min.js"></script>
<script type="text/javascript" src="public/js/jquery.appear.js"></script>
<script type="text/javascript" src="public/js/jquery.countTo.js"></script>
<script type="text/javascript" src="public/js/bootstrap.js"></script>

Aidez-moi à comprendre le concept ici et comment puis-je réussir cette migration?

47
KAD

Tout d'abord, pour répondre à vos petites questions:

  • Non, vous n'êtes pas censé exécuter votre application PHP via un serveur de développement webpack. Expliqué dans la section Live Reloading ci-dessous.
  • Non, vous ne devrez pas réécrire vos actifs. Probablement. Voir les sections [~ # ~] css [~ # ~] et Edge Cases ci-dessous.

Disclaimer: Je ne répondrai qu'à une petite fraction de votre question. Sa portée est trop large pour être regroupée dans une seule réponse StackOverflow.

Je vais seulement entrer en contact avec

  • mise en place d'un environnement de développement et de production pour webpack
  • regrouper votre premier JavaScript

qui devrait vous donner une base sur laquelle construire.

Je mentionnerai également certaines choses que vous voudrez peut-être ajouter et un lien en fonction des ressources à lire.

Alors allons-y.

Exigences

Je suppose que vous avez Node.js et npm installés sur votre machine et que vous savez à peu près comment les utiliser.

Je suppose également que vous avez webpack et webpack-cli Installés en tant que dépendances (dev) de votre projet (pas seulement globalement):

npm install --save-dev webpack webpack-cli

Mise à jour: Les versions antérieures de cette réponse ne nécessitaient pas l'installation de webpack-cli. À partir de la version 4 (février 2018), la CLI de Webpack réside dans son propre package, d'où le package supplémentaire requis.

Mise en place du développement et d'un flux de production

Vous voulez généralement faire des choses différemment dans le développement que dans la production (minimisation dans la production, rechargement automatique dans le développement, ...)

Pour y parvenir, nous allons diviser nos fichiers de configuration.

Préparer la structure du répertoire

Acceptons d'ignorer la configuration WebPack de votre question. Nous allons tout recommencer, il faudrait tout changer de toute façon.

Commencez par créer un dossier build à la racine de votre projet. Les choses liées à la construction iront là-bas, car nous ne voulons pas polluer le dossier racine de votre projet avec des fichiers de configuration. (Vous êtes libre de nommer ce dossier différemment, mais gardez une trace de cela pendant ce tutoriel.)

Créez un fichier config.base.js, Un fichier config.production.js Et un fichier config.development.js Dans ce dossier.

Génial, nous avons maintenant des fichiers de configuration pour deux chaînes de construction. Cependant, les configurations sont toujours vides, alors complétons-les maintenant avec une logique de base.

Installer webpack-merge

Mais d’abord, nous devrons installer webpack-merge.

npm install --save-dev webpack-merge

Ce paquet nous permet de fusionner profondément plusieurs configurations de webpack. Nous voulons l’utiliser pour créer des configurations de packs Web en fonction de notre environnement actuel.

Ajustez votre configuration

Maintenant, ajustez votre build/config.base.js:

module.exports = {
  // We'll place webpack configuration for all environments here
}

De toute évidence, le fichier ne fait qu'exporter un objet vide pour le moment, mais nous en aurons besoin pour les étapes suivantes.

Mettez ce code dans votre build/config.production.js:

const merge = require('webpack-merge')

module.exports = merge(require('./config.base.js'), {
  mode: 'production'

  // We'll place webpack configuration for production environment here
})

Et presque le même code entre dans votre build/config.development.js:

const merge = require('webpack-merge')

module.exports = merge(require('./config.base.js'), {
  mode: 'development',
  watch: true

  // All webpack configuration for development environment will go here
})

Je suppose que ce que cela fait est assez intuitif:

Utiliser webpack avec la configuration config.development.js Va récupérer la configuration commune et fusionner sa propre déclaration de configuration dans.

Mise à jour: L'option mode dans les fichiers de configuration ci-dessus a été ajoutée dans le Webpack 4 (publié en février 2018). Il définit n groupe de valeurs par défaut sensibles pour les bundles de développement et de production.

Le processus en cours ressemble à ceci à partir de la ligne de commande:

npx webpack --config build/config.development.js

# If the above doesn't work, you probably have an older version of npm (< 5.1) installed
# While npx is a really great tool, you can of course still call the path of the webpack executable manually:

node_modules/.bin/webpack --config build/config.development.js

... et vice versa pour l'environnement production.

Cette commande est plutôt maladroite à utiliser, mais ne vous inquiétez pas, nous en reparlerons plus tard.

Faire des fichiers d'aide

Il y a des informations que nous voudrons centraliser pour les rendre facilement échangeables. Les chemins de fichiers sont une telle chose. Alors extrayons-les.

Créez un paths.js Dans votre dossier build et faites-le exporter certains chemins que nous voudrons utiliser plus tard:

const path = require('path')

// I'm really just guessing your project's folder structure from reading your question,
// you might want to adjust this whole section
module.exports = {
  // The base path of your source files, especially of your index.js
  SRC: path.resolve(__dirname, '..', 'public'),

  // The path to put the generated bundle(s)
  DIST: path.resolve(__dirname, '..', 'public', 'dist'),

  /*
  This is your public path.
  If you're running your app at http://example.com and I got your DIST folder right,
  it'll simply be "/dist".
  But if you're running it locally at http://localhost/my/app, it will be "/my/app/dist".

  That means you should probably *not* hardcode that path here but write it to a
  machine-related config file. (If you don't already have something like that,
  google for "dotenv" or something similar.)
  */
  ASSETS: '/dist'
}

Créer des alias

Comme mentionné ci-dessus, nous pourrions techniquement exécuter notre chaîne de construction en mode development comme ceci:

npx webpack --config build/config.development.js

C'est une commande inconfortablement verbeuse, alors changeons cela.

Il est bien plus pratique de lancer votre processus de construction via les scripts npm. Ajoutez un script par environnement à votre package.json Comme ceci:

{
  "scripts": {
    "dev": "webpack --config build/config.development.js",
    "prod": "webpack --config build/config.production.js"
  }
}

Vous pouvez maintenant exécuter vos chaînes de construction avec npm run dev Resp. npm run prod - beaucoup plus facile à mémoriser et à saisir plus rapidement.

... dès qu'il n'y a rien à construire, bien sûr.

Bundle JavaScript

Bon, c’était en fait une bonne quantité de travail sans trop aboutir jusqu’à présent.

Commençons donc par quelque chose de plus excitant: nous allons définir un point d’entrée JavaScript.

Définir un point d'entrée

Mettez le code suivant dans votre build/config.base.js (En remplaçant entièrement le code existant):

const path = require('path')
const { SRC, DIST, ASSETS } = require('./paths')

module.exports = {
  entry: {
    scripts: path.resolve(SRC, 'js', 'index.js')
  },
  output: {
    // Put all the bundled stuff in your dist folder
    path: DIST,

    // Our single entry point from above will be named "scripts.js"
    filename: '[name].js',

    // The output path as seen from the domain we're visiting in the browser
    publicPath: ASSETS
  }
}

Créer le fichier JavaScript

La configuration ci-dessus s'attend à ce qu'un index.js Vive dans votre dossier SRC/js (Comme défini dans build/paths.js).

Créons ce fichier avec le contenu suivant:

import './jquery.min.js'
import './jquery.migrate.js'
import './jquery.bxslider.min.js'
import './jquery.appear.js'
import './jquery.countTo.js'
import './bootstrap.js'

Comme vous pouvez le constater, le index.js Importe uniquement tous les fichiers que vous souhaitez utiliser.

Si vous courez maintenant

npm run prod

depuis votre terminal, un fichier scripts.js sera créé dans votre dossier DIST. Vous pouvez l'inclure dans votre balise avec une simple balise '<script>.

Félicitations, vous avez une configuration de webpack qui fonctionne!

Plonger plus profondément

Ce mini-didacticiel a vraiment effleuré la surface de ce que vous pouvez faire avec webpack. Cela vous donne une base solide pour votre configuration que vous pouvez maintenant remplir avec tout ce dont vous avez besoin. Et ce sera en fait beaucoup de choses.

Je vais énumérer quelques autres choses que vous voudrez peut-être améliorer, avec quelques liens à lire.

concepts Webpack

Si vous souhaitez utiliser Webpack, il peut s'avérer difficile de le faire si vous ne connaissez pas ses concepts sous-jacents. Juho Vepsäläinen a créé un excellent guide pour commencer à utiliser Webpack, qui m'a beaucoup aidé. Il est également un contributeur de base au Webpack, vous pouvez donc être sûr qu'il sait de quoi il parle.

Surtout les chargeurs sont un concept que vous besoin de savoir.

Beaucoup des astuces de cette liste y sont également expliquées.

En savoir plus: SurviveJS - tutoriel webpack

Division de code

Comme son nom l'indique, vous ne voudrez peut-être pas regrouper tout votre code JavaScript dans un fichier de sortie volumineux.

C'est un travail que Webpack fait pour vous de scinder des parties de votre lot dont vous n'avez besoin que sur certaines pages de votre application.

En outre, selon la fréquence à laquelle vous travaillez sur le code JavaScript de votre projet, il peut être judicieux de séparer le code tiers de votre ensemble à des fins de mise en cache.

En savoir plus: Documentation sur le webpack - Fractionnement du code

Mise en cache

Vous souhaiterez peut-être améliorer le comportement de mise en cache de votre site en ajoutant un hachage aux noms de fichiers fournis, qui dépend de leur contenu. Cela créera (par exemple) un script.31aa1d3cad014475a618.js Au lieu d'un scripts.js.

Ce fichier peut ensuite être mis en cache indéfiniment, car dès que son contenu change, le nom du fichier change également.

Votre code PHP peut ensuite utiliser le webpack-manifest-plugin Pour accéder aux noms de fichiers générés.

Lire la suite:

Transpiler

Si vous souhaitez utiliser du code ES2015 moderne dans le code JavaScript de votre site (et que vous ciblez des navigateurs non permanents), vous devrez les transcrire en ES5 standard. (Si le terme "ES2015" n'a aucun sens pour vous, vous ne l'utilisez probablement pas et vous pouvez ignorer ce paragraphe.)

En savoir plus: babel-loader - Un chargeur qui exécute Babel sur vos scripts

CSS

Il existe des chargeurs de packs Web pour CSS. Et Sass. Et PostCSS. Tout ce que tu veux.

Et comme vous ne prévoyez probablement pas d'inclure votre code CSS via les balises <script>, Familiarisez-vous avec le Extract Text Plugin pour générer des fichiers .css Réels.

Mise à jour: Le Extract Text Plugin est très établi. Cependant, il s’agit en fait d’une sorte de hack: il génère des fichiers .css Même si Webpack ne connaît que JavaScript comme langue cible.

Cependant, ce n'est plus le cas avec Webpack 4. Il existe maintenant un système permettant de définir des types de module arbitraires, y compris CSS.

Longue histoire courte: Attendez-vous à ce que le support CSS natif dans Webpack remplace Extract Text Plugin prochainement .

Je vais en parler parce que c'était un réel problème pour moi jusqu'à ce que je comprenne comment fonctionne Webpack ici:

Sachez que Webpack reconnaîtra vos instructions url(...) et essaiera de les résoudre par rapport à vos fichiers source.

Cela signifie que votre fichier source public/css/main.css:

body {
  background: url('../img/bg.jpg');
}

si votre chemin de sortie est public/dist/css/bundle.css, sera transformé en:

body {
  background: url('../../img/bg.jpg');
}

Lire la suite:

Minifiant

Mise à jour: Depuis la sortie du webpack 4 en février 2018, cette section est plutôt obsolète. Définir la nouvelle option mode sur "production" Applique désormais automatiquement la minification JavaScript.

Il existe un plugin Terser pour webpack afin de minifier votre JavaScript. Réduire la taille de CSS est une fonctionnalité déjà intégrée au plug-in css-loader Mentionné ci-dessus.

En savoir plus: Terser webpack Plugin

Optimisation de l'image

webpack est un bundle, pas un coureur de tâches. Ainsi, l'optimisation des images n'est pas une tâche Webpack authentique. Il vaudrait probablement mieux utiliser un programme d'exécution de tâches réel ou simplement définir quelques scripts npm pour cela.

Cela ne signifie pas que webpack n'est pas capable de le faire. Il y a des plugins pour à peu près tout.

Lire la suite:

Rechargement en direct

Vos problèmes avec le rechargement en direct ont une cause assez simple: un serveur de développement webpack n'est qu'un simple serveur Node.js servant uniquement des fichiers statiques.

Pour votre cas, webpack-dev-server Est probablement le mauvais outil du tout. Essayez plutôt webpack-livereload-plugin Pour un rechargeur actif que vous pouvez simplement inclure via la balise <script>.

En savoir plus: webpack-livereload-plugin

Cartes source

Mise à jour: À partir du pack Web 4 (publié en février 2018), les cartes source sont générées automatiquement lorsque la nouvelle option mode est définie sur "development".

Par tous les moyens, utilisez des cartes sources. Ils faciliteront votre travail avec les liasses et vous aurez envie de pleurer.

En savoir plus: Documentation sur le pack Web - Cartes source

Cas de bord

Habituellement, tous vos scripts existants que vous allez traiter avec Webpack devraient fonctionner correctement.

La seule exception qui me vient à l’esprit à l’heure actuelle concerne les entités globales.

Regardez le code suivant:

function myFunc () {
  console.log('I exist!')
}

Ce code dans un fichier JavaScript simple rendrait myFunc disponible partout dans votre code JS. Mais comme le code de paquet Webpack est encapsulé dans des fonctions de rappel (et laisse donc la portée globale), il n’y aura plus d’accès à cette fonction.

Les bibliothèques tierces ne devraient pas être un problème là-bas, elles assignent généralement leurs globales à l'objet window directement, mais si vous avez déjà écrit du code JS dans votre projet, vous devriez en être conscient.

Automatiser!

Vous voudrez automatiser autant que possible votre flux de travail.

Envisagez de lancer npm run prod Via un crochet git avant d'appuyer/après avoir tiré.


J'espère que cela t'aides.

132
Loilo

Sur la base des modèles de vue existants et de la réponse de @Loilo, j'ai créé un modèle vue) que vous pouvez installer avec vue-cli. Ce modèle vous permet de démarrer une application vue) que vous pouvez étendre ou intégrer à votre environnement existant.

npm install -g vue-cli
vue init delcon/webpack-simple my-project
cd my-project
npm install

devwatch:

Ce modèle a une option supplémentaire d’exécution de devwatch qui surveille les changements de fil au lieu d’utiliser le serveur webpack-dev-server. Cela le rend utilisable pour tout environnement de serveur Web existant.

npm run devwatch

dev:

pour l'exécuter avec le serveur Webpack-dev-server par défaut, supprimez <script src="http://localhost:35729/livereload.js"></script> dans index.html:

npm run dev

build:

pour construire votre projet en production:

npm run build
0
Delcon