Как импортировать функцию js
Для того, чтобы какие-то компоненты модуля (переменные/константы/функции/классы) модуля можно было подключить и использовать в другом модулей, их надо экспортировать. Мы можем экспортировать какждый компонент по отдельности. Для этого перед определением компонента указывается ключевое слово export . Например, пусть у нас будет следующий модуль message.js
// экспорт переменной export let welcome = "Welcome"; // экспорт константы export const hello = "Hello"; // экспорт функции export function sayHello() < console.log("Hello METANIT.COM"); >// экспорт класса export class Messenger < send(text)< console.log("Sending message:", text); >>
Здесь экспортируются переменная welcome , константа hello , функция sayHello() и класс Messenger . Стоит отметить, что нам необзательно экспортировать все компоненты модуля, какие-то компоненты мы можем не экспортировать и использовать только внутри этого модуля.
В качестве альтернативы мы могли бы экспортировать все компоненты вместе виде списка:
let welcome = «Welcome»; const hello = «Hello»; function sayHello() < console.log("Hello METANIT.COM"); >class Messenger < send(text)< console.log("Sending message:", text); >> export
В данном случае оба способа экспорта будут эквивалентны.
Именной импорт компонентов модуля
Все имортируемые компоненты мы можем подключить по отдельности. Для этого после оператора import в фигурных скобках указываются названия подключаемых компонентов- переменных/констант/функций/функций. Затем после оператора from указывается модуль, из которого идет импорт.
import from "путь_к_модулю";
Например, импортируем в модуле main.js экспортируемые компоненты модуля message.js :
import from "./message.js"; sayHello(); const telegram = new Messenger(); telegram.send(welcome);
Итак, здесь подключаются из модуля message.js переменная welcome , функция sayHello() и класс Messenger . При этом нам необязательно подключать все компоненты модуля. Мы можем подключить только те компоненты, которые нам непосредственно нужны и которые мы собираемся использовать.
В итоге при выполнении страницы в браузере в его консоли мы увидим результат работы компонентов подключенного модуля main.js:
Hello METANIT.COM Sending message: Welcome
Импорт всего модуля
Если в подключаемом модуля очень много компонентов, и мы собираемся использовать все возможности модуля, то перечислять все подключаемые компоненты может быть утомительно. В этом случае мы можем подключить весь функционал модуля в виде:
import * as псевдоним_модуля from "модуль";
После оператора import идет знак звездочки, который указывает, что надо подключить все экспортируемые компоненты. А после оператора as идет псевдоним модуля, с которым будет сопоставляться подключаемый модуль.
Например, подключим в файле main.js весь модуль message.js
import * as MessageModule from "./message.js"; MessageModule.sayHello(); const telegram = new MessageModule.Messenger(); telegram.send(MessageModule.welcome);
В даном случае подключаемый модуль message.js сопоставляется с идентификатором MessageModule . В качестве псевдонима модуля может выстуать произвольное название. И далее мы можем обращаться ко всем экспортируемым компонентам модуля через псевдним модуля, например, обращении к функции sayHello: MessageModule.sayHello()
import
The static import declaration is used to import read-only live bindings which are exported by another module. The imported bindings are called live bindings because they are updated by the module that exported the binding, but cannot be re-assigned by the importing module.
In order to use the import declaration in a source file, the file must be interpreted by the runtime as a module. In HTML, this is done by adding type=»module» to the tag. Modules are automatically interpreted in strict mode.
There is also a function-like dynamic import() , which does not require scripts of type=»module» .
Syntax
import defaultExport from "module-name"; import * as name from "module-name"; import export1 > from "module-name"; import export1 as alias1 > from "module-name"; import default as alias > from "module-name"; import export1, export2 > from "module-name"; import export1, export2 as alias2, /* … */ > from "module-name"; import "string name" as alias > from "module-name"; import defaultExport, export1, /* … */ > from "module-name"; import defaultExport, * as name from "module-name"; import "module-name";
Name that will refer to the default export from the module. Must be a valid JavaScript identifier.
The module to import from. The evaluation of the specifier is host-specified. This is often a relative or absolute URL to the .js file containing the module. In Node, extension-less imports often refer to packages in node_modules . Certain bundlers may permit importing files without extensions; check your environment. Only single quoted and double quoted Strings are allowed.
Name of the module object that will be used as a kind of namespace when referring to the imports. Must be a valid JavaScript identifier.
Name of the exports to be imported. The name can be either an identifier or a string literal, depending on what module-name declares to export. If it is a string literal, it must be aliased to a valid identifier.
Names that will refer to the named imports. Must be a valid JavaScript identifier.
Description
import declarations can only be present in modules, and only at the top-level (i.e. not inside blocks, functions, etc.). If an import declaration is encountered in non-module contexts (for example, tags without type=»module» , eval , new Function , which all have «script» or «function body» as parsing goals), a SyntaxError is thrown. To load modules in non-module contexts, use the dynamic import syntax instead.
All imported bindings cannot be in the same scope as any other declaration, including let , const , class , function , var , and import declaration.
import declarations are designed to be syntactically rigid (for example, only string literal specifiers, only permitted at the top-level, all bindings must be identifiers), which allows modules to be statically analyzed and linked before getting evaluated. This is the key to making modules asynchronous by nature, powering features like top-level await.
Forms of import declarations
There are four forms of import declarations:
- Named import: import < export1, export2 >from «module-name»;
- Default import: import defaultExport from «module-name»;
- Namespace import: import * as name from «module-name»;
- Side effect import: import «module-name»;
Below are examples to clarify the syntax.
Named import
Given a value named myExport which has been exported from the module my-module either implicitly as export * from «another.js» or explicitly using the export statement, this inserts myExport into the current scope.
import myExport > from "/modules/my-module.js";
You can import multiple names from the same module.
import foo, bar > from "/modules/my-module.js";
You can rename an export when importing it. For example, this inserts shortName into the current scope.
import reallyReallyLongModuleExportName as shortName > from "/modules/my-module.js";
A module may also export a member as a string literal which is not a valid identifier, in which case you must alias it in order to use it in the current module.
// /modules/my-module.js const a = 1; export a as "a-b" >;
import "a-b" as a > from "/modules/my-module.js";
Note: import < x, y >from «mod» is not equivalent to import defaultExport from «mod» and then destructuring x and y from defaultExport . Named and default imports are distinct syntaxes in JavaScript modules.
Default import
Default exports need to be imported with the corresponding default import syntax. The simplest version directly imports the default:
import myDefault from "/modules/my-module.js";
Since the default export doesn’t explicitly specify a name, you can give the identifier any name you like.
It is also possible to specify a default import with namespace imports or named imports. In such cases, the default import will have to be declared first. For instance:
import myDefault, * as myModule from "/modules/my-module.js"; // myModule.default and myDefault point to the same binding
import myDefault, foo, bar > from "/modules/my-module.js";
Importing a name called default has the same effect as a default import. It is necessary to alias the name because default is a reserved word.
import default as myDefault > from "/modules/my-module.js";
Namespace import
The following code inserts myModule into the current scope, containing all the exports from the module located at /modules/my-module.js .
import * as myModule from "/modules/my-module.js";
Here, myModule represents a namespace object which contains all exports as properties. For example, if the module imported above includes an export doAllTheAmazingThings() , you would call it like this:
.doAllTheAmazingThings();
myModule is a sealed object with null prototype. The default export available as a key called default . For more information, see module namespace object.
Note: JavaScript does not have wildcard imports like import * from «module-name» , because of the high possibility of name conflicts.
Import a module for its side effects only
Import an entire module for side effects only, without importing anything. This runs the module’s global code, but doesn’t actually import any values.
import "/modules/my-module.js";
This is often used for polyfills, which mutate the global variables.
Hoisting
Import declarations are hoisted. In this case, that means that the identifiers the imports introduce are available in the entire module scope, and their side effects are produced before the rest of the module’s code runs.
.doAllTheAmazingThings(); // myModule.doAllTheAmazingThings is imported by the next line import * as myModule from "/modules/my-module.js";
Examples
Standard Import
In this example, we create a re-usable module that exports a function to get all primes within a given range.
// getPrimes.js /** * Returns a list of prime numbers that are smaller than `max`. */ export function getPrimes(max) const isPrime = Array.from( length: max >, () => true); isPrime[0] = isPrime[1] = false; isPrime[2] = true; for (let i = 2; i * i max; i++) if (isPrime[i]) for (let j = i ** 2; j max; j += i) isPrime[j] = false; > > > return [. isPrime.entries()] .filter(([, isPrime]) => isPrime) .map(([number]) => number); >
import getPrimes > from "/modules/getPrimes.js"; console.log(getPrimes(10)); // [2, 3, 5, 7]
Imported values can only be modified by the exporter
The identifier being imported is a live binding, because the module exporting it may re-assign it and the imported value would change. However, the module importing it cannot re-assign it. Still, any module holding an exported object can mutate the object, and the mutated value can be observed by all other modules importing the same value.
You can also observe the new value through the module namespace object.
// my-module.js export let myValue = 1; setTimeout(() => myValue = 2; >, 500);
// main.js import myValue > from "/modules/my-module.js"; import * as myModule from "/modules/my-module.js"; console.log(myValue); // 1 console.log(myModule.myValue); // 1 setTimeout(() => console.log(myValue); // 2; my-module has updated its value console.log(myModule.myValue); // 2 myValue = 3; // TypeError: Assignment to constant variable. // The importing module can only read the value but can't re-assign it. >, 1000);
Specifications
| Specification |
|---|
| ECMAScript Language Specification # sec-imports |
Browser compatibility
BCD tables only load in the browser
See also
- export
- import()
- import.meta
- Previewing ES6 Modules and more from ES2015, ES2016 and beyond on blogs.windows.com (2016)
- ES6 in Depth: Modules on hacks.mozilla.org (2015)
- ES modules: A cartoon deep-dive on hacks.mozilla.org (2018)
- Exploring JS, Ch.16: Modules by Dr. Axel Rauschmayer
- Export and Import on javascript.info
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on Sep 12, 2023 by MDN contributors.
Your blueprint for a better internet.
export
The export declaration is used to export values from a JavaScript module. Exported values can then be imported into other programs with the import declaration or dynamic import. The value of an imported binding is subject to change in the module that exports it — when a module updates the value of a binding that it exports, the update will be visible in its imported value.
In order to use the export declaration in a source file, the file must be interpreted by the runtime as a module. In HTML, this is done by adding type=»module» to the tag, or by being imported by another module. Modules are automatically interpreted in strict mode.
Syntax
// Exporting declarations export let name1, name2/*, … */; // also var export const name1 = 1, name2 = 2/*, … */; // also var, let export function functionName() /* … */ > export class ClassName /* … */ > export function* generatorFunctionName() /* … */ > export const name1, name2: bar > = o; export const [ name1, name2 ] = array; // Export list export name1, /* …, */ nameN >; export variable1 as name1, variable2 as name2, /* …, */ nameN >; export variable1 as "string name" >; export name1 as default /*, … */ >; // Default exports export default expression; export default function functionName() /* … */ > export default class ClassName /* … */ > export default function* generatorFunctionName() /* … */ > export default function () /* … */ > export default class /* … */ > export default function* () /* … */ > // Aggregating modules export * from "module-name"; export * as name1 from "module-name"; export name1, /* …, */ nameN > from "module-name"; export import1 as name1, import2 as name2, /* …, */ nameN > from "module-name"; export default, /* …, */ > from "module-name"; export default as name1 > from "module-name";
Identifier to be exported (so that it can be imported via import in another script). If you use an alias with as , the actual exported name can be specified as a string literal, which may not be a valid identifier.
Description
Every module can have two different types of export, named export and default export. You can have multiple named exports per module but only one default export. Each type corresponds to one of the above syntax.
// export features declared elsewhere export myFunction2, myVariable2 >; // export individual features (can export var, let, // const, function, class) export let myVariable = Math.sqrt(2); export function myFunction() // … >
After the export keyword, you can use let , const , and var declarations, as well as function or class declarations. You can also use the export < name1, name2 >syntax to export a list of names declared elsewhere. Note that export <> does not export an empty object — it’s a no-op declaration that exports nothing (an empty name list).
Export declarations are not subject to temporal dead zone rules. You can declare that the module exports X before the name X itself is declared.
export x >; const x = 1; // This works, because `export` is only a declaration, but doesn't // utilize the value of `x`.
// export feature declared elsewhere as default export myFunction as default >; // This is equivalent to: export default myFunction; // export individual features as default export default function () /* … */ > export default class /* … */ >
Note: Names for export declarations must be distinct from each other. Having exports with duplicate names or using more than one default export will result in a SyntaxError and prevent the module from being evaluated.
The export default syntax allows any expression.
export default 1 + 1;
As a special case, functions and classes are exported as declarations, not expressions, and these declarations can be anonymous. This means functions will be hoisted.
// Works because `foo` is a function declaration, // not a function expression foo(); export default function foo() console.log("Hi"); > // It's still technically a declaration, but it's allowed // to be anonymous export default function () console.log("Hi"); >
Named exports are useful when you need to export several values. When importing this module, named exports must be referred to by the exact same name (optionally renaming it with as ), but the default export can be imported with any name. For example:
// file test.js const k = 12; export default k;
// some other file import m from "./test"; // note that we have the freedom to use import m instead of import k, because k was default export console.log(m); // 12
You can also rename named exports to avoid naming conflicts:
export myFunction as function1, myVariable as variable >;
You can rename a name to something that’s not a valid identifier by using a string literal. For example:
export myFunction as "my-function" >;
Re-exporting / Aggregating
A module can also «relay» values exported from other modules without the hassle of writing two separate import/export statements. This is often useful when creating a single module concentrating various exports from various modules (usually called a «barrel module»).
This can be achieved with the «export from» syntax:
export default as function1, function2 > from "bar.js";
Which is comparable to a combination of import and export, except that function1 and function2 do not become available inside the current module:
import default as function1, function2 > from "bar.js"; export function1, function2 >;
Most of the «import from» syntaxes have «export from» counterparts.
export x > from "mod"; export x as v > from "mod"; export * as ns from "mod";
There is also export * from «mod» , although there’s no import * from «mod» . This re-exports all named exports from mod as the named exports of the current module, but the default export of mod is not re-exported. If there are two wildcard exports statements that implicitly re-export the same name, neither one is re-exported.
// -- mod1.js -- export const a = 1; // -- mod2.js -- export const a = 3; // -- barrel.js -- export * from "./mod1.js"; export * from "./mod2.js"; // -- main.js -- import * as ns from "./barrel.js"; console.log(ns.a); // undefined
Attempting to import the duplicate name directly will throw an error.
import a > from "./barrel.js"; // SyntaxError: The requested module './barrel.js' contains conflicting star exports for name 'a'
The following is syntactically invalid despite its import equivalent:
export DefaultExport from "bar.js"; // Invalid
The correct way of doing this is to rename the export:
export default as DefaultExport > from "bar.js";
The «export from» syntax allows the as token to be omitted, which makes the default export still re-exported as default export.
export default, function2 > from "bar.js";
Examples
Using named exports
In a module my-module.js , we could include the following code:
// module "my-module.js" function cube(x) return x * x * x; > const foo = Math.PI + Math.SQRT2; const graph = options: color: "white", thickness: "2px", >, draw() console.log("From graph draw function"); >, >; export cube, foo, graph >;
Then in the top-level module included in your HTML page, we could have:
import cube, foo, graph > from "./my-module.js"; graph.options = color: "blue", thickness: "3px", >; graph.draw(); console.log(cube(3)); // 27 console.log(foo); // 4.555806215962888
It is important to note the following:
- You need to include this script in your HTML with a element of type=»module» , so that it gets recognized as a module and dealt with appropriately.
- You can’t run JS modules via a file:// URL — you’ll get CORS errors. You need to run it via an HTTP server.
Using the default export
If we want to export a single value or to have a fallback value for your module, you could use a default export:
// module "my-module.js" export default function cube(x) return x * x * x; >
Then, in another script, it is straightforward to import the default export:
import cube from "./my-module.js"; console.log(cube(3)); // 27
Using export from
Let’s take an example where we have the following hierarchy:
- childModule1.js : exporting myFunction and myVariable
- childModule2.js : exporting MyClass
- parentModule.js : acting as an aggregator (and doing nothing else)
- top level module: consuming the exports of parentModule.js
This is what it would look like using code snippets:
// In childModule1.js function myFunction() console.log("Hello!"); > const myVariable = 1; export myFunction, myVariable >;
// In childModule2.js class MyClass constructor(x) this.x = x; > > export MyClass >;
// In parentModule.js // Only aggregating the exports from childModule1 and childModule2 // to re-export them export myFunction, myVariable > from "childModule1.js"; export MyClass > from "childModule2.js";
// In top-level module // We can consume the exports from a single module since parentModule // "collected"/"bundled" them in a single source import myFunction, myVariable, MyClass > from "parentModule.js";
Specifications
| Specification |
|---|
| ECMAScript Language Specification # sec-exports |
Browser compatibility
BCD tables only load in the browser
See also
- import
- JavaScript modules guide
- ES6 in Depth: Modules on hacks.mozilla.org (2015)
- ES modules: A cartoon deep-dive on hacks.mozilla.org (2018)
- Exploring JS, Ch.16: Modules by Dr. Axel Rauschmayer
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on Sep 12, 2023 by MDN contributors.
Your blueprint for a better internet.
Экспорт и импорт
Директивы экспорт и импорт имеют несколько вариантов вызова.
В предыдущей главе мы видели простое использование, давайте теперь посмотрим больше примеров.
Экспорт до объявления
Мы можем пометить любое объявление как экспортируемое, разместив export перед ним, будь то переменная, функция или класс.
Например, все следующие экспорты допустимы:
// экспорт массива export let months = ['Jan', 'Feb', 'Mar', 'Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; // экспорт константы export const MODULES_BECAME_STANDARD_YEAR = 2015; // экспорт класса export class User < constructor(name) < this.name = name; >>
Не ставится точка с запятой после экспорта класса/функции
Обратите внимание, что export перед классом или функцией не делает их функциональным выражением. Это всё также объявление функции, хотя и экспортируемое.
Большинство руководств по стилю кода в JavaScript не рекомендуют ставить точку с запятой после объявлений функций или классов.
Поэтому в конце export class и export function не нужна точка с запятой:
export function sayHi(user) < alert(`Hello, $!`); > // без ; в конце
Экспорт отдельно от объявления
Также можно написать export отдельно.
Здесь мы сначала объявляем, а затем экспортируем:
// say.js function sayHi(user) < alert(`Hello, $!`); > function sayBye(user) < alert(`Bye, $!`); > export ; // список экспортируемых переменных
…Или, технически, мы также можем расположить export выше функций.
Импорт *
Обычно мы располагаем список того, что хотим импортировать, в фигурных скобках import <. >, например вот так:
// main.js import from './say.js'; sayHi('John'); // Hello, John! sayBye('John'); // Bye, John!
Но если импортировать нужно много чего, мы можем импортировать всё сразу в виде объекта, используя import * as . Например:
// main.js import * as say from './say.js'; say.sayHi('John'); say.sayBye('John');
На первый взгляд «импортировать всё» выглядит очень удобно, не надо писать лишнего, зачем нам вообще может понадобиться явно перечислять список того, что нужно импортировать?
Для этого есть несколько причин.
-
Современные инструменты сборки (webpack и другие) собирают модули вместе и оптимизируют их, ускоряя загрузку и удаляя неиспользуемый код. Предположим, мы добавили в наш проект стороннюю библиотеку say.js с множеством функций:
// say.js export function sayHi() < . >export function sayBye() < . >export function becomeSilent()
Теперь, если из этой библиотеки в проекте мы используем только одну функцию:
// main.js import from './say.js';
Импорт «как»
Мы также можем использовать as , чтобы импортировать под другими именами.
Например, для краткости импортируем sayHi в локальную переменную hi , а sayBye импортируем как bye :
// main.js import from './say.js'; hi('John'); // Hello, John! bye('John'); // Bye, John!
Экспортировать «как»
Аналогичный синтаксис существует и для export .
Давайте экспортируем функции, как hi и bye :
// say.js . export ;
Теперь hi и bye – официальные имена для внешнего кода, их нужно использовать при импорте:
// main.js import * as say from './say.js'; say.hi('John'); // Hello, John! say.bye('John'); // Bye, John!
Экспорт по умолчанию
На практике модули встречаются в основном одного из двух типов:
- Модуль, содержащий библиотеку или набор функций, как say.js выше.
- Модуль, который объявляет что-то одно, например модуль user.js экспортирует только class User .
По большей части, удобнее второй подход, когда каждая «вещь» находится в своём собственном модуле.
Естественно, требуется много файлов, если для всего делать отдельный модуль, но это не проблема. Так даже удобнее: навигация по проекту становится проще, особенно, если у файлов хорошие имена, и они структурированы по папкам.
Модули предоставляют специальный синтаксис export default («экспорт по умолчанию») для второго подхода.
Ставим export default перед тем, что нужно экспортировать:
// user.js export default class User < // просто добавьте "default" constructor(name) < this.name = name; >>
Заметим, в файле может быть не более одного export default .
…И потом импортируем без фигурных скобок:
// main.js import User from './user.js'; // не , просто User new User('John');
Импорты без фигурных скобок выглядят красивее. Обычная ошибка начинающих: забывать про фигурные скобки. Запомним: фигурные скобки необходимы в случае именованных экспортов, для export default они не нужны.
| Именованный экспорт | Экспорт по умолчанию |
|---|---|
| export class User | export default class User |
| import from . | import User from . |
Технически в одном модуле может быть как экспорт по умолчанию, так и именованные экспорты, но на практике обычно их не смешивают. То есть, в модуле находятся либо именованные экспорты, либо один экспорт по умолчанию.
Так как в файле может быть максимум один export default , то экспортируемая сущность не обязана иметь имя.
Например, всё это – полностью корректные экспорты по умолчанию:
export default class < // у класса нет имени constructor() < . >>
export default function(user) < // у функции нет имени alert(`Hello, $!`); >
