ایمپورت و اکسپورت در جاوا اسکریپت — به زبان ساده
تقریباً هر چیزی وقتی کوچک و تکهتکه باشد بهتر میتواند مدیریت شود. کد نیز از این قاعده مستثنا نیست. معمولاً توصیه میشود که هر تابع بهتر است تنها یک وظیفه را به انجام برساند، یا این که فایلها تعداد کامپوننتهای اندک یا فقط یکی داشته باشند. اگر اپلیکیشن پیچیدهای داشته باشید و مجبور باشید در میان صدها یا هزاران خط کد اسکرول کنید، وظیفه دیباگ کردن یا صرفاً درک کارکرد اپلیکیشن بسیار دشوارتر میشود.
خوشبختانه جاوا اسکریپت با معرفی فرایندهای ایمپورت و اکسپورت در این زمینه به ما کمک میکند. بدین ترتیب میتوان کدی را در یک فایل نوشت و این کد میتواند از سوی یک فایل یا فایلهای دیگری مورد استفاده قرار گیرد.
در نمونههایی که در این نوشته بررسی میکنیم از Node.js و React.js استفاده شده است. فایلهای React با استفاده از create-react-app ایجاد شدهاند. در ابتدا یک مثال از ES5 در Node ارائه شده است که از گزارههای require استفاده میکند و سپس همین کار با استفاده از گزارههای ایمپورت در ES6 ارائه شده است.
مثال ES5
استفاده از ساختار ES5 در Node به این معنی است که اشتراک کد بین فایلها از طریق گزارههای require و module.exports صورت میگیرد. یک ماژول (module) در جاوا اسکریپت را میتوان نوعی کانتینر دانست که کدهای مرتبط با هم را در خود نگهداری میکند و میتواند به فایل دیگری اکسپورت شود.
در ادامه فهرستی از سه خط برای یک اپلیکیشن React ارائه شدهاند که سه بلوک رنگی روی صفحه نشان میدهند:
//App.js var React = require('react'); var Component = React.Component; require('./App.css'); var Color = require('./Shapes');
بدین ترتیب چند متغیر ایجاد میشوند و چند فایل و کتابخانه نیز require شدهاند. نخستین مورد React است که با استفاده از گزاره require برابر با کتابخانه «react» تنظیم شده است. دومین مورد Component است که برابر با ماژول Component کتابخانه «react» تعیین شده است. سومین خط از require تنها برای include کردن فایل css. استفاده میکند و لازم نیست آن را برابر با متغیری قرار دهیم. در نهایت متغیر color برابر با مقدار آنچه از فایل Shapes.js اکسپورت خواهد شد و در ادامه تعیین میکنیم، قرار میگیرد. بقیه فایل مانند این است:
//App.js class App extends Component { render() { return ( <div className="App"> <div className="colors"> <Color name="red"/> <Color name="green"/> <Color name="blue"/> </div> </div> ); } } module.exports = App;
بدین ترتیب کامپوننت app تعریف میشود که سه کامپوننت color را فراخوانی میکند و در نهایت آن کامپوننت را با module.exports اکسپورت میکند.
کامپوننت color بسیار شبیه به این است:
//Shapes.js var React = require('react'); var Component = React.Component; class Color extends Component { render() { const divStyle = { backgroundColor: this.props.name, color: 'white', fontSize: '20px', height: '100px', width: '100px' } return ( <div style={divStyle}>{this.props.name}</div> ) } } module.exports = Color;
در این مورد نیز کتابخانههای مورد نیاز react را require میکنیم که یک کامپوننت را تعریف کرده و آن را اکسپورت میکند. تنها تغییر در شیء «divStyle» است که مقادیر css را نگهداری میکند. نتیجه چیزی شبیه زیر است:
اکسپورت کردن کامپوننتهای چندگانه
میتوان بیش از یک چیز را نیز از یک فایل اکسپورت کرد. اگر بخواهیم کامپوننت دیگری در این صفحه داشته باشیم چطور؟ میتوانیم فایل جدیدی ایجاد کنیم و آن را در App.js به صورت require بیاوریم یا این که فایل موجود را اضافه کرده و هر دو آنها را اکسپورت کنیم.
این وضعیت در عمل به ترجیح و شرایط اپلیکیشن شما بستگی دارد. به طور معمول انتظار میرود که کامپوننتها در اپلیکیشنهای مختلف قابلیت استفاده مجدد داشته باشند و بنابراین باید آنها را طوری ترکیب کنیم که به صورت منفرد نیز عمل کنند. با این وجود اگر اپلیکیشن شما دو کامپوننت دارد که همواره با هم استفاده میشوند، در این صورت بهتر است آنها را در یک فایل قرار داده و با هم اکسپورت کنید.
اگر کامپوننت دیگری به نام Animal به فایل App.js اضافه کنیم، مانند زیر خواهد شد:
//Shapes.js var React = require('react'); var Component = React.Component; class Color extends Component { render() { const divStyle = { backgroundColor: this.props.name, color: 'white', fontSize: '20px', height: '100px', width: '100px' } return ( <div style={divStyle}>{this.props.name}</div> ) } } class Animal extends Component { render() { const divStyle = { fontSize: '20px', height: '100px', width: '100px', border: '1px solid black', borderRadius: '50%' } return ( <div style={divStyle}>{this.props.name}</div> ) } } module.exports = Color;
اما اکنون مشکلی وجود دارد. ما تنها Color را اکسپورت کردهایم؛ اما آیا میتوانیم هر دوی آنها را اکسپورت کنیم؟ ابتدا هر دو کامپوننت را به module.exports اضافه میکنیم:
//Shapes.js module.exports = { Color: Color, Animal: Animal }
بنابراین اکنون فایل در حال اکسپورت کردن یک شیء ماژول است که دو کامپوننت درون خود دارد. از آنجا که اکسپورت اینک کمی متفاوت است؛ ایمپورت نیز باید تغییر یابد.
//App.js var {Color} = require('./Shapes'); var {Animal} = require('./Shapes');
در این جا انتساب متغیرها به هر یک از کامپوننتها صورت میگیرد؛ اما نام متغیر را در داخل کروشه ({}) نسبت میدهیم. شما میتوانید این کامپوننت را هر کجا که میخواهید فراخوانی کنید؛ اما نام متغیر باید با کلید شیء اکسپورت شده از فایل Shapes.js مطابقت داشته باشد و همچنین باید از نام متغیر هنگام فراخوانی کامپوننت React استفاده کنید.
بنابراین کد فوق در عمل کار میکند. با این که چندان واضح نیست؛ اما در هر صورت کار میکند.
//Shapes.js module.exports = { Foo: Color, Bar: Animal } //App.js var {Foo} = require('./Shapes'); var {Bar} = require('./Shapes'); class App extends Component { render() { return ( <div className="App"> <div className="colors"> <Foo name="red"/> <Foo name="green"/> <Foo name="blue"/> </div> <div className="animals"> <Bar name="dog" /> <Bar name="cat" /> <Bar name="bird" /> </div> </div> ); } }
نتیجه کار چیزی شبیه زیر است:
مثال ES6
اگر از ES6 استفاده میکنید، در این صورت مفاهیم کلی ایمپورتها و اکسپورتها مشابه هم هستند؛ اما ساختار آنها کمی تفاوت دارد.
به جای require این بار از import استفاده میکنیم و میتوانیم گزاره export default را تنها در صورتی که نیاز باشد یک مورد خاص را از فایل اکسپورت کنیم، مورد استفاده قرار دهیم:
//App.js import React, {Component} from 'react'; import './App.css'; import {Color, Animal} from './Shapes'; ... export default App; //Shapes.js import React, {Component} from 'react'; export class Color extends Component {... export class Animal extends Component {...
در فایل Shapes.js هر کلاس را به صورت انفرادی اکسپورت میکنیم. اگر به اکسپورت هر دو آنها نیاز نداشته باشید، یا بخواهید تنها یکی از آنها را داشته باشید، میتوانید از گزاره export default نیز استفاده کنید.
این همه آن چیزی است که به مفاهیم مقدماتی ایمپورت و اکسپورت کردن بین فایلها مربوط میشود. بزرگترین نکتهای که باید با خاطر سپرد این است که این مفاهیم را نباید با هم مخلوط کنید. اگر از گزاره require استفاده میکنید، در این صورت باید از module.exports استفاده کنید همچنین اگر از import استفاده میکنید، در این صورت باید از گزارههای export یا export default بهره بگیرید. امیدواریم این مقاله برای شما مفید بوده باشد.
اگر علاقهمند به یادگیری بیشتر در این زمینه هستید، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- آموزش جاوا اسکریپت (JavaScript)
- مجموعه آموزشهای طراحی و برنامه نویسی وب
- 1۰ کتابخانه و فریمورک جاوا اسکریپت که باید آنها را بشناسید
- متغیرهای جاوا اسکریپت — به زبان ساده
- تابع های Arrow در جاوا اسکریپت — از صفر تا صد
==