> mkdir projet && cd projet
> npm init
> npm i webpack --save-dev
> mkdir app
> touch webpack.config.js
module.exports = {
context: __dirname + '/app',
entry: './index.js',
output: {
path: __dirname + '/app',
filename: 'bundle.js'
}
}
> touch app/index.js
alert('Oh yeah !')
Note : npm_exec est un alias vers ./node_modules/.bin
> npm_exec webpack
- Oh magie, regardez dans app ... un zouli bundle.js
> npm_exec webpack --watch
- Modifiez index.js
> touch app/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack</title>
</head>
<body>
<h1>Webpack !</h1>
<script src="bundle.js"></script>
</body>
</html>
> npm i webpack-dev-server --save-dev
- Modification de package.json
...
"scripts": {
"start": "webpack-dev-server --content-base app"
},
...
npm start
- Ouvrez un navigateur http://localhost:8080
- Et pouf joie !
- Note en passant : vous pouvez supprimer le fichier bundle.js (le dev server le regenère et le sert depuis la mémoire)
> npm i angular --save-dev
- Modifiez index.html
...
<body ng-app="app">
...
- et index.js
var angular = require('angular')
var ngModule = angular.module('app', [])
ngModule.run(function () {
console.log('Angular !')
})
- Et paf ça marche !
mkdir app/directives
touch app/directives/index.js
touch app/directives/poly-hello.js
touch app/directives/poly-hello.html
module.exports = function (ngModule) {
require('./poly-hello')(ngModule)
}
module.exports = function (ngModule) {
ngModule.directive('polyHello', function () {
return {
restrict: 'E',
scope: {},
templateUrl: 'directives/poly-hello.html',
controllerAs: 'vm',
controller: function () {
var vm = this
vm.name = 'Polypodes'
}
}
})
}
<h1 class="poly-hello">Hello {{ vm.name }}</h1>
- Et on modifie app/index.js et index.html
var angular = require('angular')
var ngModule = angular.module('app', [])
require('./directives')(ngModule)
...
<body ng-app="app">
<poly-hello></poly-hello>
<script src="bundle.js"></script>
</body>
...
- Et paf une directive !
- On modifie la directive (poly-hello.js)
// templateUrl: 'directives/poly-hello.html',
template: require('./poly-hello.html')
- Et bim ça marche plus :(
- On a besoin d'un loader
npm i raw-loader --save-dev
- Modification de webpack.config.js
module.exports = {
context: __dirname + '/app',
entry: './index.js',
output: {
path: __dirname + '/app',
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.html$/, loader: 'raw', exclude: /node_modules/ }
]
}
}
- On va avoir besoin de 2 loaders : style et css
npm i css-loader style-loader --save-dev
- style : ajoute le style dans le dom
- css : chargement des fichiers css
- Qu'on va s'empresser d'utiliser dans webpack.config.js
...
module: {
loaders: [
{ test: /\.html$/, loader: 'raw', exclude: /node_modules/ },
{ test: /\.css$/, loader: 'style!css', exclude: /node_modules/ }
]
}
...
- On crée un fichier poly-hello.css
- touch app/directives/poly-hello.css
.poly-hello { color: pink }
- Et un require suffit (on le fait dans poly-hello.js)
require('./poly-hello.css')
...
- Oh c'est rose !
> npm i babel-loader --save-dev
- Et devinez-quoi ? On va l'utiliser dans webpack.config.js
...
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/ }
...
- Et vazi les const et let et arrow function de bôgoss
const angular = require('angular') // regarde maman ... une constante
const ngModule = angular.module('app', [])
require('./directives')(ngModule)
- Tout d'abord une fonte
- Chargée dans poly-hello.css
- À toi de récupérer le .ttf ici http://openfontlibrary.org/en/font/dashley et de le copier au bon endroit (c'est à dire dans app/directives)
@font-face {
font-family: Dashley;
src: url(./Dashley.ttf);
}
.poly-hello {
font-family: Dashley;
color: pink;
}
- Un nouveau loader
> npm i file-loader --save-dev
- Et on modifie webpack.config.json (ça commence à être routinier, non ?)
{ test: /\.ttf$|\.otf$/, loader: "file" }
- T'as vu comme ça claque ?
- Et maintenant une image
- Imaginons que l'on ait une image polypode.jpg dans /app/directives/ et que l'on s'en serve dans le template poly-hello.html
<h1 class="poly-hello">
Hello {{ vm.name }}
<img src="polypode.jpg" alt="polypode">
</h1>
- Il faut ajouter l'extension de l'image (jpg) pour le loader file
{ test: /\.ttf$|\.otf$|\.jpg$/, loader: "file" }
- Mais ça marche pas ?
- Il nous faut un autre loader pour le html !
> npm i html-loader --save-dev
- Et remplacer raw par html dans webpack.config.js
...
{ test: /\.html$/, loader: 'html', exclude: /node_modules/ },
...
- Et banco !
- On va utiliser la variable d'environnement NODE_ENV
- Et changer le chemin de sortie lorsque cette variable est à "production"
var config = {
context: __dirname + '/app',
entry: './index.js',
output: {
path: __dirname + '/app',
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/ },
{ test: /\.html$/, loader: 'html', exclude: /node_modules/ },
{ test: /\.css$/, loader: 'style!css', exclude: /node_modules/ },
{ test: /\.ttf$|\.otf$|\.jpg$/, loader: "file" }
]
}
}
if (process.env.NODE_ENV === 'production') {
config.output.path = __dirname + '/dist'
}
module.exports = config
- Il suffit alors de lancer webpack en mode production et de copier index.html
> NODE_ENV=production ./node_modules/.bin/webpack && cp app/index.html dist/index.html
- Et tant qu'à faire mettre ça dans package.json
...
"scripts": {
"start": "webpack-dev-server --content-base app",
"build": "NODE_ENV=production ./node_modules/.bin/webpack && cp app/index.html dist/index.html"
},
...
> npm run build
> lrhs --dir dist/
- Note : lrhs (lr-http-server) ne sert qu'à tester, n'importe quel serveur web fait l'affaire
- Ben il suffit de rajouter "-p" comme option de webpack lors du build
- Oui mais angular, il aime pas la minification avec l'injection ..
- Par exemple : si on modifie notre directive
controller: function ($timeout) {
var vm = this
vm.name = 'Polypodes'
$timeout(function () {
vm.name = 'ByteClub'
}, 1000)
}
- Après le builde (qui compresse) ça marche plus
- Vite un nouveau loader
> npm i ng-annotate-loader --save-dev
- Et on remplace le loader de js pour la conf de production
if (process.env.NODE_ENV === 'production') {
config.output.path = __dirname + '/dist'
config.module.loaders[0] = { test: /\.js$/, loader: 'ng-annotate!babel', exclude: /node_modules/ }
}
- Et ça remarche !
- Un exemple : i18n
Thanks a lot for this. If you could add SCSS and image loaders in this setup too, it would be great - may be that's what is next :)
Once again thank you very much for this awesome Webpack-Angular compilation!