Import definition

CSS Reference

CSS ReferenceCSS Browser SupportCSS SelectorsCSS FunctionsCSS Reference AuralCSS Web Safe FontsCSS AnimatableCSS UnitsCSS PX-EM ConverterCSS ColorsCSS Color ValuesCSS Default ValuesCSS Entities

CSS Properties

align-content align-items align-self all animation animation-delay animation-direction animation-duration animation-fill-mode animation-iteration-count animation-name animation-play-state animation-timing-function

backface-visibility background background-attachment background-blend-mode background-clip background-color background-image background-origin background-position background-repeat background-size border border-bottom border-bottom-color border-bottom-left-radius border-bottom-right-radius border-bottom-style border-bottom-width border-collapse border-color border-image border-image-outset border-image-repeat border-image-slice border-image-source border-image-width border-left border-left-color border-left-style border-left-width border-radius border-right border-right-color border-right-style border-right-width border-spacing border-style border-top border-top-color border-top-left-radius border-top-right-radius border-top-style border-top-width border-width bottom box-decoration-break box-shadow box-sizing break-after break-before break-inside

caption-side caret-color @charset clear clip clip-path color column-count column-fill column-gap column-rule column-rule-color column-rule-style column-rule-width column-span column-width columns content counter-increment counter-reset cursor

direction display empty-cells filter flex flex-basis flex-direction flex-flow flex-grow flex-shrink flex-wrap float font @font-face font-family font-feature-settings font-kerning font-size font-size-adjust font-stretch font-style font-variant font-variant-caps font-weight

grid grid-area grid-auto-columns grid-auto-flow grid-auto-rows grid-column grid-column-end grid-column-gap grid-column-start grid-gap grid-row grid-row-end grid-row-gap grid-row-start grid-template grid-template-areas grid-template-columns grid-template-rows

hanging-punctuation height hyphens @import isolation justify-content @keyframes left letter-spacing

line-height list-style list-style-image list-style-position list-style-type

margin margin-bottom margin-left margin-right margin-top max-height max-width @media min-height min-width mix-blend-mode

object-fit object-position opacity order outline outline-color outline-offset outline-style outline-width overflow overflow-x overflow-y

padding padding-bottom padding-left padding-right padding-top page-break-after page-break-before page-break-inside perspective perspective-origin pointer-events position quotes

resize right

scroll-behavior


tab-size table-layout text-align text-align-last text-decoration text-decoration-color text-decoration-line text-decoration-style text-indent text-justify text-overflow text-shadow text-transform top

transform transform-origin transform-style transition transition-delay transition-duration transition-property transition-timing-function

unicode-bidi user-select

vertical-align visibility

white-space width word-break word-spacing word-wrap writing-mode

z-index

Nesting permalinkNesting

Imports are usually written at the top level of a stylesheet, but they don’t have to be. They can nested within style rules or plain CSS at-rules as well. The imported CSS is nested in that context, which makes nested imports useful for scoping a chunk of CSS to a particular element or media query. Note that top-level mixins, functions, and variables defined in the nested import are still defined globally, though.

Fun fact:

Nested imports are very useful for scoping third-party stylesheets, but if you’re the author of the stylesheet you’re importing, it’s usually a better idea to write your styles in a mixin and include that mixin in the nested context. A mixin can be used in more flexible ways, and it’s clearer when looking at the imported stylesheet how it’s intended to be used.

️ Heads up!

The CSS in nested imports is evaluated like a mixin, which means that any parent selectors will refer to the selector in which the stylesheet is nested.

Why imports?

Think about how you load different types of resources on the web. For JS, we have . For CSS, your go-to is probably . For images it’s . Video has . Audio, …. Get to the point! The majority of the web’s content has a simple and declarative way to load itself. Not so for HTML. Here’s your options:

  1. — tried and true but heavy weight. An iframe’s content lives entirely in a separate context than your page. While that’s mostly a great feature, it creates additional challenges (shrink wrapping the size of the frame to its content is tough, insanely frustrating to script into/out of, nearly impossible to style).
  2. AJAX — I love , but you’re saying I need JS to load HTML? That doesn’t seem right.
  3. CrazyHacks — embedded in strings, hidden as comments (e.g. ). Yuck!

See the irony? The web’s most basic content, HTML, requires the greatest amount of effort to work with. Fortunately, Web Components are here to get us back on track.

Импорт стилей в Less¶

В Less импорт стилей происходит с помощью всё той же директивы, но с расширенным функционалом. Перед именем файла можно указывать (необязательно) ключевое слово, которое указывает компилятору, как ему поступать с файлом.

Тем более, вы можете комбинировать ключевые слова для достижения определённых целей. Например, если нужно использовать css-файл как less-файл, но при этом не выводить его содержимого.

Во-первых, в Less не регламентируется то, где возможно подключение других таблиц стилей. Вы можете использовать директиву до объявления селекторов, после или даже между ними:

Во вторых, расширение файла может быть любым, главное — чтобы в нём содержался валидный CSS- или Less-синтаксис. Но здесь начинают действовать специфичные для Less правила:

Файлы с расширением :

Если при подключении файла с помощью директивы будет указано расширение , то такой файл подключается как обычный css-файл и не обрабатывается компилятором.

Файлы без расширения:

Если при подключении файла с помощью директивы у него не будет указано расширение, то такой файл подключается как less-файл и обрабатывается компилятором.

Файлы с другими расширениями:

Если при подключении файла с помощью директивы у него будет указано расширение, но оно не соответствует ни ни , то такой файл подключается как less-файл и будет обрабатываться компилятором.

Все это вкупе с доступными опциями для директивы , которые будут рассматриваться позднее, даёт вам возможность построения гибкой и хорошо поддерживаемой структуры проекта. Про структуру проекта я буду рассказывать намного позднее, так как без полного понимания доступных возможностей Less она вам не пригодится.

Пример 2.6.1

Рассмотрим пример, который отображает всю суть импорта стилей в Less. Для этого создадим в директории следующие файлы: , , и . В этих файлах объявим одноимённые с названиями файлов классы и укажем с помощью свойства официальный цвет сервиса. Кроме них нам понадобится файл , к которому будут подключаться эти файлы.

Для наглядности я предлагаю посмотреть на карту директории этого примера:

Теперь я предлагаю взглянуть на содержимое файла и то, что получилось после его компиляции.

Содержимое файла :

Как не сложно заметить, подключение таблиц стилей происходит до и после содержимого файла, что не допускается в CSS, но разрешено в Less.

Содержимое файла , полученное после компиляции:

Во время компиляции происходит конкатенация содержимого файлов. А файлы с расширением подключаются стандартным для CSS способом.

Import *

Usually, we put a list of what to import in curly braces , like this:

But if there’s a lot to import, we can import everything as an object using , for instance:

At first sight, “import everything” seems such a cool thing, short to write, why should we ever explicitly list what we need to import?

Well, there are few reasons.

  1. Modern build tools (webpack and others) bundle modules together and optimize them to speedup loading and remove unused stuff.

    Let’s say, we added a 3rd-party library to our project with many functions:

    Now if we only use one of functions in our project:

    …Then the optimizer will see that and remove the other functions from the bundled code, thus making the build smaller. That is called “tree-shaking”.

  2. Explicitly listing what to import gives shorter names: instead of .

  3. Explicit list of imports gives better overview of the code structure: what is used and where. It makes code support and refactoring easier.

Re-export

“Re-export” syntax allows to import things and immediately export them (possibly under another name), like this:

Why would that be needed? Let’s see a practical use case.

Imagine, we’re writing a “package”: a folder with a lot of modules, with some of the functionality exported outside (tools like NPM allow us to publish and distribute such packages), and many modules are just “helpers”, for internal use in other package modules.

The file structure could be like this:

We’d like to expose the package functionality via a single entry point, the “main file” , to be used like this:

The idea is that outsiders, developers who use our package, should not meddle with its internal structure, search for files inside our package folder. We export only what’s necessary in and keep the rest hidden from prying eyes.


As the actual exported functionality is scattered among the package, we can import it into and export from it:

Now users of our package can .

The syntax is just a shorter notation for such import-export:

The default export needs separate handling when re-exporting.

Let’s say we have , and we’d like to re-export class from it:

  1. won’t work. What can go wrong?… But that’s a syntax error!

    To re-export the default export, we have to write , as in the example above.

  2. re-exports only named exports, but ignores the default one.

    If we’d like to re-export both named and the default export, then two statements are needed:

Such oddities of re-exporting the default export are one of the reasons why some developers don’t like them.

Проверка импортируемости модуля

Python содержит стиль кодирования под названием EAFP: Easier to ask for forgiveness than permission (легче просить о прощении, чем разрешения). Это значит, что зачастую проще предположить, что что-то существует (к примеру, ключ в словаре), и словить ошибку, если это не так. Ранее мы пытались импортировать модуль, с вероятностью получить ошибку ImportError, если его не существует. Что если нам нужно проверить и увидеть, может ли модуль быть импортированным, чтобы исключить догадки? Вы можете добиться этого с importlib!

Python

import importlib.util

def check_module(module_name): «»» Проверяет, можно ли импортировать модуль без его фактического импорта «»» module_spec = importlib.util.find_spec(module_name) if module_spec is None: print(‘Module: {} not found’.format(module_name)) return None else: print(‘Module: {} can be imported!’.format(module_name)) return module_spec

def import_module_from_spec(module_spec): module = importlib.util.module_from_spec(module_spec) module_spec.loader.exec_module(module) return module

if __name__ == ‘__main__’: module_spec = check_module(‘fake_module’) module_spec = check_module(‘collections’) if module_spec: module = import_module_from_spec(module_spec) print(dir(module))

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

importimportlib.util

defcheck_module(module_name)

«»»

    Проверяет, можно ли импортировать модуль без его фактического импорта     «»»

module_spec=importlib.util.find_spec(module_name)

ifmodule_spec isNone

print(‘Module: {} not found’.format(module_name))

returnNone

else

print(‘Module: {} can be imported!’.format(module_name))

returnmodule_spec

defimport_module_from_spec(module_spec)

module=importlib.util.module_from_spec(module_spec)

module_spec.loader.exec_module(module)

returnmodule

if__name__==’__main__’

module_spec=check_module(‘fake_module’)

module_spec=check_module(‘collections’)

ifmodule_spec

module=import_module_from_spec(module_spec)

print(dir(module))

Импортируем модуль «this»

В Пайтоне есть ключевые слова для импорта модулей. Попробуйте вот этот:

Python

import this

1 importthis

Запустив данный код в своем интерпретаторе, вы увидите что-то в таком духе:

Python

The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren’t special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one— and preferably only one —obvious way to do it. Although that way may not be obvious at first unless you’re Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it’s a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea — let’s do more of those!

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren’t special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one— and preferably only one —obvious way to do it. Although that way may not be obvious at first unless you’re Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it’s a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea — let’s do more of those!

Поздравляем, вы нашли «пасхальное яйцо» в Пайтоне, также известное как «Дзен». Это одна из лучших неофициальных частей работы в Пайтон. Сам по себе модуль this не делает ничего особенного, только показывает оригинальный способ импорта чего-либо. Теперь давайте импортируем что-нибудь, чем мы сможем воспользоваться в будущем, к примеру, модуль math:

Python

import math

print(math.sqrt(4)) # 2.0

1 2 3

importmath

print(math.sqrt(4))# 2.0

В примере выше мы импортировали модуль math и сделали что-то новое. Мы вызвали одну из функций модуля – sqrt (т.е. square root – квадратный корень). Для вызова метода импортированного модуля, нам нужно использовать следующий синтаксис: module_name.method_name(аргумент). В данном примере мы нашли квадратный корень от 4. В модуле math есть много других функций, которыми мы можем воспользоваться, такие как нахождение косинуса, факториал, логарифмы и другие. Вы можете призывать эти функции таким же образом, как и с функцией sqrt. Единственное, в чем вам нужно удостовериться – принимают ли они большее количество аргументов или нет. Теперь посмотрим на другой способ импорта.

Динамический импорт

Модуль importlib поддерживает возможность импорта модуля, который был передан строке. Так что давайте создадим несколько простых модулей, с которыми мы сможем работать. Мы выделим каждому модулю одинаковый интерфейс, но дадим им выводить свои названия, чтобы увидеть разницу между ними. Создадим два модуля с разными названиями, вроде foo.py и bar.py, и добавим в них следующий код:

Python

def main(): print(__name__)

1 2

defmain()

print(__name__)

Теперь нам остается только использовать importlib чтобы импортировать их. Давайте посмотрим на следующий код, чтобы сделать именно это. Убедитесь в том, что этот код находится в той же папке, что и созданные ранее два модуля.

Python

import importlib

def dynamic_import(module): return importlib.import_module(module)

if __name__ == ‘__main__’: module = dynamic_import(‘foo’) module.main()

module_two = dynamic_import(‘bar’) module_two.main()

1 2 3 4 5 6 7 8 9 10 11

importimportlib

defdynamic_import(module)

returnimportlib.import_module(module)

if__name__==’__main__’

module=dynamic_import(‘foo’)

module.main()

module_two=dynamic_import(‘bar’)

module_two.main()

Здесь мы импортируем модуль importlib и создаем очень простую функцию под названием dynamic_import. Все, что делает эта функция, это вызывает другую функцию importlib — import_module со строкой модуля, который мы ей передали, и возвращает результат этого вызова. Далее, в нашем условном операторе внизу, мы можем вызвать главный метод каждого модуля, который покорно выведет название модуля. Вы, скорее всего, не будете делать это часто в своем коде, но периодически вам может быть нужно импортировать модуль, когда он представлен только в виде строки. Модуль importlib дает возможность сделать именно это.

Importing CSS permalinkImporting CSS

Dart Sass
since 1.11.0
LibSass
partial
Ruby Sass

LibSass supports importing files with the extension , but contrary to the specification they’re treated as SCSS files rather than being parsed as CSS. This behavior has been deprecated, and an update is in the works to support the behavior described below.

In addition to importing and files, Sass can import plain old files. The only rule is that the import must not explicitly include the extension, because that’s used to indicate a .

CSS Output


CSS files imported by Sass don’t allow any special Sass features. In order to make sure authors don’t accidentally write Sass in their CSS, all Sass features that aren’t also valid CSS will produce errors. Otherwise, the CSS will be rendered as-is. It can even be extended!

CSS Properties

align-contentalign-itemsalign-selfallanimationanimation-delayanimation-directionanimation-durationanimation-fill-modeanimation-iteration-countanimation-nameanimation-play-stateanimation-timing-functionbackface-visibilitybackgroundbackground-attachmentbackground-blend-modebackground-clipbackground-colorbackground-imagebackground-originbackground-positionbackground-repeatbackground-sizeborderborder-bottomborder-bottom-colorborder-bottom-left-radiusborder-bottom-right-radiusborder-bottom-styleborder-bottom-widthborder-collapseborder-colorborder-imageborder-image-outsetborder-image-repeatborder-image-sliceborder-image-sourceborder-image-widthborder-leftborder-left-colorborder-left-styleborder-left-widthborder-radiusborder-rightborder-right-colorborder-right-styleborder-right-widthborder-spacingborder-styleborder-topborder-top-colorborder-top-left-radiusborder-top-right-radiusborder-top-styleborder-top-widthborder-widthbottombox-decoration-breakbox-shadowbox-sizingbreak-afterbreak-beforebreak-insidecaption-sidecaret-color@charsetclearclipclip-pathcolorcolumn-countcolumn-fillcolumn-gapcolumn-rulecolumn-rule-colorcolumn-rule-stylecolumn-rule-widthcolumn-spancolumn-widthcolumnscontentcounter-incrementcounter-resetcursordirectiondisplayempty-cellsfilterflexflex-basisflex-directionflex-flowflex-growflex-shrinkflex-wrapfloatfont@font-facefont-familyfont-feature-settingsfont-kerningfont-sizefont-size-adjustfont-stretchfont-stylefont-variantfont-variant-capsfont-weightgridgrid-areagrid-auto-columnsgrid-auto-flowgrid-auto-rowsgrid-columngrid-column-endgrid-column-gapgrid-column-startgrid-gapgrid-rowgrid-row-endgrid-row-gapgrid-row-startgrid-templategrid-template-areasgrid-template-columnsgrid-template-rowshanging-punctuationheighthyphens@importisolationjustify-content@keyframesleftletter-spacingline-heightlist-stylelist-style-imagelist-style-positionlist-style-typemarginmargin-bottommargin-leftmargin-rightmargin-topmax-heightmax-width@mediamin-heightmin-widthmix-blend-modeobject-fitobject-positionopacityorderoutlineoutline-coloroutline-offsetoutline-styleoutline-widthoverflowoverflow-xoverflow-ypaddingpadding-bottompadding-leftpadding-rightpadding-toppage-break-afterpage-break-beforepage-break-insideperspectiveperspective-originpointer-eventspositionquotesresizerightscroll-behaviortab-sizetable-layouttext-aligntext-align-lasttext-decorationtext-decoration-colortext-decoration-linetext-decoration-styletext-indenttext-justifytext-overflowtext-shadowtext-transformtoptransformtransform-origintransform-styletransitiontransition-delaytransition-durationtransition-propertytransition-timing-functionunicode-bidiuser-selectvertical-alignvisibilitywhite-spacewidthword-breakword-spacingword-wrapwriting-modez-index

Всё о __init__.py

У файла есть две функции:

  1. Превратить папку со скриптами в импортируемый пакет модулей (до Python 3.3).
  2. Выполнить код инициализации пакета.

Превращение папки со скриптами в импортируемый пакет модулей

Чтобы импортировать модуль (или пакет) из директории, которая находится не в директории нашего скрипта (или не в директории, из которой мы запускаем интерактивный интерпретатор), этот модуль должен быть в пакете.

Как было сказано ранее, любая директория, содержащая файл , является пакетом. Например, при работе с Python 2.7 может импортировать пакет , но не , так как в директории нет файла .

Это не относится к Python 3.3 и выше благодаря появлению неявных пакетов пространств имён. Проще говоря, в Python 3.3+ все папки считаются пакетами, поэтому пустые файлы больше не нужны.

Допустим, — пакет пространства имён, так как в нём нет . Если запустить интерактивную оболочку Python 3.6 в директории , то мы увидим следующее:

Выполнение кода инициализации пакета

В момент, когда пакет или один из его модулей импортируется в первый раз, Python выполняет в корне пакета, если такой файл существует. Все объекты и функции, определённые в , считаются частью пространства имён пакета.

Рассмотрим следующий пример:

test/packA/a1.py

test/packA/__init__.py

test/start.py

Вывод после запуска :

Примечание Если вызовет , и мы запустим , то не будет вызван, несмотря на то, что вроде бы является частью пакета . Это связано с тем, что когда Python выполняет скрипт (в данном случае ), содержащая его папка не считается пакетом.

Примеры

Пример 1: известен заранее

Если вы собираетесь вызывать только или , то прописать импорты всем модулям не составит труда. В данном случае всегда будет включать папку . Таким образом, все импорты можно писать относительно этой папки.

Пример: файлу в проекте нужно импортировать функцию из .

Решение: (или любой другой эквивалентный синтаксис импорта).

Пример 2: мог измениться

Зачастую нам требуется как запускать скрипт напрямую из командной строки, так и импортировать его как модуль в другом скрипте. Как вы увидите далее, здесь могут возникнуть проблемы, особенно в Python 3.

Пример: пусть нужно импортировать , которому нужно импортировать . Предположим, что всегда запускается напрямую, а не импортируется. Также мы хотим иметь возможность запускать напрямую.

Звучит просто, не так ли? Нам всего лишь нужно выполнить два импорта: один в и другой в .

Проблема: это один из тех случаев, когда меняется. Когда мы выполняем , содержит , а при выполнении содержит .

С импортом в нет никаких проблем. Так как этот модуль всегда запускается напрямую, мы знаем, что при его выполнении в всегда будет . Тогда импортировать можно просто с помощью .

С импортом в немного сложнее. Когда мы запускаем напрямую, содержит , поэтому в импорт будет выглядеть как . Однако если запустить напрямую, то в уже будет . Теперь импорт вызовет ошибку, так как не является папкой внутри .

Вместо этого мы могли бы попробовать . Это решает проблему при запуске напрямую, однако теперь создаёт проблему при запуске . В Python 3 это приведёт к ошибке, потому что не находится в (в Python 2 это не вызовет проблемы из-за поддержки неявных относительных импортов).

Обобщим информацию:

Запускаем
Нет проблем В Py2 нет проблем, в Py3 ошибка ( не в )
Ошибка ( не в ) Нет проблем

Использование относительного импорта будет иметь тот же эффект, что и .

Вряд ли для этой проблемы есть чистое решение, поэтому вот несколько обходных путей:

1. Использовать абсолютные импорты относительно директории (т. е. средняя колонка в таблице выше). Это гарантирует, что запуск напрямую всегда сработает. Чтобы запустить напрямую, запустите его как импортируемый модуль, а не как скрипт:

  1. В консоли смените директорию на  .
  2. Запустите .

2. Использовать абсолютные импорты относительно директории (средняя колонка в таблице). Это гарантирует, что запуск напрямую всегда сработает. Чтобы запустить напрямую, можно изменить в , чтобы включить перед импортом .

Примечание Обычно этот метод работает, однако в некоторых случаях переменная может быть неправильной. В таком случае нужно использовать встроенный пакет . Подробнее в этом ответе на StackOverflow.

3. Использовать только Python 2 и неявные относительные импорты (последняя колонка в таблице).

4. Использовать абсолютные импорты относительно директории и добавить её в переменную среды . Это решение не переносимо, поэтому лучше не использовать его. О том, как добавить директорию в , читайте в этом ответе.

Пример 3: мог измениться (вариант 2)

А вот ещё одна проблема посложнее. Допустим, модуль никогда не надо запускать напрямую, но он импортируется и , которые запускаются напрямую.

В этом случае первое решение из примера выше не сработает. Тем не менее, всё ещё можно использовать остальные решения.

Пример 4: импорт из родительской директории

Если мы не изменяем и стараемся не изменять программно, то сталкиваемся со следующим основным ограничением импортов в Python: при запуске скрипта напрямую невозможно импортировать что-либо из его родительской директории.

Например, если бы нам пришлось запустить , то этот модуль не смог бы ничего импортировать из без вмешательства в или .

На первый взгляд может показаться, что относительные импорты (например ) помогут решить эту проблему. Однако запускаемый скрипт (в данном случае ) считается «модулем верхнего уровня». Попытка импортировать что-либо из директории над этим скриптом приведёт к ошибке .

Для решения этой проблемы лучше её не создавать и избегать написания скриптов, которые импортируют из родительской директории. Если этого нельзя избежать, то предпочтительным обходным путём является изменение .

Before Importing # Before Importing

If the file you’re importing is too large, your server may run out of memory when you import it. If this happens, you’ll see an error like “Fatal error: Allowed memory size of 8388608 bytes exhausted.”

If you have sufficient permissions on the server, you can edit the php.ini file to increase the available memory. Alternatively, you could ask your hosting provider to do this. Otherwise, you can edit your import file and save it as several smaller files, then import each one.

If your import process fails, it still may create some content. When you resolve the error and try again, you may create duplicate data. Review your site after a failed import and remove records as necessary to avoid this.

Using the content


Including an import on a page doesn’t mean «plop the content of that file here». It means «parser, go off an fetch this document so I can use it». To actually use the content, you have to take action and write script.

A critical moment is realizing that an import is just a document. In fact, the content of an import is called an import document. You’re able to manipulate the guts of an import using standard DOM APIs!

link.import

To access the content of an import, use the link element’s property:

is under the following conditions:

  • The browser doesn’t support HTML Imports.
  • The doesn’t have .
  • The has not been added to the DOM.
  • The has been removed from the DOM.
  • The resource is not CORS-enabled.

Full example

Let’s say contains:

Importers can grab a specific portion of this document and clone it into their page:

Scripting in imports

Imports are not in the main document. They’re satellite to it. However, your import can still act on the main page even though the main document reigns supreme. An import can access its own DOM and/or the DOM of the page that’s importing it:

Example — import.html that adds one of its stylesheets to the main page

Notice what’s going on here. The script inside the import references the imported document (), and appends part of that document to the importing page (). Pretty gnarly if you ask me.

Rules of JavaScript in an import:

  • Script in the import is executed in the context of the window that contains the importing . So refers to the main page document. This has two useful corollaries:
    • functions defined in an import end up on .
    • you don’t have to do anything crazy like append the import’s blocks to the main page. Again, script gets executed.
  • Imports do not block parsing of the main page. However, scripts inside them are processed in order. This means you get defer-like behavior while maintaining proper script order. More on this below.

Импорт *

Обычно мы располагаем список того, что хотим импортировать, в фигурных скобках , например вот так:

Но если импортировать нужно много чего, мы можем импортировать всё сразу в виде объекта, используя . Например:

На первый взгляд «импортировать всё» выглядит очень удобно, не надо писать лишнего, зачем нам вообще может понадобиться явно перечислять список того, что нужно импортировать?

Для этого есть несколько причин.

  1. Современные инструменты сборки (webpack и другие) собирают модули вместе и оптимизируют их, ускоряя загрузку и удаляя неиспользуемый код.

    Предположим, мы добавили в наш проект стороннюю библиотеку с множеством функций:

    Теперь, если из этой библиотеки в проекте мы используем только одну функцию:

    …Тогда оптимизатор увидит, что другие функции не используются, и удалит остальные из собранного кода, тем самым делая код меньше. Это называется «tree-shaking».

  2. Явно перечисляя то, что хотим импортировать, мы получаем более короткие имена функций: вместо .

  3. Явное перечисление импортов делает код более понятным, позволяет увидеть, что именно и где используется. Это упрощает поддержку и рефакторинг кода.

Caveats / Limitations

is not a

As a consequence, will be the main document, while of the imported children will be the itself. Consider using in these cases. e.g:

const ownerDoc = HTMLImports.importForElement(document.currentScript);
let someElement = ownerDoc.querySelector('some-element');
if (ownerDoc !== HTMLImports.importForElement(someElement)) {
  // This element is contained in another import, skip.
  someElement = null;
}

If you require document isolation, use .

Dynamic imports

The polyfill supports dynamically added imports by observing mutations in and within other imports; it won’t detect imports appended in .

If you require to append imports in , notify the polyfill of these additions using the method .

Imported stylesheets in IE/Edge

In IE/Edge, appending in a node that is not breaks the cascading order; the polyfill checks if an import contains a , and moves all the imported and to . It drops a placeholder element in their original place and assigns a reference to the applied element, . e.g.

imports a stylesheet and applies a style:

<link rel="stylesheet" href="my-linked-style.css">
<style> .blue { color: blue }; </style>

And is imported in index.html:

<head>
  <link rel="import" href="my-element.html">
</head>

This is how the resolved import will look like:

<head>
  <link rel="stylesheet" href="my-linked-style.css">
  <style> .blue { color: blue }; </style>
  <link rel="import" href="my-element.html">
    <link type="import-placeholder">
    <style type="import-placeholder"></style>
  </link>
</head>

The placeholders contain a reference to the applied element:

var myImport = document.head.querySelector('link').import;
var link = myImport.querySelector('link');
console.log(link.__appliedElement || link);
var style = myImport.querySelector('style');
console.log(style.__appliedElement || style);

Итого

Вот все варианты , которые мы разобрали в этой и предыдущей главах.

Вы можете проверить себя, читая их и вспоминая, что они означают:

  • Перед объявлением класса/функции/…:
  • Отдельный экспорт:
  • Реэкспорт:
    • (не реэкспортирует ).
    • (реэкспортирует только ).

Импорт:

  • Именованные экспорты из модуля:
  • Экспорт по умолчанию:
  • Всё сразу:
  • Только подключить модуль (его код запустится), но не присваивать его переменной:

Мы можем поставить в начало или в конец скрипта, это не имеет значения.

То есть, технически, такая запись вполне корректна:

На практике импорты, чаще всего, располагаются в начале файла. Но это только для большего удобства.

Обратите внимание, что инструкции import/export не работают внутри. Условный импорт, такой как ниже, работать не будет:

Условный импорт, такой как ниже, работать не будет:

…Но что, если нам в самом деле нужно импортировать что-либо в зависимости от условий? Или в определённое время? Например, загрузить модуль, только когда он станет нужен?

Мы рассмотрим динамические импорты в следующей главе.


С этим читают