pombreda / base2

Automatically exported from code.google.com/p/base2
0 stars 0 forks source link

Javascript linker/builder #42

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I'm proposing a file-based builder, instead of the current package-based php 
build script. 

Let me explain. We get rid of all package.xml files. For every javascript file, 
we add "extended" 
comments to state the dependencies. For the file base2/DOM/init.js this will be:

//#uses "namespace,selector-api/Selector"

and the file base2/DOM/namespace.js needs to be updated with:

//#module "DOM"

The uses-statement will tell the linker (I'll call this new builder a linker) 
the file init.js is 
depended on two files. The module-statement will tell the linker to create a 
namespace object. 
The linker will actually replace the module-statement with the following:

var DOM = new base2.Namespace(this, {
    name:    "DOM",

So when we want to use the shortcut DOM.$ in our javascript file, we just add 
the statement 
#uses "DOM/init" to our file. This enables the use of the DOM.$ shortcut, with 
a very footprint. 
The linker will only include the necessary files (I'll leave the actually 
included files as an exercise 
to the reader).

One of the problems of the current build system is the fixed namespaces. Either 
you use the 
whole package, or you don't. Take the IO namespace for example. When a WebDAV 
file system is 
created, is it to be included in this namespace?

Somebody wanting to use the WebDAV file system is likely not to use the Local 
file system, and 
vice versa. Creating a separate namespace is not logical, because of the 
"abstract" classes. So a 
possible solution is to create the sub-namespaces IO.local and IO.WebDAV. The 
"abstract" IO 
classes stay in the IO namespace. But with this solution you get more and more 
namespace 
clutter in your code.

File size increases too. This might partially be solved by lazy loading. But 
often, lazy loading is 
"just too late" loading (in contrast with "just in time"). Users accept waiting 
a couple of seconds 
while a web-page loads. But when they press a button on a page, the expect 
near-instant 
action.

I think the current namespace/build system is quite handy, because it's a 
simple (simple as in 
good) system. But it doesn't scale too well.

This linker idea has not yet 100% crystalized yet, but let me fill in some more 
details. We also 
need a "requires" or "imports" and a "exports" statement, which can be used 
along with the 
"module" statement. The linker makes sure, the namespace object is declared 
correctly.

I still need to think about the file-name to object-name resolution. For 
simplicity, I've assumed 
one object per file, ignored directories a bit and omitted the javascript file 
extension. But I'm 
sure we can solve this.

Also, I don't have a 100% clear picture of the semantics of the statements. How 
do the publish 
and closure attributes of the package.xml map to the (just introduced) 
statements? Or do we 
actually need them? Should files be usable without a namespace, when there are 
no (#using) 
dependencies with a file defining a module-statement?

This needs further studying. I think this should be a team effort. But I think, 
this is the right time 
to debate this issue. But before we do that, the following.

As a bonus, including text files as a variables is more natural:

//#include "popupHtml=popup.html"

This will result in something like:

var popupHtml="<html>...</html>";

And it will be possible to add extended regular expressions (ecma script 4 
proposal) in a nice 
way (I'm working on a translator for that):

//#include "rfc822date=RegExtended(rfc822date.regex)";

To be clear: I don't want to build a Ant-like generic build system. The 
strategy is to only 
implement what we really need. And I think multi line RegExp's are really handy 
(you can do 
comments and named matches too). And also an automatic inclusion of the 
MIT-license might 
be an option. The linker should of course support native packing.

I don't think the linker should have knowledge of javascript itself. I see it 
as a preprocessor, like 
you know it from the C-language.

To conclude: the linker should be build with javascript, not php. We can 
provide for this with 
asp+javascript on Windows/IIS (I've written server-side javascript for years) 
and with 
Rhino+FastCGI for Apache, Lighttpd and others.

Another advantage of writing the linker with javascript: take this line from an 
HTML file:
  <script src="build.php?package=some/package.xml"></script>

When you commit this to subversion, the HTML stops working, because Google 
doesn't support 
server-side scripting. I think it's possible to fall back to client-side 
linking... (note: it's a pretty 
cool idea, but not really important to have).

This ends my idea frenzy. I'm interested to know what you think of all this.

Original issue reported on code.google.com by doek...@gmail.com on 23 Jul 2007 at 9:07

GoogleCodeExporter commented 9 years ago
This sounds great. Go ahead and build it. I like the idea that the linker is 
built in
JavaScript. The php stuff has always been a temporary hack.

Original comment by dean.edw...@gmail.com on 26 Jul 2007 at 5:21

GoogleCodeExporter commented 9 years ago
Are we ever going to implement this? :-)

Original comment by dean.edw...@gmail.com on 17 Aug 2008 at 3:59

GoogleCodeExporter commented 9 years ago
I still like the idea very much, but I don't see myself working on this this or 
next year...

Original comment by doek...@gmail.com on 18 Aug 2008 at 2:32

GoogleCodeExporter commented 9 years ago
Another approach would be using (X)HTML as a wrapper for Javascript, with
processing-instructions or link-elements to state dependencies, defines, etc. 

The advantages:
- your JS editor probably understands JS in HTML too
- The (X)HTML parser takes care of most of the parsing
- Reasonably easy to add features

I've been using this approach for over a year. A source file could look like 
this:
<?xml version="1.0"?>
<?xpl-param name="pkglibdir" value="{pkglibdir}"?>  
<?xpl-param name="pkgdefaultlibdir" value="{pkgdefaultlibdir}"?>  
<?xpl-require href="lib/Meeko/XBL.xhtml"?>
<?xpl-require href="HostRequest.xhtml"?>
<?xpl-prefetch href="{pkglibdir}/UI.js"?>
<?xpl-prefetch href="{pkglibdir}/UI.xml"?>
<?xpl-prefetch href="{pkglibdir}/WF2.xml"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script>
(function() {
    var pkglibdir = xplContext.params["pkglibdir"];
    var pkgdefaultlibdir = xplContext.params["pkgdefaultlibdir"];
    xplSystem.prefetch[pkgdefaultlibdir + '/UI.js'] = xplSystem.prefetch[pkglibdir +
'/UI.js'];
    xplSystem.prefetch[pkgdefaultlibdir + '/UI.xml'] = xplSystem.prefetch[pkglibdir +
'/UI.xml'];
    xplSystem.prefetch[pkgdefaultlibdir + '/WF2.xml'] = xplSystem.prefetch[pkglibdir +
'/WF2.xml'];
})();
    </script>
</head>
</html>

If you are interested I'd be happy to collaborate.

Original comment by shogu...@gmail.com on 12 Feb 2009 at 11:56

GoogleCodeExporter commented 9 years ago
There will be base2.require() and base2.exec() in base2 version 2.0.

Original comment by dean.edw...@gmail.com on 16 Feb 2010 at 3:30