Webpack: Loader ve Plugin Kullanımları
Webpack giriş yazısında kurulum ve yapılandırma işlemlerine temel bir şekilde değinmiş ve bir örnekle de süreci pratiğe dökmeye çalışmıştık.
Bu yazıda ise kaldığımız yerden devam ederek, ilgili örneğin kapsamını biraz daha genişletecek, loader ve plugin kullanımıyla detaylandırmaya çalışacağım.
Webpack: Loader ve Plugin
Webpack’in temel çekirdek konseptler (core concepts) dahilinde yetenekler sunduğunu ve bu yeteneklerin geliştirilebildiğine daha önce değinmiştim. Bu konseptlerden ilk olarak loader
kullanımını örneğimize dahil edelim.
Loader
Webpack'in yapısal olarak JavaScript merkezinde hareket ettiğinden daha önce bahsetmiştim. Bu nedenle CSS (.css), SCSS (.scss) veya TS (.ts) gibi diğer kaynakların paketlenmesini istediğimizde webpack için harici derleme ve paketleme desteğine ihtiyaç duyarız. İş destek webpack için loader’lar ile sağlanır. Loader’lar webpack için belirtilen kaynakların compile ve/veya transform edilmesi işlemlerini yürüten ve bundle edilebilen node tabanlı (node-based) JavaScript modülleridirler. Diğer yandan, Vue yazı dizisine de atfen, Vue loader ile vue single-page component’leri (*.vue
) de farklı loader yapılandırmaları ile ele almak mümkündür1.
Plugin’ler webpack için belkemiği (backbone) olarak ifade edilmektedirler ve webpack’in kendisi de webpack yapılandırmalarında kullanılan eklenti sistemi üzerine kuruludur. Loader’ların eksik kaldığı, müdahale edemediği her türlü durum için destek özelliği gösterirler. Dolayısıyla loader ve plugin kullanımı birbirini tamamlayan webpack özellikleridirler. Plugin tanımamaları da yine loader’lar gibi webpack.config.js
içeriğinde gerçekleştirilir. Plugin’ler (eklentiler) argümanlar / opsiyonlar (arguments / options) alırlar2. Elbette bu işlemler yeni instance ile tanımlanır. Örnek olarak aşağıda bir eklenti tanımı iletitorum.
const HtmlWebpackPlugin = require('html-webpack-plugin'); // npm veya yarn ile indirilir
const webpack = require('webpack'); // ön tanımlı (built-in) eklentilere erişim sağlar
const path = require('path');
module.exports = {
module: {
rules: [
{
... // loader tanımları
}
]
},
plugins: [
new webpack.ProgressPlugin(), // ön tanımlı (built-in) eklenti
new HtmlWebpackPlugin({template: './src/index.html'}) // HtmlWebpackPlugin ile eriştiğimiz html-webpack-plugin eklentisi ayarları
]
};
Proje Yapılandırması
Kısa tanımların ardından, bir önceki yazıda geliştirmeye başladığımız örnek projemize loader ve plugin ekleyerek teorik bilgileri pratiğe dönüştürelim.
Dosya ve klasör yapımız son durumda (node modülleri; node_modules hariç) şu şekildeydi.
.
├── dist
│ ├── bundle.js
│ ├── css
│ ├── img
│ ├── js
│ └── view
├── package-lock.json
├── package.json
├── src
│ ├── css
│ ├── img
│ ├── index.js
│ ├── js
│ │ ├── bar.js
│ │ └── foo.js
│ └── layout
├── webpack.config.js
└── yarn.lock
10 directories, 8 files
Örnek işlemler için Bulma CSS framework ile ilerleyeceğim. İşleme alacağımız yeni klasörler ve dosyalarımızı oluşturalım. Son durumda proje içeriğimiz şöyle olsun:
.
├── dist
│ ├── bundle.js
│ ├── css
│ │ └── main.bundle.css
│ ├── img
│ ├── index.html
│ └── js
├── index.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── src
│ ├── img
│ │ └── logo.png
│ ├── index.js
│ ├── js
│ │ ├── bar.js
│ │ ├── foo.js
│ │ └── main.jsx
│ ├── layouts
│ │ ├── header.pug
│ │ ├── main.pug
│ │ └── top.pug
│ ├── sass
│ │ └── style.scss
│ └── templates
│ └── index.html
├── webpack.config.js
└── yarn.lock
10 directories, 19 files
git clone git@gitlab.com:ceaksan/webpack-test.git
yarn install
# ya da
npm install
Kısa tanımların ardından, bir önceki yazıda geliştirmeye başladığımız örnek projemize bir loader ekleyerek teorik bilgileri pratiğe dönüştürelim.
npm install bulma html-webpack-plugin mini-css-extract-plugin node-sass webpack webpack-cli --save-dev
Şimdi, ilgili loader’ları sırayla indirebiliriz.
npm install css-loader html-loader postcss-loader sass-loader style-loader babel-loader --save-dev
ELbette plugin ve loader indirme işlemlerinin yanı sıra bazı bağımlılıkların da yapılandırılması ve package.json
dosyasına eklenmesi gerekmekte:
{
"name": "webpack-test",
"version": "1.0.0",
"description": "webpack-test-example",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "webpack --mode development ./src/index.js",
"build": "webpack --mode production ./src/index.js",
"start": "webpack-dev-server --mode development --open"
},
"repository": {
"type": "git",
"url": "git://gitlab.com/ceaksan/webpack-test.git",
"private": false
},
"dependencies": {
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.6",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"bulma": "^0.7.5",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^5.0.3",
"css-loader": "^3.0.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.7.0",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"react": "^16.0.0",
"react-dom": "^16.8.6",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"webpack": "^4.34.0",
"webpack-dev-server": "^3.7.1"
},
"devDependencies": {
"webpack-cli": "^3.3.4"
}
}
Bir sonraki aşamada webpack.config.js
dosyasının loader ve plugin’ler için düzenlenmesi gerekiyor.
const path = require("path")
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.join(__dirname, "dist"),
publicPath: 'http://localhost:8080'
},
devServer: {
contentBase: "./dist"
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].bundle.css',
template: './src/css/style.css',
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/templates/index.html',
}),
],
module: {
rules: [{
test: /\.(js|jsx|mjs)$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: {
presets: ["@babel/preset-env", "@babel/react"]
}
}],
},
{
test: /\.s?[ac]ss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: false,
sourceMap: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
config: {
path: 'postcss.config.js'
}
}
}
]
},
{
test: /\.html$/,
use: ['html-loader'],
}
],
},
mode: "development"
}
Bu kurulumların ve yapılandırmaların ardından src
klasörü içeriğindeki dosyalar dist
içeriğine yapılandırılarak aktarılacaklardır. loader
kullanımında, loader ilgili dosyanın okunmasını sağlarken plugin’ler ile projenin yapılandırılması sağlanır.
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
Ek olarak, bağımlılıklar için ayrıca konfigürasyon dosyalarının da düzenlenmesi gerekmekte. .babelrc
ve postcss.config.js
dosyaları bu proje örneği için gerekli olan yapılandırmaları içermektedir. postcss.config.js
içeriği şu şekildedir:
module.exports = {};
.babelrc
içeriği ise şöyle:
{
"presets": [
"@babel/preset-env", "@babel/react"
]
}
Bu örnek sürecinde, ayrıca main.jsx
dosyası üzerinden react dom
ile index.html
dosyasına şu eklemeyi yapabiliriz.
import React from "react";
import ReactDOM from "react-dom";
function tick() {
const element = <strong>It is {new Date().toLocaleTimeString()}.</strong>;
ReactDOM.render(element, document.getElementById("impl"));
}
setInterval(tick, 1000);
Örnek ile ilgili diğer tüm işlemler ve kod incelemeleri için GitLab reposu incelenebilir. Ayrıca aşağıda örnek ile ilişkili olarak bazı ek yazılar ve örnekler iletiyorum.
Örnekler
İleri Okumalar
- Webpack Loaders, CSS and Style Loaders
- Webpack / Loaders
- Bulma with webpack
- Setup New Vue Webpack Project With Bulma
- How to combine Webpack 4 and Babel 7 to create a fantastic React app
- A Beginner’s Guide to Webpack 4 and Module Bundling
- Tutorial: How to set up React, webpack, and Babel 7 from scratch (2019)
- Webpack 4 Tutorial: from 0 Conf to Production Mode
- Separating CSS
- Using Babel and Webpack
- Webpack 4: Extract CSS from Javascript files with mini-css-extract-plugin
- React + Webpack 4 + Babel 7 Setup Tutorial