درک JavaScript مدرن برای دایناسورها - بخش دوم

گردآوری و تالیف : عرفان کاکایی
تاریخ انتشار : 11 شهریور 1397
دسته بندی ها : جاوا اسکریپت

Transpile کردن کد برای امکانات زبان جدید

Transpile کردن کد، یعنی تبدیل کردن کد نوشته شده در یک زبان، به کدی در یک زبان مشابه. این یک بخش مهم از توسعه frontend است. از آنجایی که مرورگرها در اضافه کردن امکانات جدید کند هستند، زبان‌های جدیدی با امکانات آزمایشی ساخته شدند تا به زبان‌هایی با سازگاری با مرورگر transpile شوند.

به عنوان مثال برای CSS، مواردی مانند Sass، Less و Stylus را داریم. برای JavaScript، معروف‌ترین آن‌ها مدتی CoffeeScript بود، که امروزه اکثر مردم از babel یا TypeScript استفاده می‌کنند. CoffeScript زبانی است که بر روی ارتقای JavaScript با اعمال تغییرات قابل ملاحظه به زبان متمرکز است. مثلا پرانتز‌های اختیاری، whitespaceهای قابل ملاحظه و... Babel یک زبان جدید نیست، اما یک transpiler است که JavaScript نسل بعدی را با ویژگی‌هایی که در تمام مرورگرها در دسترس هستند transpile می‌کند. TypeScript زبانی است که برابر با JavaScript نسل بعدی است، اما همچنین تایپت کردن استاتیک اختیاری را اضافه می‌کند. بسیاری از افراد استفاده از babel را ترجیح می‌دهند، زیرا از باقی موارد بیشتر به Vanilla JavaScript نزدیک است.

بیایید به مثالی از نحوه استفاده از babel با Build Step (قدم ساخت) Webpack قبلی خود نگاهی داشته باشیم. در ابتدا babel (که یک پکیج npm است) را از طریق این خط دستوری در پروژه خود نصب می‌کنیم:

 npm install babel-core babel-preset-env babel-loader --save-dev

دقت کنید که ما ۳ پکیج جدا را به عنوان Dependencyهای توسعه نصب می‌کنیم. Babel-core اصلی‌ترین بخش babel است، babel-preset-env یک مورد از پیش تعریف شده است که تعریف می‌کند کدام امکانات JavaScript را باید transpile کرد، و babel-loader هم پکیجی است که babel را قادر می‌سازد تا با Webpack کار کند. ما می‌توانیم با ویرایش فایل webpack.config.js به این صورت، Webpack را پیکربندی کنیم تا از babel-loader استفاده کند:

// webpack.config.js
module.exports = {
  mode: 'development',
  entry: './index.js',
  output: {
    filename: 'main.js',
    publicPath: 'dist'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['env']
          }
        }
      }
    ]
  }
};

این سینتکس می‌تواند گیج‌کننده باشد. (و خوشبختانه چیزی نیست که زیاد نیاز به ویرایش آن داشته باشیم.) اساسا ما به Webpack می‌گوییم که به دنبال تمام فایل‌های .js بگردد (به جز موارد موجود در پوشه node_modules) و transpile کردن babel را با استفاده از babel-loader به آن اعمال کند.

حال که همه چیز را راه‌اندازی کرده‌ایم، می‌توانیم شروع به نوشتن امکانات ES2015 در JavaScript خود بنماییم. در اینجا مثالی از رشته الگوی ES2015 در فایل index.js را می‌بینید:

// index.js
var moment = require('moment');
console.log("Hello from JavaScript!");
console.log(moment().startOf('day').fromNow());
var name = "Bob", time = "today";
console.log(`Hello ${name}, how are you ${time}?`);

همچنین می‌توانیم برای وارد کردن ماژول‌ها، به جای require از بیانیه ورود ES2015 استفاده کنیم، که امروزه این مورد را می‌توانید در codebaseهای زیادی ببینید:

// index.js
import moment from 'moment';
console.log("Hello from JavaScript!");
console.log(moment().startOf('day').fromNow());
var name = "Bob", time = "today";
console.log(`Hello ${name}, how are you ${time}?`);

در این مثال، سینتکس import خیلی با سینتکس require تفاوت ندارد، اما import انعطاف بیشتری برای موارد پیشرفته‌تر دارد. از آنجایی که ما index.js را تغییر دادیم، باید Webpack را مجددا در خط دستوری اجرا کنیم:

./node_modules/.bin/webpack

حال می‌توانیم index.html را در مرورگر خود مجددا بارگذاری کنیم. در حال حاضر، اکثر مرورگرهای مدرن از babel پشتیبانی می‌کنند. می‌توانید این را در مرورگری مانند Internet Explorer 9 یا بالاتر آزمایش کنید، یا می‌توانید در فایل bundle.js به دنبال خط کد transpile شده بگردید:

// bundle.js
// ...
console.log('Hello ' + name + ', how are you ' + time + '?');
// ...

در اینجا می‌توانید ببینید که babel رشته الگوی ES2015 را به رشته JavaScript معمولی transpile‌ کرد، تا با مرورگر سازگار باشد. در حالیکه این مثال ممکن است زیاد هیجان انگیز نباشد، خود قابلیت transpile کردن کد بسیار هیجان انگیز است. امکانات زیادی ماند async / await به JavaScript آمده‌اند که امروزه می‌توانید از آن‌ها استفاده کنید تا کد بهتری بنویسید. و با این که transpile کردن گاهی ممکن است خسته کننده و دردناک به نظر برسد، اما منجر به یک پیشرفت دراماتیک در این زبان شده است.

کار ما تقریبا تمام شده است، اما بخشی دیگر از آن هنوز باقی مانده است. اگر ما نگران کارایی برنامه هستیم، بهتر است فایل bundle آن را کاهش دهیم. همچنین هر زمان که JavaScript را تغییر می‌دهیم، باید دستور Webpack مجددا اجرا کنیم. پس مورد بعدی‌ای که به آن نگاهی خواهیم داشت،‌ برطرف کردن این مشکلات است.

استفاده از یک Task Runner (اسکریپت‌های npm)

حال که تصمیم به استفاده از یک Build Step برای کار با ماژول‌های JavaScript گرفته‌ایم، استفاده از یک Task Runner کاملا معقول به نظر می‌رسد. Task Runner ابزاری است که بخش‌های مختلفی از روند ساخت را خودکارسازی می‌کند. برای توسعه frontend، taskهای موجود شامل کاهش کد، بهینه‌سازی تصاویر، اجرای آزمایشات و... هستند.

در سال 2013، Grunt معروف‌ترین Task Runner برای frontend بود، که کمی پس از آن Gulp به میان آمد. هر دو به پلاگین‌هایی که ابزارهای خط دستوری دیگر را جمع‌بندی می‌کنند، تکیه می‌کنند. ظاهرا امروزه معروف‌ترین انتخاب،‌ استفاده از قابلیت‌های اسکریپت‌نویسی در خود ابزار مدیریت پکیج npm‌ است، که از پلاگین‌ها استفاده نمی‌کند، اما در عوض با دیگر ابزار خط دستوری مستقیما کار می‌کند.

بیایید چند اسکریپت npm بنویسیم که استفاده از Webpack را آسان‌تر می‌کنند. این کار، شامل اعمال یک تغییر ساده به فایل package.json، به این صورت است:

{
  "name": "modern-javascript-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --progress --mode=production",
    "watch": "webpack --progress --watch"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "moment": "^2.22.2"
  },
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^8.0.0",
    "babel-preset-env": "^1.7.0",
    "webpack": "^4.17.1",
    "webpack-cli": "^3.1.0"
  }
}

در اینجا ما دو اسکریپت را اضافه کرده‌ایم: build و watch. برای اجرای اسکریپت ساخت، می‌توانید خط دستوری را وارد کنید:

npm run build

این کد، Webpack‌ را (با پیکربندی‌هایی که پیش‌تر در فایل webpack.config.js تعریف کردیم) به همراه گزینه --progress جهت نمایش درصد پردازش و گزینه -p جهت کوچک کردن کد، اجرا خواهد کرد. برای اجرای اسکریپت watch:

npm run watch

این کد، در عوض از گزینه --watch استفاده می‌کند تا به طور خودکار هر زمان که هر فایل JavaScriptای تغییر می‌کند، Webpack را مجددا اجرا کند، که این قابلیت برای توسعه عالی است.

دقت کنید که از آنجایی که node.js مسیر هر فایل ماژول npm را می‌داند، اسکریپت‌های موجود در فایل package.json می‌توانند بدون مجبور بودن برای تعیین مسیر کامل، Webpack را اجرا کنند. ما حتی می‌توانیم با نصب webpack-dev-server همه چیز را بهتر کنیم. webpack-dev-server یک ابزار جدا است که یک وب سرور ساده با بارگذاری زنده را فراهم می‌کند. برای نصب آن به عنوان یک Dependency، این دستور را اجرا کنید:

npm install webpack-dev-server --save-dev 

سپس یک اسکریپت npm به فایل package.json اضافه کنید:

{
  "name": "modern-javascript-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --progress -p",
    "watch": "webpack --progress --watch",
    "server": "webpack-dev-server --open"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "moment": "^2.19.1"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "webpack": "^3.7.1",
    "webpack-dev-server": "^3.1.6"
  }
}

حال می‌توانید با اجرای این دستور، سرور توسعه خود را اجرا کنید:

npm run server

این کد به طور خودکار وبسایت index.html را در مرورگر شما با آدرس localhost:080 اجرا خواهد کرد. هر زمان که JavaScript موجود در فایل index.js را تغییر دهید، webpack-dev-server جاوااسکریپت خود را مجددا ساخته، و bundle خواهد کرد و سپس هم مرورگر را به طور خودکار مجددا بارگذاری خواهد کرد. این کار، از هدر رفتن مقدار زیادی از زمان شما جلوگیری خواهد کرد.

این تنها سطح ماجراست! گزینه‌های بسیار زیاد دیگری هم برای Webpack و همچنین webpack-dev-server وجود دارند. حتی می‌توانید از اسکریپت‌های npm برای کارهای دیگری مانند تبدیل Sass به CSS، فشرده‌سازی تصاویر، اجرای آزمایشات و... نیز استفاده کنید.

نتیجه گیری

و این بود، JavaScript مدرن به صورت خلاصه شده. ما از HTML‌ و JavaScript خالی شروع کرده، و به استفاده از یک ابزار مدیریت پکیج برای دانلود خودکار پکیج‌ها، یک module bundler برای ساخت یک فایل اسکریپت تکی، یک transpiler برای استفاده از امکانات JavaScript جدید، و یک task runner برای خودکارسازی بخش‌های مختلف پردازش رسیدیم. قطعا این مسائل به خصوص برای تازه‌کاران شگفت انگیز هستند. امیدوارم این مقاله برای شما پر کاربرد بوده باشد.

منبع

مقالات پیشنهادی

درک JavaScript مدرن برای دایناسورها - بخش اول

اگر از هنگام پدید آمدن JavaScript تا به حال مدتی باشد که در صحنه حضور ندارید، یادگیری آن می‌تواند سخت باشد. این اکوسیستم به قدری با سرعت در حال تغییر...

وب سایت های الهام بخش برای طراحی - سری 9

امروز قصد داریم یک سری وبسایت های خارجی که بطور کاربردی ، زیبا و قدرتمند طراحی شدن رو براتون قرار بدیم تا شما بتونین با طریقه طراحی اونها آشنا بشین یا...

وب سایت های الهام بخش برای طراحی - سری 10

امروز قصد داریم یک سری وبسایت های خارجی که بطور کاربردی ، زیبا و قدرتمند طراحی شدن رو براتون قرار بدیم تا شما بتونین با طریقه طراحی اونها آشنا بشین یا...

وب سایت های الهام بخش برای طراحی - سری 8

امروز قصد داریم یک سری وبسایت های خارجی که بطور کاربردی ، زیبا و قدرتمند طراحی شدن رو براتون قرار بدیم تا شما بتونین با طریقه طراحی اونها آشنا بشین یا...