Различия между операторами require и import в JavaScript
В современной веб-разработке мы используем require
или import
для обозначения зависимостей JavaScript. А иногда мы используем и то, и другое в сочетании и используем то, что подходит для библиотеки.
Но знаете ли вы, почему они оба существуют? Что происходит внизу? И каковы лучшие практики при использовании того или другого?
В этой статье я расскажу об использовании require
и import
и отвечу на некоторые из этих общих вопросов.
Предпосылки - Типы модулей JavaScript
Прежде чем обсуждать require
и import
, необходимо иметь представление о модулях JavaScript. Итак, давайте посмотрим, какие типы модулей JavaScript доступны.
1. AMD - определение асинхронного модуля
Модули AMD были введены, чтобы сделать модули более удобными для внешнего интерфейса. Для них не нужны сборщики пакетов, и все зависимости разрешаются динамически.
Функция AMD use require
используется для загрузки внешних модулей и может выступать в качестве оболочки для модулей CommonJS.
define("exampleModule", [], () => {
return {
print: () => console.log("Hello World!");
}
}
define("main", ["require", "exampleModule"], (require) => {
const exampleModule= require("exampleModule");
exampleModule.print();
});
Однако с появлением модулей ES использование AMD резко сократилось.
2. Модули CommonJS
CommonJS - это стандарт, используемый NodeJS для инкапсуляции JavaScript в модулях. modules.export
используется для экспорта модулей CommonJS, а функция import
используется для включения модулей в отдельные файлы.
Хотя модули CommonJS широко используются в NodeJS, они не используются при разработке внешнего интерфейса. Основная причина этого - синхронное поведение функции require
.
Однако NodeJS начал поддерживать модули ES только начиная с v13. До этого большинство модулей NodeJS, включая библиотеки NPM, разрабатывались с использованием модулей CommonJS.
Поэтому модули CommonJS по-прежнему широко используются разработчиками.
Модули CommonJS не менее важны, чем модули ES, и я расскажу больше в следующих разделах статьи.
3. UMD - универсальное определение модуля
UMD - это комбинация AMD и CommonJS. Он использует синтаксис CommonJS и асинхронную загрузку от AMD, чтобы сделать его подходящим как для серверной, так и для клиентской стороны.
UMD используется как резервный модуль в таких сборщиках, как Webpack, и простой пример модуля UMD показан ниже:
(function (root, factory) {
if (typeof define === "function" && define.amd) {
define(["jquery"], factory); // AMD
} else if (typeof exports === "object") {
modules.export = factory(require("jquery")); //CommonJS
} else {
root.returnExports = factory(root.jQuery);
} })(this, function ($) {
function exampleFunction() {}
return exampleFunction;
});
4. ESM - модули ES
Модули ES (модули ECMAScript) - официальный стандарт, используемый в JavaScript. Модули ES используют операторы import
и export
для работы с модулями. Он устраняет одно из самых больших ограничений CommonJS - синхронную загрузку.
Модули ES импортируют ведущие модули асинхронно, позволяя проводить статический анализ времени сборки.
После введения модулей ES среди разработчиков было много споров, касающихся совместимости с CommonJS. Однако разработчики адаптировались для использования обоих, и мы обсудим более подробную информацию в следующих разделах.
Поскольку теперь вы знакомы с предысторией модулей JavaScript, давайте перейдем к обсуждению require
и import
.
«Требовать» встроено в NodeJS.
require
обычно используется с NodeJS для чтения и выполнения модулей CommonJS.
Эти модули могут быть либо встроенными модулями, такими как http
, либо модулями, написанными на заказ. С require
вы можете включать их в свои файлы JavaScript и использовать их функции и переменные.
// built-in moduels const http= require('http');
// local moduels
const getBlogName = require('./blogDetails.js')
Однако, если вы используете require
для получения локальных модулей, сначала вам нужно экспортировать их с помощью modules.export
.
Например, предположим, что у вас есть файл с именем blogDetails.js
, и вам нужно использовать функцию из этого файла в index.js
файле.
Вы также можете экспортировать несколько модулей одновременно, используя modules.export
следующим образом:
Примечание. Вместо того, чтобы использовать
modules.export
в конце, вы также можете добавитьexport
в начале каждой функции. Например:exports.getBlogContent = () => {};
Думаю, теперь вы понимаете, когда следует использовать require
и как это работает. Но прежде чем перейти к уникальным функциям require
, давайте посмотрим, как работает import
. Тогда мы сможем сравнивать и противопоставлять их на более глубоком уровне понимания.
«Импорт» был введен с модулями ES6
import
- это модуль ES, и с export
они известны как ES6 import
и export
.
Мы не можем использовать
import
или экспорт вне модулей ES.
Мы видим, что попытка import
выйти за пределы модулей ES - распространенная ошибка разработчиков, и на этот счет есть много потоков StackOverflow.
Если я возьму тот же пример, единственное изменение, которое мне нужно сделать, - это изменить modules.export
на export default
.
Затем мы можем использовать import
, чтобы включить этот файл в наш index.js
файл.
Примечание. Как и
require
, вы также можете экспортировать каждую функцию по отдельности, добавив экспорт к каждому определению функции.
Eg:
export const = getBlogContent = () => {};
Итак, я надеюсь, что теперь вы понимаете, как и когда следует использовать require
и import
. Но это не все; есть некоторые существенные различия в их функциях и использовании. Пришло время для сравнения.
Требовать Vs. Импортировать
И require
, и import
используются для включения модулей. Но у них есть несколько важных функций, о которых вам следует знать.
1. Операторы Require можно вызывать в любом месте кода.
Обычно мы вызываем операторы import
или require
в начале файла.
Но знаете ли вы, что можете свободно использовать операторы
require
в любом месте вашего кода? Да, ты можешь!
С другой стороны, операторы import
могут быть определены только в начале файла. Определение оператора import
в другом месте приведет к ошибке или автоматически перейдет к началу файла.
2. Require можно назвать условно
Оператор require
позволяет загружать модули условно или динамически, когда имя загруженного модуля не определено заранее.
Например, вы можете вызвать require
внутри функции или условия if, как показано ниже:
if(articleCount>0){ const getBlogTitle = require(‘./blogDetails.js’); }
Операторы require
обладают такой гибкостью, поскольку рассматриваются как функции. Они вызываются во время выполнения, и до этого нет никакого способа узнать что-либо. Но операторы import
статичны, и мы не можем использовать их условно или динамически.
Примечание. Вы можете рассматривать это как преимущество
require
. Но посколькуimport
statements статичны, вы можете обнаружить любую ошибку до запуска приложения.
3. Операторы импорта асинхронны.
Синхронизация или асинхронность могут не иметь большого значения в небольших приложениях. Но если мы думаем о крупномасштабных приложениях, используются сотни модулей. Так,
если вы используете
require
, модули будут загружаться и обрабатываться один за другим.
С другой стороны, import
операторы решают эту проблему, работая асинхронно, и, как известно, они хорошо работают по сравнению с require
функциями в крупномасштабных приложениях.
4. Модули ES - это будущее
Как мы уже говорили, система модулей ES была введена в качестве стандарта для поддержки клиентских модулей JavaScript. Он также принят TypeScript с дополнениями для определения Type. Поэтому я не думаю, что require
снова сможет заменить ES, поскольку он стал широко используемым стандартом среди разработчиков.
Но поскольку существует множество модулей и библиотек NodeJS, написанных с использованием CommonJS, мы не можем полностью игнорировать require
. Поэтому мы должны использовать их оба соответственно.
Также мы можем настроить компиляторы для преобразования вывода различных типов модулей.
Если вы используете TypeScript, вы можете настроить таргетинг на разные модульные системы в качестве выходных данных, внеся несколько изменений в tsconfig.json
файл. Например, предположим, что нам нужно вывести версию кода, в которой используется CommonJS.
Все, что вам нужно сделать, это создать новый tsconfig
файл для вывода CommonJS, расширив исходный tsconfig
файл и изменив параметр module
в CompilerOptions
.
{ "extends": "./tsconfig.json", "compilerOptions": { "module": "CommonJS", "outDir": "./lib/cjs" }, }
Примечание. Вы также можете использовать инструменты сборки, такие как Webpack, для преобразования модулей ES в модули CommonJS.
Помимо этих существенных различий, между ними есть некоторые незначительные изменения в синтаксисе. Итак, я создал инфографическое сравнение, обобщающее все, что обсуждалось в статье, чтобы четко понять различия между require
и import
.
Создавайте из независимых компонентов для увеличения скорости и масштабирования
Вместо того, чтобы создавать монолитные приложения, сначала создайте независимые компоненты и объедините их в функции и приложения. Это ускоряет разработку и помогает командам создавать более согласованные и масштабируемые приложения.
Инструменты OSS, такие как Bit, предлагают отличные возможности разработчика для создания независимых компонентов и составления приложений. Многие команды начинают с создания своих дизайн-систем или микро-интерфейсов через компоненты. Попробуйте →
Заключение
В этой статье я рассмотрел вопрос, часто задаваемый многими разработчиками: разница между require
и import
. Хотя ES import
и export
- это новые стандарты, используемые для включения модулей, функции require широко используются в NodeJS.
Итак, понимание разницы между ними и их использованием поможет вам свести к минимуму нежелательные ошибки в вашем приложении.
Спасибо за чтение !!!
Учить больше
« Двойные кавычки против одинарных кавычек против обратных кавычек в JavaScript
Разница между использованием одинарных кавычек , двойных кавычек и обратных кавычек в строках JavaScript . blog.bitsrc.io »