اگر یادتان باشد در قسمت قبل اسکریپت خاصی را برای شروع به کار webpack-dev-server نوشتیم:
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack-dev-server", "build": "webpack" }
سپس دستور npm start
را اجرا کردیم تا سرور مجازی Webpack اجرا شود. با این کار به آدرسی که به ما داده شده بود مراجعه کردیم و برنامه خود را در آن قسمت پیدا کردیم. در نگاه اول هیچ مشکلی وجود ندارد اما اگر بخواهیم فایل هایمان را ویرایش کنیم چه خواهد شد؟
اینجاست که نکته جالبی را یاد می گیریم. اگر به فایل app.ts برویم و یک کد ساده مثل console.log را به آن اضافه کنم، فکر می کنید چه اتفاقی بیفتد؟
import { ProjectInput } from './components/project-input'; import { ProjectList } from './components/project-list'; new ProjectInput(); new ProjectList('active'); new ProjectList('finished'); console.log('Hi!');
اگر این کد را ذخیره کنیم و دوباره به مرورگر برویم، این دستور log را در هیچ کجا مشاهده نمی کنیم. جالب تر اینجاست که اگر فایل bundle.js را حذف کرده و دوباره دستور npm start را اجرا کنیم (تا فایل bundle.js دوباره ساخته شود)، صفحه ما خراب می شود و دیگر سرور مجازی کار نخواهد کرد.
نکته: پس از اجرای دستور npm start اگر پوشه dist را چک کنید، فایل bundle.js را نخواهید دید، اما این مشکل برنامه ما نیست. در زمان استفاده از Webpack-dev-server فایل های جدید فقط روی مموری دستگاه ساخته می شوند و روی disk شما ثبت نخواهند شد. بنابراین مشکل خرابی برنامه به خاطر نبود فایل bundle.js نیست. با اینکه فایل bundle.js را نمی بینید، اما ساخته شده است و فقط روی دیسک شما قابل مشاهده نمی باشد.
راه حل مشکل ما رفتن به فایل webpack.config.js و اضافه کردن کد زیر است:
const path = require('path'); module.exports = { mode: 'development', entry: './src/app.ts', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), publicPath: 'dist' }, devtool: 'inline-source-map', module: { rules: [ { test: /\.ts$/, use: 'ts-loader', exclude: /node_modules/ } ] }, resolve: { extensions: ['.ts', '.js'] } };
با اضافه کردن pulicPath و دادن آدرس پوشه نهایی کدها (dist) مشکل ما حل می شود. publicPath به Webpack می گوید که فایل نهایی ما کجا ساخته خواهد شد و آدرس آن نسبت به فایل index.html چیست. در حالت پیش فرض، سرور مجازی webpack فایل html ای را در مرورگر لود می کند که در همان پوشه تعریف اسکریپتِ start (فایل package.json) باشد. در نظر اول این مسئله مشکلی ندارد چرا که فایل package.json و index.html ما در یک پوشه قرار دارند اما بعدا نمی تواند رابطه فایل index.html و پوشه dist را به درستی تشخیص دهد به همین دلیل باید به webpack بگوییم که publicPath ما کجاست.
البته اگر به کد بالا دقت کرده باشید، متوجه می شوید که من کد زیر را نیز به آن اضافه کرده ام:
mode: 'development',
ثبت حالت کاری Webpack به حالت توسعه (development) کاری می کند که webpack کمتر به دنبال بهینه سازی و فشرده سازی کدها باشد تا وقت کمتری صرف آن کند. دلیل این کار این است که اولا زمان کامپایل کردن کدها را کاهش دهیم چرا که در حالت توسعه می خواهیم سریع کار ها را انجام بدهیم نه اینکه هر بار کدها را تا حد ممکن بهینه سازی و کوچک کنیم. همچنین با انجام این کار، debug کردن کدها ساده تر می شود و پیام های خطایی که دریافت می کنیم منطقی تر و خوانا تر خواهند بود. (دانلود سورس کد تا این قسمت برای توسعه)
تا زمانی که در حال توسعه و کدنویسی هستیم، همین حالت را حفظ کنید اما زمانی که به مرحله production (قرار دادن فایل ها روی سرور واقعی برای استفاده واقعی مردم از سایت) رسیدید باید آن را تغییر دهیم چرا که به نهایت بهینه سازی نیاز خواهیم داشت. حالا فرض کنید کدهای خود را نوشته اید و دیگر به حالت توسعه نیازی ندارید. برای اینکه وارد حالت production شویم چه کار باید کرد؟
در ابتدا فایلی به نام webpack.config.prod.js بسازید. البته شما می توانید این نام را تغییر دهید اما از آنجایی که این نام یک قرارداد جا افتاده بین برنامه نویسان است بهتر است از همین نام استفاده کنید. من تمام کدهای webpack.config.js را کپی کرده و درون این فایل قرار میدهم. اول از همه باید mode را روی production بگذاریم تا webpack کدهای ما را minify و بهینه سازی کند. در مرحله بعد می توانید publicPath را حذف کنید چرا که دیگر قرار نیست از webpack-dev-server (دستور npm start) استفاده کنیم بلکه می خواهیم از دستور npm run build استفاده کنیم تا فایل نهایی bundle.js را دریافت کنیم. این فایل بعدا روی سرور ما قرار می گیرد.
در مرحله بعد devtool را روی none بگذارید چرا که در حالت production نیازی به آن ها نداریم (هنگام استفاده از وب سایت که کدها را debug نمی کنیم!). در نهایت به انتهای این فایل یک خصوصیت plugins اضافه می کنیم. plugin ها روی تمام پروژه اعمال می شوند ولی rules و modules فقط روی فایل های خاصی تاثیر دارند. در این قسمت می خواهم کدی را بنویسم که قبل از گرفتن خروجی، خروجی های قبلی (تمام فایل های درون پوشه dist) را پاک کند. با این کار همیشه آخرین و نهایی ترین نسخه را خواهیم داشت. قبل از اضافه کردن آن باید دستور زیر را اجرا کنید تا یک پکیج دیگر را هم نصب کنیم:
npm install --save-dev clean-webpack-plugin
پس از نصب این پکیج، باید آن را وارد این فایل کنید:
const path = require('path'); const CleanPlugin = require('clean-webpack-plugin'); module.exports = { // بقیه کدها //
حالا می توانیم از این پلاگین برای قسمت plugins استفاده نماییم. تمام توضیحاتی که دادم در کد زیر خلاصه می شود:
const path = require('path'); const CleanPlugin = require('clean-webpack-plugin'); module.exports = { mode: 'production', entry: './src/app.ts', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, devtool: 'none', module: { rules: [ { test: /\.ts$/, use: 'ts-loader', exclude: /node_modules/ } ] }, resolve: { extensions: ['.ts', '.js'] }, plugins: [ new CleanPlugin.CleanWebpackPlugin() ] };
متد CleanWebpackPlugin همه چیز را قبل از گرفتن خروجی در Dist حذف می کند. حالا برای اینکه به webpack بگوییم از فایل webpack.config.prod.js استفاده کند باید به package.json رفته و اسکریپت build را به شکل زیر ویرایش کنیم:
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "webpack-dev-server", "build": "webpack --config webpack.config.prod.js" }
اضافه کردن دو علامت خط فاصله و سپس config و در نهایت نام فایل، به Webpack می گوید که برای گرفتن خروجی از این فایل استفاده کند. حالا می توانید npm run build را اجرا کنید تا فایل نهایی و بهینه سازی شده bundle.js را دریافت کنید. (دانلود سورس کد حالت production)
این فصل هم در این قسمت به پایان رسید. در فصل بعدی با کتابخانه های تایپ اسکریپت آشنا خواهیم شد و یک پروژه جدید را با هم خواهیم ساخت.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.