درس هشتم: پاکسازی Dist و تولید خودکار HTML

Clear Dist and Auto-Generate HTML

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

در قسمت قبل با هش کردن نام فایل بر اساس محتوا آشنا شدیم تا مشکل browser caching را دور بزنیم اما به مشکل جدیدی برخوردیم. هر بار که فایلی را ویرایش کنیم و دستور npm run build را اجرا کنیم، فایل جدیدی در dist ایجاد می شود چرا که نام آن با نام فایل قبلی تفاوت دارد و replace نمی شود. روش های مختلفی برای حل این مشکل وجود دارد که یکی از آن ها استفاده از پلاگین clean webpack plugin است. برای استفاده از آن ابتدا به فایل webpack.config.js بروید. در آنجا می گوییم:

const CleanWebpackPlugin = require('clean-webpack-plugin');

سپس به قسمت plugins بروید و یک نمونه از آن را بسازید:

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

با این کار هر زمانی که دستور npm run build را اجرا کنیم، تمام محتویات پوشه ی dist حذف می شود تا فقط فایل های جدید در آنجا بمانند. البته هنوز آن را نصب نکرده ایم بنابراین یک ترمینال را باز کنید و دستور زیر را در آن اجرا کنید:

npm install clean-webpack-plugin --save-dev

حالا اگر دستور npm run build را دوباره اجرا کنید فقط دو فایل جدید (جاوا اسکریپت و CSS) خواهیم داشت و تمام فایل های قبلی حذف شده اند. بنابراین مشکل ما تمام شد، مگر نه؟ خیر!

ما مشکل خود را حل کردیم اما با مشکل جدیدی روبرو هستیم. به فایل index.html بروید. آیا تگ های link یا script تغییری کرده اند؟ خیر تغییری نکرده اند. آیا ما نگفتیم که با هر بار تغییر دادن کدها، نام فایل ها تغییر می کند؟ آیا متوجه مشکل هستید؟ در حال حاضر فایل ما هر بار یک نام جدید می گیرد که باید به صورت دستی وارد HTML شود! بنابراین اگر الان برنامه را در مرورگر باز کنید، برنامه بالا نمی آید چرا که آدرس های جاوا اسکریپت و CSS خراب شده اند. چطور می توان این مشکل را حل کرد؟ باز هم با پلاگین ها!

وارد webpack.config.js شده و به قسمت plugins بروید. حالا مانند من می گویید:

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

حالا این پلاگین را از ابتدای فایل وارد می کنیم:

const HtmlWebpackPlugin = require('html=webpack-plugin');

در نهایت با دستور npm زیر آن را نصب می کنیم:

npm install html-webpack-plugin --save

در ضمن ترتیب انجام این کار ها، دارای نظم خاصی نیست بلکه شما می توانید ابتدا پلاگین را نصب و سپس آن را require کرده و در آخر یک نمونه از آن بسازید. مهم این است که تمام این مراحل را انجام بدهید.

حالا دستور npm run build را اجرا کنید. اگر پس از اجرای این دستور به پوشه ی Dist برویم متوجه حضور فایل index.html درون این پوشه می شویم. یعنی index.html هم در src حضور دارد و هم در پوشه ی dist. اگر index.html را باز کنید متوجه می شوید که محتوای این فایل دقیقا همان کدهایی است که قبلا نوشته بودیم با این تفاوت که webpack فایل های جاوا اسکریپت و CSS را به صورت خودکار و با نام صحیح برایمان وارد کرده است. مثلا برای فایل جاوا اسکریپت:

<script type="text/javascript" src="dist/bundle.43hgst02380tnq5ngjdj.js"></script>

همانطور که می بینید آدرس این فایل از خود پوشه ی dist نوشته شده است. اگر می خواهید پروژه ی خود را روی سرور آپلود کنید، مشکلی نیست؛ می توانیم index.html را در روت دیرکتوری آپلود کرده و سپس فایل های CSS و جاوا اسکریپت را در یک پوشه به نام dist قرار دهیم اما در هنگام توسعه، فایل index.html درون پوشه ی dist و در کنار فایل های جاوا اسکریپت و CSS خواهد بود بنابراین این آدرس دهی اشتباه است. برای حل این مشکل از فایل webpack.config.js مقدار publicPath را یک رشته ی خالی بگذارید:

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

سپس دوباره npm run build را اجرا کرده و به پوشه ی dist برگردید. حالا قسمت dist در آدرس نمی آید:

<script type="text/javascript" src="bundle.43hgst02380tnq5ngjdj.js"></script>

بنابراین می توانیم فایل index.html را باز کنیم (از پوشه ی Dist) و برنامه ی ما بدون مشکل باز خواهد شد. البته مشکلات ما هنوز هم دست از سر ما برنمی دارند! اگر به تگ title دقت کنید، متوجه می شوید که webpack آن را از Hello World به Webpack App تغییر داده است. برای حل این مشکل باید از طریق همان پلاگینی اقدام کنیم که برای این کار نصب کرده بودیم، بنابراین به فایل webpack.config.js رفته و به HtmlWebpackPlugin نگاهی می اندازیم. این پلاگین پارامتر های خاصی می گیرد که یکی از آن ها همین title است بنابراین:

    plugins: [
        new TerserPlugin(),
        new MiniCssExtractPlugin({
            filename: 'styles.[contenthash].css'
        }),
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            title: 'Hello World',
            filename: 'subfolder/custom_filename.html',
            meta: {
                viewport: 'width=device-width, initial-scale=1'
            }
        })
    ]

همانطور که می بینید من چندین خصوصیت را به عنوان پارامتر های ورودی (به صورت یک شیء جاوا اسکریپتی) به آن پاس داده ام. خصوصیت title که همان تگ title صفحه ی ما را مشخص می کند. خصوصیت filename نیز نام فایل html ما را مشخص می کند؛ مثلا اگر بخواهیم به جای index.html نا فایل ما custom_file.html باشد، این مقدار را در این قسمت تایپ می کنیم. البته اگر بخواهید، می توانید مثل من یک پوشه نیز تعریف کنید (subfolder) که فایل html در آن ایجاد شود (این پوشه خودکار ساخته می شود). یکی دیگر از این خصوصیات تگ های meta هستند که آن ها را نیز در همین قسمت مشخص می کنیم. مثلا من تگ viewport را در این قسمت مشخص کرده ام.

حالا دستور npm run build را اجرا کنید. سپس اگر به پوشه ی dist بروید، پوشه ی جدیدی به نام subfolder را مشاهده خواهید کرد که حاوی فایل custom_filename.html خواهد بود. برای اینکه با خصوصیات دیگر این پلاگین یا هر پلاگین دیگری آشنا بشوید باید به صفحه ی گیت هاب آن ها بروید. مثلا صفحه ی گیت هاب این پلاگین در آدرس https://github.com/jantimon/html-webpack-plugin قرار دارد و در قسمتی به نام options تمام این گزینه ها توضیح داده شده اند.

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

دیدگاه‌های شما (2 دیدگاه)

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

aminda
28 بهمن 1399
سلام خیلی ممنون امیر جان از آموزش های خوبت توی این آموزش با روشی که شما گفتی پلاگین ها رو نصب کردم و کانفیگ کردم و... ولی وقتی قایل custom_filename.html باز میکردم با یک صفحه کاملا سفید روبه رو میشدم یکم با همین فایل کار کردم و دیدم که داره آدرس دهی فایل های bundle.js ای هش شده و فایل css هش شده رو اشتباه میده. برای رفعش تنظیمات "../":publicpathc رو اینطوری نوشتم و درست شد البته قبلش یک ارور دیگه هم میخوردم که با عوض کردن ایمپورت پلاگین CleanWebpackPlugin به شیوه زیر اون رو هم رفعش کردم const { CleanWebpackPlugin } = require("clean-webpack-plugin");

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

programer2121
28 بهمن 1399
با سلام و خسته نباشید و تشکر فراوان برای آموزش webpack. چون من کدها را همزمان اجرا میکنم چند قسمت به خطا خوردم که اشتباه سینتکسی داشت و گفتم اطلاع دهم. const HtmlWebpackPlugin = require('html=webpack-plugin'); درست=> const HtmlWebpackPlugin = require('html-webpack-plugin'); این کد را هم برای من خطا می گرفت const CleanWebpackPlugin = require('clean-webpack-plugin'); که آن را درون آکولاد قرار دادم و مشکل حل شد const {CleanWebpackPlugin} = require('clean-webpack-plugin'); در هر صورت خدا خیرتان بدهد برای آموزش های رایگان مفیدتان

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