درس پنجم: کار با SASS و Babel

Working With SASS and Babel

22 شهریور 1399
درسنامه درس 5 از سری آموزش Webpack
02-Webpack-4-The-Complete-Tutorial-For-Beginners-lesson5

در جلسه قبل در مورد کارایی webpack در ادغام کدهای CSS صحبت کردیم اما اگر شما از SASS یا LESS برای استایل دهی استفاده می کنید، مشکلی وجود ندارد. من در این جلسه نحوه کار با SASS را برایتان توضیح می دهم اما شما می توانید با هر پیش پردازنده CSS دیگری مثل LESS نیز کار کنید. در ابتدا به فایل hello-world-button.css بروید و نام آن را به hello-world-button.scss تغییر دهید (فرمت به scss تغییر پیدا کرد). حالا وارد استایل ها شده و چند متغیر تعریف می کنیم و از آن ها استفاده می کنیم:

$font-size: 20px;
$button-background-color: green;
$button-font-color: white;
$text-font-color: red;

.hello-world-button {
    font-size: $font-size;
    padding: 7px 15px;
    background: $button-background-color;
    color: $button-font-color;
    outline: none;
}

.hello-world-text {
    color: $text-font-color;
    font-weight: bold;
}

من کدهای CSS خودم را بدین صورت نوشته ام و در آن ها از SASS  استفاده کرده ام. اگر با SASS آشنایی ندارید به صورت خلاصه برایتان می گویم که یک پیش پردازنده CSS است و قابلیت های بیشتری (مانند متغیرها) را به CSS اضافه می کند تا نوشتن استایل ها راحت تر باشد. پس از ذخیره استایل های بالا به فایل hello-world-button.js رفته و دستور import را نیز تصحیح کنید (دیگر پسوند فایل css نیست):

import './hello-world-button.scss';

حالا به فایل webpack.config.js می رویم و یک rule جدید برای SASS می سازیم:

    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'
                ]
            }
        ]
    }

توجه داشته باشید که ترتیب استفاده از loader ها از راست به چپ است بنابراین webpack ابتدا sass-loader را اجرا می کند تا کدهای sass را درک و کامپایل کند. سپس css-loader را اجرا می کند تا کدهای کامپایل شده CSS را بخواند و نهایتا Style-loader را اجرا می کند تا کدهای CSS خوانده شده را وارد صفحه کند. ما هنوز sass-loader را نداریم بنابراین با استفاده از دستور زیر آن را نصب می کنیم:

npm install sass-loader node-sass --save

سپس فایل ها را ذخیره کرده و دستور زیر را اجرا کنید تا webpack دوباره اجرا شود:

npm run build

حالا باید برنامه بدون خطا در مروگر باز شود.

استفاده از Babel

احتمالا با خودتان می گویید که مگر ما قبلا نگفتیم برای استفاده از فایل های جاوا اسکریپت در Webpack نیاز به کار خاصی نیست؟ مگر نگفتیم که webpack از ابتدا برای جاوا اسکریپت ساخته شده است؟ حرفتان درست است! اگر یادتان باشد ما فایل hello-world-button.js را در جلسات قبل درون فایل index.js وارد کردیم:

import HelloWorldButton from './components/hello-world-button/hello-world-button.js';

اما این ها فایل های عادی جاوا اسکریپت هستند و من می خواهم از یک ابزار خاص به نام babel استفاده کنم، بنابراین نیاز به انجام کار های بیشتری داریم. سوال اول اینجاست که Babel چیست؟ Babel یک ترسنپایلر (transpiler) است که کدهای جدید جاوا اسکریپت جدید را به کدهای قدیمی تبدیل می کند! احتمالا با خودتان بگویید چرا باید چنین کاری انجام بدهیم؟

همانطور که می دانید زبان جاوا اسکریپت به صورت مرتب به روز رسانی می شود و به روز رسانی های جدید تا مدتی طولانی در مرورگرها پیاده سازی نمی شوند. بعد از آنکه این قابلیت ها در مرورگرها پیاده سازی شدند باید تا مدت زیادی منتظر بمانیم که این قابلیت ها به دست همه مردم برسد. اکثر مردم مرورگرهای خود را دیر به دیر آپدیت می کنند (شاید حتی شش ماه یک بار یا هر سال یک بار) بنابراین اگر از این قابلیت های جدید استفاده کنیم، باعث بروز مشکل در مرورگرهای کاربر و از دست دادن کاربران سایت می شویم.

از طرفی نوشتن کدهای قدیمی جاوا اسکریپت کار بسیار سختی است اما کدهای جدید بسیار خلاصه تر و راحت تر هستند، بنابراین با استفاده از Babel می توانیم کار خود را به عنوان توسعه دهنده راحت کنیم چرا که از قابلیت های جدید جاوا اسکریپت استفاده می کنیم و نیازی به نگرانی نخواهیم داشت. از طرف دیگر مشکل کاربران نیز حل می شود چرا که کدهای جدید به کدهای قدیمی تبدیل می شوند و در همه مرورگرها پشتیبانی خواهند شد.

نکته: با معرفی تایپ اسکریپت (typescript) استفاده از babel توجیهی ندارد چرا که تایپ اسکریپت بسیار بهتر و قوی تر از babel است. پیشنهاد بنده این است که حتما از تایپ اسکریپت استفاده کنید اما برای کسانی که به دلایلی می خواهند از Babel استفاده کنند این آموزش را قرار می دهم. آموزش استفاده از تایپ اسکریپت در webpack نیز در دوره جامع آن توضیح داده خواهد شد.

برای شروع به کار به فایل hello-world-button.js بروید. ما در این کد کلاس CSS دکمه را به صورت دستی نوشته ایم اما بهتر است آن را به شکل زیر تغییر دهیم:

import './hello-world-button.scss';

class HelloWorldButton {
    buttonCssClass = 'hello-world-button';

    render() {
        const button = document.createElement('button');
        const body = document.querySelector('body');
        button.innerHTML = 'Hello world';
        button.onclick = function () {
            const p = document.createElement('p');
            p.innerHTML = 'Hello world';
            p.classList.add('hello-world-text');
            body.appendChild(p);
        }
        button.classList.add(this.buttonCssClass);
        body.appendChild(button);
    }
}

export default HelloWorldButton;

یعنی کلاس را در خصوصیتی به نام buttonCssClass قرار داده ایم و سپس به جای نام کلاس از این خصوصیت استفاده کرده ایم. مشکل اینجاست که اگر دستور npm run build را اجرا کنیم webpack به ما خطا خواهد داد. چرا؟ به دلیل اینکه نوشتن خصوصیات (property) درون کلاس ها به شکل بالا در اکثر مرورگرها پشتیبانی نمی شود و جزئی از ECMA Script نیستند. خطای webpack به ما می گوید احتمالا به loader خاصی برای اجرای کد خود نیاز داشته باشید و حرفش هم درست است. اینجاست که برای کار با فایل های جاوا اسکریپت به یک loader جدید نیاز پیدا می کنیم بنابراین مثل همیشه به webpack.config.js می رویم و یک rule جدید برای این مورد تعریف می کنیم:

    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']
                    }
                }
            }
        ]
    }

به rule جدید ما توجه کنید. در قسمت test گفته ایم تمام فایل های جاوا اسکریپت، یعنی تمام فایل های جاوا اسکریپت شامل این rule می شوند. سپس پوشه node_modules را در قسمت exclude (به معنی «مستثنی کردن») گذاشته ایم تا به فایل های درون این پوشه کار نداشته و آن ها را نادیده بگیرد. چرا؟ به دلیل اینکه فایل های درون node_modules مخصوص وابستگی های پروژه هستند و ما آن ها را ننوشته ایم که حالا بخواهیم به کدهای قدیمی تبدیلشان کنیم، آن ها بدون مشکل کار می کنند. به صورت قانونی عمومی همیشه به یاد داشته باشید که هیچ وقت به فایل های درون node_modules دست نزنید مگر اینکه از کار خود مطمئن باشید.

در مرحله بعد گفته ایم که از babel-loader برای این فایل ها استفاده کن. در قسمت options نیز خصوصیتی به نام presets (تنظیمات اولیه) را تعریف کرده و مقدار آن را روی env گذاشته ایم. این مقدار به babel می گوید که نسخه های جدید تر جاوا اسکریپت (ES6 و ES7 و غیره) را به نسخه ES5 تبدیل می کند و خودمان هم می توانیم از جدید ترین کدهای جاوا اسکریپت در آن استفاده کنیم. همچنین از آنجایی که نمی توانیم از class property (خصوصیات درون کلاس ها) به صورت عادی استفاده کنیم باید از پلاگین های babel کمک بگیریم.

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

npm install @babel/core babel-loader @babel/preset-env babel-plugin-transform-class-properties --save-dev

حالا که این وابستگی ها نصب شدند می توانید دستور npm run build را اجرا کنید تا webpack اجرا شود. این بار هیچ خطایی دریافت نمی کنیم و صفحه ما بدون خطا باز خواهد شد. در قسمت بعد به سراغ توضیح پلاگین ها و انواع آن ها خواهیم رفت.

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

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

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