Allen:
I agree with the assessment of entangling configuration management and module
management.
Both module specifications have this issue, although Ihab's package proposal
attempts to separate the two.
In the community, the commonjs syntax is 'require("./compiler/Lexer");' which
implicitly says to go get the
script at relative location ./compiler/Lexer.js, where a '.js' is appended to
the literal string.
This is an implicit rule which inherently ties configuration management with
module management.
BTW, string literal's (which are in both module specifications) doesn't work
well with combo handlers
used by Yahoo and others where a 'module' (defined to be a collection of script
files) is fetched
using the URL
'http://yui.yahooapis.com/combo?version/resource1.js&version/resource2.js&version/resource3.js'
The implicit rule would be to add '.js' to the above que
An approach taken by commonjs when specifying a string literal eg:
require('import/Lexer')
is to have a 'paths' property on the require function like
require.paths=["url1","url2","url3"];
which resembles java's class path mechanism where first found is first loaded.
Of course this assumes that the relative path is constant among the different
path entries.
An approach I had taken was to separate loading resources completely.
I use client-side websockets which communicate using a derived MessageEvent
that specifies
resources by name, mimetype, if-modified-since or etag. This is a 'pull'
mechanism where the client
asks for resources which are then used to create modules. These derived
MessageTypes would need to be specified
at the WebIDL (W3C) level and used by a module loader. Delegating resource
acquisition to an implementation
of the loader does decouple module management from configuration management,
there should be
MessageEvent's or JSON structures that module management can use when
evaluating resources fetched by the configuration management
system. This would be a great example of specifying the ecmascript mapping from
WebIDL.
kam
________________________________
From: Allen Wirfs-Brock <allen.wirfs-br...@microsoft.com>
To: "es-discuss@mozilla.org" <es-discuss@mozilla.org>
Sent: Sat, January 30, 2010 11:43:39 AM
Subject: simple modules: module managment vs. configuration management
There is quite a bit of literature on “2nd class”
module systems, but most of it is from a period before first class
modules became the primary modularity research interest. I’ll see
if I can dig up some references to papers that may be helpful.
One of the points that I recall is the importance of not
entangling “module management” with “configuration management”.
In this context, “module management” means structuring the
source code of a program into independent explicitly coupled pieces. This
is done to manage complexity, allow parallel or independent development,
simplify
maintenance, etc. “Configuration management” means controlling
and structuring the assembly instructions that describe how an actual runable
program
is instantiated as a composition of specific module instances. Configuration
management is about selecting which specific module versions from various
possible
alternatives and sources get bound together for execution.
As a more concrete example, a “program” might be
logically composed of 4 modules with import/export based dependencies:
module Main { …};
module Subsys { …};
module DB { …};
module yui3 {…};
To actually run this program you have to identify specific
versions of containers that contain the modules definitions (eg, which specific
files to load, which versions to load from a repository, which server to load
from, etc.). How configurations are specified is usually quite
specific to the actual mechanism used construct/instantiate executable
programs. It might be a makefile, or a manifest, or some other
declarative or imperative description. On the web, it might simply be the
set of script tags in a HTML document:
<script type='text/javascript”
src='/myapp/main/version2.js'>
<script type='text/javascript”
src='/myapp/subsys/version1.js'>
<script type=”text/javascript” src='/library/DB-2010.js'>
<script type=”text/javascript” src='http://developer.yahoo.com/modules/yui3.js'>
Module management becomes entangled with configuration management
when configuration management information is embedded within the actual module
definitions. When this occurs, configuration changes require the modification
of the actual source code of modules. For example, if a module import statement
uses a hard-code file path or server name then moving the location of an
imported module requires modification of every module that performs such an
import.
The simple module proposal has a couple places where this
sort of entanglement is possible. For example, from the samples:
import
'http://json.org/modules/json2.js' as JSON;
import 'http://developer.yahoo.com/modules/yui3.js#dom' as dom;
import “compiler/Lexer”;
if “compiler/Lexer”
is interpreted by the module id resolver as an actual access path
import
['JSON', 'http://json.org/modules/json2.js'] as JSON;
(but loadModule probably isn’t a problem. See note
below)
This is a problem even if the intent of the proposal is that
module ID’s are implementation dependent values and any concrete interpretation
is imposed by an implementation dependent module id resolver. As
the examples illustrate it is all too easy for module writers or a module id
resolver designers to decide to use the ModuleSpecifier string literal in a
configuration management like manner. The use of a string literal as
ModuleSpecifiers is an attractive nuisance that makes it too easy to entangle
module management and configuration management.
As an alternative my suggestions is that we completely avoid
using strings within ECMAScript source code to (statically) identify
modules. Instead, modules might be identified (in both Module declarations
and ImportDeclarations ) as any of the following alternatives 1) a simple
identifier, 2) a sequences of dot separated identifiers (my current
preference), or 3) a sequence of identifiers separated by some other delimiter
such as “::”. These identifiers populate a single module name
space that is distinct from the EnvironmentRecords used for normal identifier
resolution. The module name space gets populated in accordance with a specified
set of semantic rules by processing Module declarations contained within
Applications. The manner in which the actual containers (files, etc.) of the
Applications
for a specific program are identified would be completely implementation or
environment dependent.
(note about loadModule: I don’t see a problem
with loadModule using container/configuration information. By its very nature,
loadModule exists to support dynamic, open-ended program configuration.
(if you know the static module structure you shouldn’t need to use
loadModule.) In order to dynamically add modules to an inflight program you are
going to have to provide some sort of container or configuration information
and loadModule sees like a fine place to do so. However, while I think
that the semantics of dynamic processing a Module declaration (for example, via
eval…) needs to be well specified in the ECMAScript core semantics, it is
less clear to me that loadModule needs to be part of the standard
ECMAScript library. Externally locating and retrieving a container of an
Application declaration seems like an inherently implementation or environment
specific action and perhaps the definition of an API like loadModule should be
relegated to environment specific libraries (eg a browser API)).
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss