// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtqml-modules-identifiedmodules.html
\title Identified Modules
\brief Creating and importing identified modules

Identified modules are modules that are installed and identifiable to the QML
engine by a URI in the form of a dotted identifier string, which should be
specified by the module in its \c qmldir file.  This enables such modules to
be imported with a unique identifier that remains the same no matter where the
module is located on the local file system.

When importing an identified module, an unquoted identifier is used, with an
optional version number:

\snippet qml/imports/installed-module.qml imports

Identified modules must be installed into the
\l{qtqml-syntax-imports.html#qml-import-path}{import path} in order to be found
by the QML engine.

Syntactically, each dot-separated segment of the URI must be a well-formed
ECMAScript Identifier Name. This means, for example, the segments must not start
with a number and they must not contain \e{-} (minus) characters. As the URI
will be translated into directory names, you should restrict it to alphanumeric
characters of the latin alphabet, underscores, and dots.

\section1 Locally Installed Identified Modules

A directory of QML and/or C++ files can be shared as an identified module if it
contains a \l{qtqml-modules-qmldir.html}{qmldir file} with the module metadata
and is installed into the QML import path.  Any QML file on the local file
system can import this directory as a module by using an
\l{qtqml-syntax-imports.html}{import} statement that refers to the module's
URI, enabling the file to use the \l{qtqml-typesystem-objecttypes.html}
{QML object types} and \l{qtqml-javascript-resources.html}
{JavaScript resources} defined by the module.

The module's \c qmldir file must reside in a directory structure within the
\l{qtqml-syntax-imports.html#qml-import-path}{import path} that reflects the
URI dotted identifier string, where each dot (".") in the identifier reflects
a sub-level in the directory tree. For example, the \c qmldir file of the
module \c com.mycompany.mymodule must be located in the sub-path
\c com/mycompany/mymodule/qmldir somewhere in the
\l{qtqml-syntax-imports.html#qml-import-path}{import path}.

It is possible to store different versions of a module in subdirectories of its
own. For example, a version 2.1 of a module could be located under
\c com/mycompany/mymodule.2/qmldir or \c com/mycompany/mymodule.2.1/qmldir.
The engine will automatically load the module which matches best.

Alternatively, versioning for different types can be defined within a qmldir
file itself, however this can make updating such a module more difficult (as a
\c qmldir file merge must take place as part of the update procedure).


\section2 An Example

Consider the following QML project directory structure. Under the top level
directory \c myapp, there are a set of common UI components in a sub-directory
named \c mycomponents, and the main application code in a sub-directory named
\c main, like this:

\code
myapp
    |- mycomponents
        |- CheckBox.qml
        |- DialogBox.qml
        |- Slider.qml
    |- main
        |- application.qml
\endcode

To make the \c mycomponents directory available as an identified module, the
directory must include a \l{qtqml-modules-qmldir.html}{qmldir file} that
defines the module identifier, and describes the object types made available by
the module. For example, to make the \c CheckBox, \c DialogBox and \c Slider
types available for version 1.0 of the module, the \c qmldir file would contain
the following:

\code
module myapp.mycomponents
CheckBox 1.0 CheckBox.qml
DialogBox 1.0 DialogBox.qml
Slider 1.0 Slider.qml
\endcode

Additionally, the location of the \c qmldir file in the
\l{qtqml-syntax-imports.html#qml-import-path}{import path} must match the
module's dotted identifier string. So, say the top level \c myapp directory is
located in \c C:\qml\projects, and say the module should be identified as
"myapp.mycomponents". In this case:

\list
\li The path \c C:\qml\projects should be added to the
    \l{qtqml-syntax-imports.html#qml-import-path}{import path}
\li The qmldir file should be located under \c C:\qml\projects\myapp\mycomponents\qmldir
\endlist

Once this is done, a QML file located anywhere on the local filesystem can
import the module by referring to its URI and the appropriate version:

\qml
import myapp.mycomponents 1.0

DialogBox {
    CheckBox {
        // ...
    }
    Slider {
        // ...
    }
}
\endqml

\section1 Remotely Installed Identified Modules

Identified modules are also accessible as a network resource. In the previous
example, if the \c C:\qml\projects directory was hosted as
\c http://www.some-server.com/qml/projects and this URL was added to the QML
import path, the module could be imported in exactly the same way.

Note that when a file imports a module over a network, it can only access QML
and JavaScript resources provided by the module; it cannot access any types
defined by C++ plugins in the module.


\section1 Semantics of Identified Modules

An identified module is provided with the following guarantees by the QML
engine:
\list
\li other modules are unable to modify or override types in the module's
    namespace
\li other modules are unable to register new types into the module's
    namespace
\li usage of type names by clients will resolve deterministically to a given
    type definition depending on the versioning specified and the import order
\endlist

This ensures that clients which use the module can be certain that the
object types defined in the module will behave as the module author documented.

An identified module has several restrictions upon it:
\list
\li an identified module must be installed into the
    \l{qtqml-syntax-imports.html#qml-import-path}{QML import path}
\li the module identifier specified in the \l{qtqml-modules-qmldir.html}
    {module identifier directive} must match the install path of the module
    (relative to the QML import path, where directory separators are replaced
    with period characters)
\li the module must register its types into the module identifier type
    namespace
\li the module may not register types into any other module's namespace
\endlist

For example, if an identified module is installed into
\c{$QML_IMPORT_PATH/ExampleModule}, the module identifier directive must be:
\code
module ExampleModule
\endcode

If the strict module is installed into
\c{$QML_IMPORT_PATH/com/example/CustomUi}, the module identifier directive
must be:
\code
module com.example.CustomUi
\endcode

Clients will then be able to import the above module with the following import
statement:
\qml
import com.example.CustomUi
\endqml

\sa {Modernizing QML Modules}, {Port QML modules to CMake}
*/
