-
Notifications
You must be signed in to change notification settings - Fork 261
JEP Linker
This page describes linker process that will be used by cfx-js to build an add-on manifest. Linker will perform multiple iterations of graph refinements before reaching a final manifest format. Following sections describe iterations and expected results:
Linker takes add-on's root
path and entry
point module path (relative
to the add-on root
) as an arguments and starts building a graph for the
given module. Linker reads module source, and extracts requirements to
spit out stream of requirement nodes:
link('./main.js', './addon/')
<stream
{
requirement: './utils',
requirer: './main.js',
root: './addon/'
}
{
requirement: '@panel',
requirer: './main.js',
root: './addon/'
}
{
requirement: '@devtools/scratchpad',
requirer: './main.js',
root: './addon/'
}
{
requirement: 'fs',
requirer: './main.js',
root: './addon'
}
{
requirement: 'tabs',
requirer: './main.js',
root: './addon',
}
{
requirement: 'foo/bar',
requirer: './main.js',
root: './addon'
}
/>
In this iteration node of the generate graph are expanded to include information about requirement type ('local', 'system', 'remote') and expected paths:
<stream
{
requirement: './utils',
requirer: './main.js',
root: './addon/',
type: 'local',
path: './utils.js'
}
{
requirement: '@panel',
requirer: './main.js',
root: './addon/'
type: 'system',
path: './std/panel.js'
}
{
requirement: '@devtools/scratchpad',
requirer: './main.js',
root: './addon/,
type: 'system',
path: './devtools/scratchpad.js'
}
{
requirement: 'fs',
requirer: './main.js',
root: './addon',
type: 'external',
path: './fs.js'
}
{
requirement: 'tabs',
requirer: './main.js',
root: './addon',
type: 'external',
path: './tabs.js'
}
{
requirement: 'foo/bar',
requirer: './main.js',
root: './addon',
type: 'external',
path: './foo/bar.js'
}
/>
Note: path
on 'local' and 'external' nodes are relative to add-on
root
. For 'system' nodes it is relative to an add-on SDK lib
.
In this iteration linker locates module requirements from graph in the filesystem. This process is type specific, so requirements grpah is fork-joined by a node types.
Local requirements are located under the node path
relative to the
add-on root. Nodes are expanded with an information of file existence:
<stream
{
requirement: './utils',
requirer: './main.js',
root: './addon/',
type: 'local',
path: './utils.js',
located: true
}
/>
System requirements are located under the node path
relative to the
add-on SDK lib
. Nodes are expanded with an information of file
existence:
<stream
{
requirement: '@panel',
requirer: './main.js',
root: './addon/'
type: 'system',
path: './sdk/panel.js',
located: true
}
{
requirement: '@devtools/scratchpad',
requirer: './main.js',
root: './addon/,
type: 'system',
path: './devtools/scratchpad.js',
located: false
}
/>
External dependencies are located under under the node path
relative
to @modules
directory in an add-on root
. Nodes are expanded with an
information of file existence:
<stream { requirement: 'fs', requirer: './main.js', root: './addon', type: 'external', path: './fs.js', located: true } { requirement: 'tabs', requirer: './main.js', root: './addon', type: 'external', path: './tabs.js', located: false } { requirement: 'foo/bar', requirer: './main.js', root: './addon', type: 'external', path: './foo/bar.js', located: false } />
In this iteration graph is fork-joined for nodes that were not
located (node located
is false
). Graph is also fork-joined by
node type
.
If graph contains local dependency that was not located, linker exits with error that says that given requirement for the given module is missing.
For system modules we log a message that says that add-on will expect to have a given module in the system.
On missing remote modules we make several attempt of locating them only for backwards compatibility:
Assuming that user meant system module we fork-join sub-graph to
refine nodes that meant system modules instead. If modules are
discovered in add-on SDK lib
node's are expanded with an
appropriate information:
{
requirement: 'tabs',
requirer: './main.js',
root: './addon',
type: 'deprecated',
correction: { type: 'system', requirement: '@tabs' },
path: './sdk/tabs.js',
located: true
}
Assuming that user meant local module we fork-join sub-graph to
refine nodes that meant system modules instead. If modules are
discovered in add-on SDK lib
node's are expanded with an
appropriate information:
{ requirement: 'foo/bar', requirer: './main.js', root: './addon', type: 'deprecated', correction: { type: 'local', requirement: './foo/bar' }, path: './foo/bar.js', located: true }
If we run linker for test mode we fork-join sub-graph to refine
nodes that could have being discovered if we were running cfx test
in older cfx-py. If node path
exists relative to add-on root we
we enhance node accordingly.