David Soyez @2016
Code source des exemples: https://github.com/david-soyez/webpack_intro
Webpack prend des modules avec dépendances et génère des assets représentant ces modules.
Webpack est comparable aux outils tels que Grunt, Gulp, RequireJs, Browserify...
Popularité:
Tendance:
Objectifs:
Plus concrètement:
// installation globale
$ npm install --save-dev webpack
// usage global
$ webpack
// installation locale dans un projet
$ npm init
$ npm install --save-dev webpack
// usage local dans un projet
$ nodejs ./node_modules/webpack/bin/webpack.js
$ vim entry.js
document.write("Ca fonctionne.");
$ vim index.html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type="text/javascript" src="bundle.js" charset="utf-8"></script>
</body>
</html>
$ webpack ./entry.js bundle.js
Hash: e50979b7c38d7547d9e8
Version: webpack 1.12.14
Time: 33ms
Asset Size Chunks Chunk Names
bundle.js 1.42 kB 0 [emitted] main
[0] ./entry.js 34 bytes {0} [built]
// création du bundle
bundle.js
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports) {
document.write("Ca fonctionne.");
/***/ }
/******/ ]);
$ vim entry.js
var monModule = require('./monModule');
var module1 = new monModule();
document.write(module1.bonjour());
document.write('<br>');
document.write(module1.auRevoir());
$ vim monModule.js
function monModule() {
this.bonjour = function() {
return 'bonjour!';
}
this.auRevoir = function() {
return 'au revoir!';
}
}
module.exports = monModule;
$ webpack ./entry.js bundle.js
// création du bundle
bonjour!
au revoir!
$ vim entry.js
// define integrera tout le code dans bundle.js sans faire de requete ajax
define(['./monModule'] , function (module1) {
document.write(module1.bonjour());
document.write('<br>');
document.write(module1.auRevoir());
});
$ vim monModule.js
define([], function() {
return {
bonjour: function() {
return 'bonjour';
},
auRevoir: function() {
return 'au revoir';
}
};
});
$ webpack ./entry.js bundle.js
// création du bundle
L'utilisation de define() générera un bundle.js complet.
L'utilisation de define() générera un bundle.js intégrant tous les modules
$ vim entry.js
require(['./monModule'] , function (module1) {
document.body.innerHTML += module1.bonjour();
document.body.innerHTML += '<br>';
document.body.innerHTML += module1.auRevoir();
});
$ webpack ./entry.js bundle.js
Hash: 3235bc0333357bac68a4
Version: webpack 1.12.14
Time: 43ms
Asset Size Chunks Chunk Names
bundle.js 3.91 kB 0 [emitted] main
1.bundle.js 540 bytes 1 [emitted]
[0] ./entry.js 192 bytes {0} [built]
[1] ./monModule.js 161 bytes {1} [built]
// création du bundle
L'utilisation de require() générera un bundle.js sans monModule.js et effectuera un chargement ajax pour charger ce dernier.
L'utilisation de require() générera un bundle.js sans monModule.js et effectuera un chargement ajax pour charger ce dernier
Afin de sauvegarder les paramètres et gagner du temps nous pouvons creer un fichier de configuration webpack.config.js
module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
}
};
$ vim webpack.config.js
Et ensuite lancer simplement la commande webpack:
$ webpack
Hash: cd6d42419beaf70c1a14
Version: webpack 1.12.14
Time: 42ms
Asset Size Chunks Chunk Names
bundle.js 1.81 kB 0 [emitted] main
[0] ./entry.js 167 bytes {0} [built]
[1] ./monModule.js 172 bytes {0} [built]
Dans un projet npm vous pouvez également configurer le paramètre start ou make afin de lancer webpack avec un npm start ou npm run make
Ou par exemple parametrer watch pour lancer le watch mode avec un npm run watch
Les loaders sont des transformations qui sont appliquées sur un fichier de ressources de votre application. Ils prennent une source en entrée et renvoient une nouvelle source modifiées.
Par exemple, il y a des loaders pour CoffeeScript ou JSX.
Les principales fonctionnalités des loaders sont:
Reprenons l'exemple précédent pour y ajouter un loader pour inclure du css:
$ npm install css-loader style-loader --save-dev
Nous devons d'abord installer les loaders css et style:
module.exports = {
entry: "./entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
}
};
Nous modifions ensuite webpack.config.js pour y ajouter notre loader:
$ vim webpack.config.js
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type="text/javascript" src="bundle.js" charset="utf-8"></script>
</body>
</html>
Le code source de index.html ne change pas:
require("./style.css");
var monModule = require('./monModule');
var module1 = new monModule();
document.write(module1.bonjour());
document.write('<br>');
document.write(module1.auRevoir());
Nous modifions ensuite entry.js pour y ajouter le require de notre style.css qui aura pour effet de l'inclure dans notre bundle en tant que module:
$ vim entry.js
On peut maintenant créer le bundle.js:
$ webpack
Le css est alors ajouté a l’intérieur de <head> par bundle.js:
/* 2 */
/***/ function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(3)();
exports.push([module.id, "body {\n background: blue;\n color: white;\n}\n", ""]);
/***/ },
Un module est généré et ajouté dans bundle.js:
De la même façon nous pouvons ajouter des fonts et des images avec url-loader. Il permet de traiter et copier nos assets dans le répertoire désiré.
$ npm install url-loader --save-dev
The url loader works like the file loader, but can return a Data Url if the file is smaller than a limit.
Rajoutons notre loader une limite pour que nos assets soit directement inclus en data:base64 en fonction de leurs tailles.
module.exports = {
entry: "./public/entry.js",
output: {
path: "./public/assets", // The output directory as absolute path (required)
publicPath: "/assets/", // specifies the public URL address of the output files when referenced in a browser
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" },
{ test: /\.(png|jpg|ttf)$/, loader: 'url-loader?limit=8192' }
]
}
};
Installons le packet npm:
$ vim webpack.config.js
@font-face {
font-family: "Roboto";
src: url('./Roboto-Black.ttf');
}
body {
background-image: url(./webpack_logo.png);
color: black;
}
.smile {
background-image: url(./smile.png);
width: 48px;
height: 48px;
display: block;
}
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type="text/javascript" src="./assets/bundle.js" charset="utf-8"></script>
<div>
<span class="smile"></span>
</div>
</body>
</html>
$ vim public/style.css
$ vim public/index.html
$ webpack --progress --colors --watch
L'option watch permet de reconstruire automatiquement après un changement du code source.
$ npm install webpack-dev-server -g
$ webpack-dev-server --progress --colors
webpack-dev-server permet la même chose mais en créant un mini serveur http en NodeJs .
http://localhost:8080/ ou http://localhost:8080/webpack-dev-server/
module.exports = {
entry: "./public/entry.js",
output: {
path: "./public/assets", // The output directory as absolute path (required)
publicPath: "/assets/", // specifies the public URL address of the output files when referenced in a browser
filename: "bundle.js"
},
devServer: {
contentBase: 'public'
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" },
{ test: /\.(png|jpg|ttf)$/, loader: 'url-loader?limit=8192' }
]
}
};
$ vim webpack.config.js
$ webpack-dev-server --hot --inline
Avec --hot --online comme parametre, les modules sont recharges a chaud:
Il faut egalement ajouter module.hot.accept() dans les modules