Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Orion/Dependency resolution"

Line 1: Line 1:
 
''Dependency resolution'' refers to the ability to resolve a type of cross-file dependency to a file in the workspace at development time. Examples of dependencies within our scope are:
 
''Dependency resolution'' refers to the ability to resolve a type of cross-file dependency to a file in the workspace at development time. Examples of dependencies within our scope are:
* <tt>src</tt> and <tt>href</tt> attributes in an HTML file
+
* HTML files: <tt>src</tt> and <tt>href</tt> attributes
* <tt>@import</tt> statements and <tt>url( .. )</tt> in a CSS file
+
* CSS files: <tt>@import</tt> statements and <tt>url( .. )</tt>
* <tt>define([ deps.. ])</tt> and <tt>require([ deps.. ])</tt> in a JS file (AMD modules)
+
* JS files: <tt>define([ deps.. ])</tt> and <tt>require([ deps.. ])</tt> — '''AMD modules'''
* <tt>require( "dep/path" )</tt> in a JS file (Node.js/CommonJS)
+
* JS files: <tt>require( "dep/path" )</tt> — '''Node.js/CommonJS'''
* <tt>importScripts( urls.. )</tt> in a JS file (web worker API)
+
* JS files <tt>importScripts( urls.. )</tt> — '''web worker API'''
 +
**Note that importScripts' arguments are resolved relative to the '''calling script''''s location, which is '''not''' necessarily the same as <tt>window.location</tt>.
  
 
Dependency resolution is a prerequisite feature to cross-file type inference and content assist.  
 
Dependency resolution is a prerequisite feature to cross-file type inference and content assist.  
  
 
=== Minimally Useful Case ===
 
=== Minimally Useful Case ===
* Allow user to ctrl+click a CSS <tt>@import</tt> to open the imported file in an editor tab.
+
* Allow user to ctrl+click a CSS <tt>@import</tt> to open the imported file in an editor tab, if it is within the workspace.
  
 
=== Concepts ===
 
=== Concepts ===
 
* '''Dependency''': a reference to some ''logical path'' (LP).
 
* '''Dependency''': a reference to some ''logical path'' (LP).
 
* '''Logical path''' (LP): whatever goes inside the <tt>src="___"</tt>, <tt>@import "___"</tt>, <tt>require(___)</tt>, etc.
 
* '''Logical path''' (LP): whatever goes inside the <tt>src="___"</tt>, <tt>@import "___"</tt>, <tt>require(___)</tt>, etc.
** The LP is opaque to everything but a Resolver, which can translate LP to a workspace path.
+
** The LP is opaque to everything but a <tt>Resolver</tt>.
** Example: in JS, depending on the context, the LP can be a commonJS module path (Node.js), a path in the local file system (Node.js), a web path (browser/worker), or an AMD module ID.
+
** <tt>Resolver</tt> can map LP to a workspace path (WP), and vice-versa (?).
 +
** Example: in JS, depending on the context, an LP may be either a commonJS module path (Node.js), a path in the local file system (Node.js), a web path (browser/worker), or an AMD module ID.
 
* '''Resolver''': resolves a LP to a workspace path (WP).
 
* '''Resolver''': resolves a LP to a workspace path (WP).
** WPs can be fetched/parsed using the usual Orion FileClient API.
+
** WPs can be fetched/parsed using the usual Orion FileClient API. Thus they are tractable to the tooling, assuming the necessary APIs are exposed.
* '''Web Path Definition''' (WPD): captures the path-translation info necessary to map from an LP that is a web location.
+
* '''Web Path Config''' (WPC): captures the path-translation info necessary to map from an LP that is a web location.
** The notion of WPD is important because a resource's location on a web server is generally not the same as its location in the workspace. For example, a file located at a repo path of <tt>/src/webapp/static/js/foo.js</tt> may be exposed on the web as <tt>/admin/js/foo.js</tt>.
+
** The notion of WPC is important because a resource's location on a web server is generally not the same as its location in the workspace. For example, a file located at a repo path of <tt>/src/webapp/static/js/foo.js</tt> may be exposed on the web as <tt>/admin/js/foo.js</tt>. Dependencies will refer to the latter, not the former.
** The WPD
+
** The user must assist us in constructing the WPC. See how ReSharper<ref>http://blog.jetbrains.com/dotnet/2013/04/15/resharpers-web-path-mapping-explained/</ref> does it.
** The WPD is of interest to any Resolvers that may encounter web paths as LPs.  
+
** The WPC is of interest to any Resolvers that may encounter web paths as LPs.
** A WPD is a subset of the site structure defined by an Orion site configuration. Should factor out any commonality here.
+
** A WPC is a subset of the site structure defined by an Orion site configuration. (It's basically a site configuration that does not support REST API path mappings.) Should factor out any commonality here.
 +
** WPC should live at the project level, possibly inside <tt>project.json</tt>.
  
 
=== Questions (TODO) ===
 
=== Questions (TODO) ===
* What is the basic interface of Resolver?
+
* What is the basic interface of <tt>Resolver</tt>?
* What Resolver implementations do we need?
+
** <tt>toWorkspacePath(LP) &rarr; WP</tt>
* Which Resolvers leverage the WPD?
+
** <tt>toLogicalPath(WP) &rarr; LP</tt>
 +
* What implementations of <tt>Resolver</tt> do we need?  
 +
** GenericWebResolver, CommonJSResolver, AMDResolver extends GenericWebResolver...
 +
** Which Resolvers leverage the WPC?
 +
* What are the exact semantics/shape of a WPC?
 +
** In complex WPC's like Orion's, the map of LP:WP is likely 1:N. For example consider if both <tt>org.eclipse.orion.client.ui</tt> and <tt>org.eclipse.orion.client.core</tt> have a file named <tt>plugin.js</tt>. How to resolve ambiguity? Show an error?
 
* Do we expect a stanza present in JS files to distinguish whether Node.js resolution logic or AMD should be used? (eg. <tt>/*eslint-env amd*/</tt> versus <tt>/*eslint-env node*/</tt>).
 
* Do we expect a stanza present in JS files to distinguish whether Node.js resolution logic or AMD should be used? (eg. <tt>/*eslint-env amd*/</tt> versus <tt>/*eslint-env node*/</tt>).
* Expose a user action to select the '''root context''' (HTML file, JS script, etc) -- the base URL they're working against on the web.
+
* Should we expose a user action to select the '''root context''' (base HTML file, base JS script, etc) -- giving the base URL they're working against on the web.
  
 +
=== References ===
 +
<references />
  
 
[[Category:Orion]]
 
[[Category:Orion]]
 
[[Category:Orion/Tooling]]
 
[[Category:Orion/Tooling]]

Revision as of 12:07, 14 October 2014

Dependency resolution refers to the ability to resolve a type of cross-file dependency to a file in the workspace at development time. Examples of dependencies within our scope are:

  • HTML files: src and href attributes
  • CSS files: @import statements and url( .. )
  • JS files: define([ deps.. ]) and require([ deps.. ])AMD modules
  • JS files: require( "dep/path" )Node.js/CommonJS
  • JS files importScripts( urls.. )web worker API
    • Note that importScripts' arguments are resolved relative to the calling script's location, which is not necessarily the same as window.location.

Dependency resolution is a prerequisite feature to cross-file type inference and content assist.

Minimally Useful Case

  • Allow user to ctrl+click a CSS @import to open the imported file in an editor tab, if it is within the workspace.

Concepts

  • Dependency: a reference to some logical path (LP).
  • Logical path (LP): whatever goes inside the src="___", @import "___", require(___), etc.
    • The LP is opaque to everything but a Resolver.
    • Resolver can map LP to a workspace path (WP), and vice-versa (?).
    • Example: in JS, depending on the context, an LP may be either a commonJS module path (Node.js), a path in the local file system (Node.js), a web path (browser/worker), or an AMD module ID.
  • Resolver: resolves a LP to a workspace path (WP).
    • WPs can be fetched/parsed using the usual Orion FileClient API. Thus they are tractable to the tooling, assuming the necessary APIs are exposed.
  • Web Path Config (WPC): captures the path-translation info necessary to map from an LP that is a web location.
    • The notion of WPC is important because a resource's location on a web server is generally not the same as its location in the workspace. For example, a file located at a repo path of /src/webapp/static/js/foo.js may be exposed on the web as /admin/js/foo.js. Dependencies will refer to the latter, not the former.
    • The user must assist us in constructing the WPC. See how ReSharper[1] does it.
    • The WPC is of interest to any Resolvers that may encounter web paths as LPs.
    • A WPC is a subset of the site structure defined by an Orion site configuration. (It's basically a site configuration that does not support REST API path mappings.) Should factor out any commonality here.
    • WPC should live at the project level, possibly inside project.json.

Questions (TODO)

  • What is the basic interface of Resolver?
    • toWorkspacePath(LP) → WP
    • toLogicalPath(WP) → LP
  • What implementations of Resolver do we need?
    • GenericWebResolver, CommonJSResolver, AMDResolver extends GenericWebResolver...
    • Which Resolvers leverage the WPC?
  • What are the exact semantics/shape of a WPC?
    • In complex WPC's like Orion's, the map of LP:WP is likely 1:N. For example consider if both org.eclipse.orion.client.ui and org.eclipse.orion.client.core have a file named plugin.js. How to resolve ambiguity? Show an error?
  • Do we expect a stanza present in JS files to distinguish whether Node.js resolution logic or AMD should be used? (eg. /*eslint-env amd*/ versus /*eslint-env node*/).
  • Should we expose a user action to select the root context (base HTML file, base JS script, etc) -- giving the base URL they're working against on the web.

References

  1. http://blog.jetbrains.com/dotnet/2013/04/15/resharpers-web-path-mapping-explained/

Back to the top