Webpack 4 kullanımı — Bölüm 1
Bu yazımda webpack modül paketleyicisinin kullanımı ve özelliklerinden bahsedeceğim.
Webpack hakkında bilgi sahibi olmak isteyenler buradan önceki yazıma ulaşabilir.
Temel Kavramlar;
Entry
Hangi modül paketinden okuma yapacağımızı belirtiriz. Yani projede giriş noktası adı verilen root dosyasını ister. Bu dosyayı belirttiğimizde ilk olarak dosya okuma işlemi yapar. Ayrıca tek bir dosyaya bağlı olmayan paketleme işlemlerinde ise birden fazla giriş noktası ile çalışabilmektedir.
Tekli giriş noktası tanımlama:
module.exports = {
entry: './file.js'
};
bu örnekte file.js dosyasında içerisinde çalışan bileşenleri bir araya getirip paketleme işlemi yapılır.
Çoklu giriş noktası tanımlama:
module.exports = {
//...
entry: {
home: './home.js',
about: './about.js',
contact: './contact.js'
}
};
bu örnekte ise birden fazla entry başlıklarında çalışan bileşenleri bir araya getirip paketleme işlemi yapılır.
Output
Bu özellik Entry ile belirttiğimiz dosyaların çıkış noktasını tanımlamıza olanak sağlar. Yani paketlenen dosyanın nereye çıktı vereceğini ve hangi isimlerde verileceği gibi ayarlamaları yapmaktayız.
Varsayılan olarak çıktı dosyası ./dist/main.js
ve klasör olarak da ./dist
dosyasını kullanır.
Ayrıca tek bir dosyaya bağlı olmayan paketleme işlemlerinde ise birden fazla çıkış noktası ile çalışabilmektedir.(Bunun için birden fazla entry tanımlası gerekmektedir)
Tekli çıkış noktası tanımlama:
module.exports = {
entry: './file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'file.bundle.js'
}
};
bu örnekte file.js dosyasında içerisinde çalışan bileşenleri bir araya getirip paketleme işlemi yapıldıktan sonra dist klasörüne file.bundle.js dosyası çıkarılacaktır.
Çoklu giriş noktası tanımlama:
module.exports = {
entry: {
home: "./src/home.js",
about: "./src/about.js"
},
output: {
path: path.join(__dirname, "dist"),
filename: "[name].js"
}
};
bu örnekte ise entry noktası home ve about olan objeleri output kısmında “[name]” ile obje keyleri ile derlenip çıktısını path ile tanımlanan dist klasörü altına çıkarılacaktır.
Örnek dosyalama sistemi ve çıktı sonucu:
Örnek repoya buradan ulaşabilirsiniz.
Loaders
Webpack aslında JavaScript ve JSON dosyaları ile işlem yapar. Bu dosyaları derleme sonucunda üretip bize istediğimiz çıktıları verir ve aslında biz tüm paketleme türlerini veya farklı dosyaları anlamasını istediğimiz durumlarda webpack den yardım alırız. Loaders’lar ise burada aslında farklı dosya türlerinin anlaşılır JSON veya JavaScript dosyalarına paketleme işleminde önemli rol oynamaktadır.
Örnek vermek gerekirse loaders’ların ana görevi CSS’de ile yazdığımız kodları JS dosyaları içerisine ekleyip kullanabilme imkanı sunar. Veya JSX ile yazdığımız React kodlarını yine client’ın anlayacağı JS dosyasına dönüştürmektir.
İlerleyen zamanlarda bu ve benzeri örnekleri hem yazı hemde repo halinde sunmaya çalışacağım.
CSS Loader örneklemesi:
İlk olarak css loaders paketimizi kurmamız gerekmektedir.
Reposu: https://github.com/webpack-contrib/css-loader
npm install --save-dev css-loader style-loader
veya
yarn add css-loader style-loader
Kurulumdan sonra proje içerisinde kullanabilmek için webpack.config.js dosyası içerisinde ayarlamaları yapmamız gerekmektedir.
webpack.config.js
const path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
path: path.join(__dirname, "dist"),
filename: "index.js",
},
module: {
rules: [
/*
test: ile css uzantısını tanımasını sağladık
use: ile hangi loader'ların kullanılacağını belirttik
*/
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
}
};
yukarıda yapılan ayarlamalarımızda css-loader ve style-loader’ları kullandık.
css-loader: css dosyalarını anlayıp çözümleyebilmek için kullanılır
style-loader: dom içine css-loader ile çözümlenen css dosyalarını ekler
NOT: use kısmında kullanılan style ve css loader’ların sıralaması çok önemlidir. Aslında buradaki sıralama loader kuralları gereği ters çalışmaktadır. Yani önce css-loader çalışmaktadır. Bunun sebebi ise önce css-loader ile css dosyaları çözümlenir daha sonra bu çözümlenen dosyalar style-loader ile dom içine enjekte edilir. Sıralama kuralı tüm loader’lar için geçerlidir css ile ilgili değildir.
İlerleyen zamanlarda daha fazla loaders örneklerini paylaşmaya çalışacağım.
Çıktı:
Örnek repoya buradan ulaşabilirsiniz.
Plugins
Loaders’lar belirli modül tiplerini dönüştürmek için kullanılırken, paketlerin optimizasyonu ve ortam değişkenleri gibi değerleri projeye enjekte ederken kullanabileceğimiz görevleri yönetmek içinde Plugins’lere ihtiyaç duyarız.
Örnek vermek gerekirse paketlediğimiz css ve js dosyalarını html template yapısında bir araya getirip kullanabiliriz veya birden fazla çıkış noktası tanımladığımız dosyalarımızı birden fazla html template yapısında inject edebiliriz.
Html Webpack Plugin örneklemesi:
İlk olarak html webpack plugin paketimizi kurmamız gerekmektedir.
Reposu: https://github.com/jantimon/html-webpack-plugin
npm install --save-dev html-webpack-plugin
veya
yarn add html-webpack-plugin
Kurulumdan sonra proje içerisinde kullanabilmek için webpack.config.js dosyası içerisinde ayarlamaları yapmamız gerekmektedir.
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
path: path.join(__dirname, "dist"),
filename: "index.js",
},
module: {
rules: [
/*
aşağıda kurallara css-loader'ımızı ekledik
test: ile css uzantısını tanımasını sağladık
use: ile hangi loader'ların kullanılacağını belirttik
*/
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: "new-index.html",
template: "index.html"
})
]
};
plugin özelliklerine filename ve template değerleri yerleştirildi (boş bırakılsaydı boş bir index.html dosyası /dist altına oluşturup içerisine output kısmında tanımlanan index.js dosyasını enjekte edecekti)
filename: oluşturulacak olan dosyanın adını tanımlamak için kullanılır
template: orjinal hangi template ile çalışılacak ise o dosyayı tanımlamamızı ister
yani template içerisinde yazılan index.html dosyamızı alıp adını
new-index.html olarak değiştirdikten sonra /dist altına kopyalayacaktır
bu işlemlerle beraber paketlediğimiz dosyalarda içerisine enjekte edilmektedir.
Çıktı:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack Example - Html Webpack Pluging</title>
</head>
<body>
<h1>Derleme işlemi başarılı</h1>
</body>
</html>
new-index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack Example - Html Webpack Pluging</title>
</head>
<body>
<h1>Derleme işlemi başarılı</h1>
<script type="text/javascript" src="index.js"></script></body>
</html>
Örnek repoya buradan ulaşabilirsiniz.
Mode
Mode yapılandırma seçeneklerinin sağlanması ve paketleme optimizasyonlarını uygun şekilde kullanmaya olanak sağlar.
3 çeşit mode vardır bunlar;
development
production
none
Yapılandırma ayarlanı package.json dosyasından ayarlamamızda mümkün.
"scripts": {
"dev": "webpack --mode=development --config webpack.config.js",
"build": "webpack --mode=production --config webpack.config.js"
}
burada bulanan ayarları terminalde npm run dev veya yarn dev komutunu ile development mode’da kullanmamıza imkan sunar. Aynı şekilde production mode’da kullanmak içinde npm run build veya yarn build yazmak yeterli olacaktır.
webpack.config.js
module.exports = {
mode: "development|production|none",
//...
}
yukarıda yaptığımız işlemde ise eğer package.json içerisinde scripts tag’leri arasında yazılmadığı durumlar var ise burada yazılan mode aktif olur.
NOT: scripts tag’leri ve webpack.config.js içerisinde aynı anda mode değeri kullanılırsa scripts içerisinde yazılan mode değeri baz alınır.
development: bu mode ile birlikte NamedChunksPlugin
ve NamedModulesPlugin
eklentileri çalışmaktadır.
production: bu mode ile birlikte FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin, UglifyJsPlugin
eklentileri çalışmaktadır.
none: varsayılan tüm optimizasyon seçeneklerini kullanmadan sonuç üretir
Browser Compatibility
Tarayıcı uyumluluğu en önemli konulardan biri peki webpack derlenen bu paketlerde tarayıcılara uyumluluğu nasıl sağlar ?
Webpack aslında ES5 standartlarına uyumlu tüm tarayıcıları destekler.(IE8 ve altı desteklenmez). Yani IE8 altında olan tarayıcılar hariç neredeyse tüm tarayıcıları destekler.
Paketlenen kodların eski tarayıcılarda desteklenmesini istiyorsanız Shimming yöntemlerinden Pollyfills kullanımınına bakmanızı tavsiye ederim. (babel-preset-env
, babel-polyfill
, babel-loader
)
ÖNEMLİ: webpack ile çalışabilmek için NodeJS 8 ve üzeri bir versiyonun kurulu olması gerekmektedir
Proje ve örneklerde kullanılan sürümler:
NodeJS: 13.0.2, npm: 6.13.1, yarn: 1.19.1, webpack: 4.41.2
webpack-cli: 3.3.10, css-loader: 3.4.0, style-loader: 1.1.2
html-webpack-plugin: 3.2.0