درس ششم: آشنایی با پلاگین‌های webpack

Familiarity with Webpack Plugins

23 شهریور 1399
درسنامه درس 6 از سری آموزش Webpack
02-Webpack-4-The-Complete-Tutorial-For-Beginners-lesson6

در جلسه قبل به طور مفصل در مورد SASS و Babel صحبت کردیم و در انتهای جلسه برای فعال سازی قابلیت class properties از یک پلاگین babel به نام transform-class-properties استفاده نمودیم. حالا باید با مفهوم plugin ها در webpack آشنا شویم. پلاگین ها کتابخانه های جاوا اسکریپتی هستند که کارایی بیشتری نسبت به loader ها به ما می دهند. معمولا loader ها برای import کردن فایل های جدید به کار می روند اما اگر بخواهیم با فایل های import شده کار خاصی انجام بدهیم (به عنوان مثال در جلسه قبل می خواستیم از class properties استفاده کنیم) باید پلاگین مورد نظر آن را وارد کنیم. پلاگین ها گستره وسیعی دارند و می توانند کارهای مختلفی انجام بدهند؛ مثلا می توانند bundle نهایی ما را ویرایش کنند. یکی از این پلاگین ها uglifyJSPlugin است که کدهای ما را minify می کند تا حجم فایل کاهش پیدا کند. من برای این جلسه از پلاگینی به نام terset استفاده خواهم کرد.

همانطور که می دانید شاید تغییر سایز فایل جاوا اسکریپت ما از 40 کیلوبایت به 80 کیلوبایت تفاوت آنچنانی ایجاد نکند اما همین موارد ریز هستند که روی هم جمع شده و نهایتا سرعت بارگذاری سایت ما را تعیین می کنند. همچنین در دستگاه های کوچک تر مانند تلفن های هوشمند، کاهش سایز فایل ها (حتی در حد 20 کیلوبایت) می تواند تاثیر بسزایی در سرعت بارگذاری سایت شما داشته باشد چرا که دستگاه های تلفن همراه معمولا قدرت پردازشی کمتری دارند. در حال حاضر bundle.js من که در پوشه dist قرار دارد، حدود 21 کیلوبایت حجم دارد. بعد از استفاده از terset به این فایل برمی گردیم تا حجم آن را بررسی کنیم.

برای شروع به فایل Webpack.config.js بروید و قسمت جدیدی به نام plugins را در آن تعریف کنید:

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');


module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, './dist'),
        publicPath: 'dist/'
    },
    mode: 'none',
    module: {
        rules: [
            {
                test: /\.(png|jpg)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name][contenthash:5].[ext]'
                        }
                    }
                ]
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader', 'css-loader'
                ]
            },
            {
                test: /\.scss$/,
                use: [
                    'style-loader', 'css-loader', 'sass-loader'
                ]
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/env'],
                        plugins: ['transform-class-properties']
                    }
                }
            }
        ]
    },
    plugins: [
        
    ]
}

همانطور که می بینید plugins را بعد از module اضافه کرده ام. شما می توانید هر تعداد پلاگینی که خواستید را در این قسمت اضافه کنید. همچنین حتما متوجه شده اید که پلاگین terser را با require وارد این فایل کرده ام (بالای فایل و پس از وارد کردن ماژول path). حالا می توانیم پلاگین terser را در قسمت plugins بیاوریم:

    plugins: [
        new TerserPlugin()
    ]

توجه کنید که من یک نمونه از کلاس terserPlugin را ساخته ام. مشکل اینجاست که این پلاگین را هنوز نصب نکرده ایم بنابراین در یک صفحه ترمینال دستور زیر را اجرا کنید تا نصب شود:

npm install terser-webpack-plugin --save-dev

تمام پلاگین های webpack باید به صورت --save-dev نصب شوند چرا که فقط هنگام توسعه به درد ما می خورند. حالا دستور npm run build را دوباره اجرا کنید تا فایل bundle.js دوباره ساخته شود. حالا اگر به پوشه dist بروید و فایل bundle.js را بررسی کنید، سایز آن از 21 کیلوبایت به 7 کیلوبایت تبدیل شده است!

استخراج کدهای CSS درون یک فایل جداگانه

تا این قسمت از کار باید متوجه کلیت پلاگین ها شده باشید بنابراین برای تمرین بیشتر به سراغ پلاگین دیگری می رویم. در حال حاضر اگر برنامه خودمان را در مرورگر را باز کنید و کلید f12 را بزنید تا به قسمت dev tools مرورگر بروید، شاهد صحنه جالبی خواهید بود. کدهای CSS ما همگی درون فایل HTML و درون یک تگ style قرار گرفته اند!

استایل های ما درون خود فایل html قرار گرفته اند
استایل های ما درون خود فایل html قرار گرفته اند

همانطور که می دانید این روش برای حالت توسعه (هنگام کدنویسی) مشکل ساز نیست اما در هنگام production نباید از این حالت استفاده کنیم. ما استایل های برنامه را درون فایل های جاوا اسکریپتی خود نوشته ایم بنابراین کدهای CSS ما توسط جاوا اسکریپت و در run time به فایل HTML تزریق می شوند! تصور کنید یک پروژه بزرگ داشته باشیم که هزاران خط کد CSS داشته باشد! تزریق این کدها توسط جاوا اسکرپیت زمان زیادی خواهد برد. همچنین حجم فایل bundle.js ما بسیار زیاد خواهد شد. از طرفی متخصصان سئو نیز می گویند که این روش اصلا توصیه نمی شود.

به دلایلی که ذکر کردم بهتر است راه جدیدی برای اعمال استایل های خود پیدا کنیم. خوشبختانه پلاگینی وجود دارد که می تواند به جای تزریق کدهای CSS ما به فایل HTML، آن ها را در یک فایل CSS نهایی ادغام کند تا به صورت عادی و با یک تگ link آن را به صفحه HTML متصل کنیم. نام این پلاگین miniCSSExtractor است. همانطور که می دانید باید وارد فایل webpack.config.js بشویم تا از این پلاگین استفاده کنیم:

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

همانطور که می بینید در ابتدا باید این پلاگین را وارد این فایل کنیم. سپس باید یک نمونه از آن را در قسمت plugins بسازیم:

    plugins: [
        new TerserPlugin(),
        new MiniCssExtractPlugin({
            filename: 'styles.css'
        })
    ]

آرگومانی که به کلاس MiniCssExtractPlugin پاس داده ام filename است که نام فایل ما را مشخص خواهد کرد. شاید فکر کنید که کار ما تمام شده است اما خیر! اگر یادتان باشد ما برای فایل های CSS یک rule جداگانه نوشته بودیم و حالا با اضافه شدن این پلاگین باید آن را ویرایش کنیم:

            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader, 'css-loader'
                ]
            }

در واقع به جای style-loader از MiniCssExtractPlugin.loader استفاده کرده ام که loader مخصوص پلاگین MiniCssExtract را اجرا می کند. همین کار را برای scss نیز انجام می دهیم:

             {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader, 'css-loader'
                ]
            },
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'
                ]
            }

در نهایت هم خود پلاگین را با دستور زیر نصب می کنیم:

npm install mini-css-extract-plugin --save-dev

حالا npm run build را اجرا کنید و سپس به پوشه dist توجه کنید. همانطور که می بینید فایل جدیدی به نام style.css به این پوشه اضافه شده است بنابراین باید آن را وارد index.html کنیم:

<head>
    <meta charset="UTF-8">
    <title>Hello World</title>
    <link rel="stylesheet" href="./dist/styles.css">
</head>

حالا اگر به مرورگر بروید، برنامه ما بدون مشکل باز می شود. همچنین دیگر استایل ها درون تگ style نیستند و شکل مناسبی گرفته اند.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش Webpack توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.