درس دوازدهم: کار با برنامه‌های MPA

Working with MPA Programs

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

احتمالا تا این قسمت از کار متوجه شده اید که تمرکز ما روی برنامه های SPA یا single page application بوده است (تمام کدها درون یک فایل جاوا اسکریپت است و یک صفحه HTML داریم) اما در چند قسمت بعدی می خواهیم در مورد برنامه های MPA یا multi-page application نیز توضیحاتی را بدهیم. در واقع در این قسمت می خواهیم در حالت هایی کار کنیم که فایل جاوا اسکریپت ما به چند فایل تقسیم می شود و همچنین بیشتر از یک فایل HTML خواهیم داشت.

برای شروع کار در پوشه components پوشه جدیدی به نام kiwi-image ایجاد کنید و تصویر کیوی را که در جلسات اولیه با هم کار کرده بودیم به درون این فایل منتقل می کنم. سپس یک فایل جدید جاوا اسکریپت به نام kiwi-image.js را ایجاد کنید. محتویات درون این فایل به شکل زیر خواهد بود:

import Kiwi from './kiwi.jpg';
import './kiwi-image.scss';

class KiwiImage {
    render() {
        const img = document.createElement('img');
        img.src = Kiwi;
        img.alt = 'Kiwi';
        img.classList.add('kiwi-image');

        const bodyDomElement = document.querySelector('body');
        bodyDomElement.appendChild(img);
    }
}

export default KiwiImage;

من در ابتدا فایل تصویری کیوی را وارد کرده ام. سپس فایلی به نام kiwi-image.scss را وارد کرده ام که فعلا آن را ایجاد نکرده ایم. حالا کلاسی ساخته ایم که فقط یک متد به نام render دارد. این متد در اتبدا عنصر img را ساخته و src و alt آن را مشخص می کند. سپس کلاس kiwi-image را نیز به آن اضافه می کند. در نهایت تصویر خود را به body فایل HTML متصل می نماییم. مثل همیشه export کردن این فایل نیز با دستور export default انجام می شود.

حالا نوبت به ساختن فایل kiwi-image.scss است. این فایل را درون همان پوشه kiwi-image ساخته و محتویات آن را به شکل زیر کدنویسی کنید:

.kiwi-image {
    display: block;
    width: 400px;
    height: auto;
}

اگر از تصویر دیگری استفاده می کنید که و دوست دارید width را تغییر دهید، کاملا مختار هستید.

در مرحله بعد فایل جدیدی در پوشه src ایجاد کرده و نام آن را kiwi.js قرار دهید. محتویات درون این فایل باید به شکل زیر باشد:

import Heading from './components/heading/heading.js';
import KiwiImage from './components/kiwi-image/kiwi-image.js';

const heading = new Heading();
heading.render();
const kiwiImage = new KiwiImage();
kiwiImage.render();

این صفحه قرار است یک صفحه عادی باشد بنابراین به heading نیاز داریم (اگر از جلسات قبل یادتان باشد heading مسئول ساخت تیتر صفحه ما بود. در نهایت یک نمونه از تصویر کیوی را نیز در این صفحه ساخته ایم. حالا نام فایل index.js را به hello-world.js تغییر دهید.

بدین صورت با رفتن به یک صفحه دکمه Hello world و با رفتن به صفحه دیگر تصویر کیوی را می بینیم. من می خواهم به webpack بگویم که این دو صفحه از هم جدا هستند بنابراین به فایل webpack.production.config.js بروید و entry را به صورت یک شیء جاوا اسکریپتی پاس بدهید:

module.exports = {
    entry: {
        'hello-world': './src/hello-world.js',
        'kiwi': './src/kiwi.js'
    }

همانطور که می بینید درون این فایل دو entry مختلف را تعریف کرده ایم که دو صفحه ما هستند. مشکل بعدی اینجاست که با توجه به تنظیمات فعلی ما، نام هر دو فایل bundle خواهد بود:

    output: {
        filename: 'bundle.[contenthash].js',
        path: path.resolve(__dirname, './dist'),
        publicPath: ''
    }

درست است که hash نیز در نام آن ها قرار می گیرد اما بهتر است نام های جداگانه ای داشته باشند بنابراین می گوییم:

module.exports = {
    entry: {
        'hello-world': './src/hello-world.js',
        'kiwi': './src/kiwi.js'
    },
    output: {
        filename: '[name].[contenthash].js',
        path: path.resolve(__dirname, './dist'),
        publicPath: '/static/'
    },

همانطور که می بینید [name] یعنی نام خصوصیت موجود در شیء entry را بگیر و همان را برای فایل خروجی ما قرار بده (hello-world و kiwi). من همین کار را برای فایل های CSS نیز انجام می دهم:

    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash].css'
        }),

حالا اگر دستور npm run build را اجرا کنید و به پوشه dist بروید متوجه تغییرات می شوید. ما دو فایل جاوا اسکریپت، دو فایل CSS و یک فایل HTML داریم. تصویر ما نیز در این پوشه موجود است. آیا متوجه مشکل شدید؟ اگر واقعا بخواهیم برنامه MPA داشته باشیم باید دو فایل HTML جداگانه داشته باشیم. اگر بخواهیم چنین کاری را انجام بدهیم باید دو بار از پلاگین HTMLWebpackPlugin نمونه سازی کنیم:

    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].[contenthash].css'
        }),
        new CleanWebpackPlugin('dist'),
        new HtmlWebpackPlugin({
            filename: 'hello-world.html',
            chunks: ['hello-world'],
            title: 'Hello world',
            description: 'Hello world',
            template: 'src/page-template.hbs'
        }),
        new HtmlWebpackPlugin({
            filename: 'kiwi.html',
            chunks: ['kiwi'],
            title: 'Kiwi',
            description: 'Kiwi',
            template: 'src/page-template.hbs'
        })
    ]

من در ابتدا filename را مشخص کرده ام تا فایل های HTML ما همنام نباشند (هر نامی را که دوست دارید به آن بدهید). سپس در قسمت template از index.hbs استفاده کرده بودیم که به نظر من دیگر نام خوبی نیست چرا که index.hbs حالا فقط یک قالب کلی است بنابراین آن را به page-template.hbs تغییر نام داده ام (این کار من سلیقه ای بود و ربطی به منطق کدنویسی نداشت). در قدم بعد سوال این است که از کدام فایل جاوا اسکریپتی در کدام فایل HTML استفاده کنیم؟ برای مشخص کردن این مورد از خصوصیت chunks استفاده می کنیم بنابراین آن را نیز اضافه کرده ام و صفحه جاوا اسکریپتی خودم را به آن داده ام. توجه کنید که chunks مقدار خود را به صورت آرایه می گیرد (چرا که در پروژه های پیشرفته تر بیشتر از یک فایل جاوا اسکریپتی خواهیم داشت).

اکنون دوباره npm run build را اجرا کنید تا تغییرات پوشه dist را ببینیم. در حال حضار درون این پوشه دو فایل HTML به نام های kiwi.html و hello-worl.html داریم و مشکل ما حل شده است.

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

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