modulr 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,7 +9,7 @@ in Ruby for client-side JavaScript. It accepts a singular file as input (the _pr
9
9
  which is does static analysis to recursively resolve its dependencies.
10
10
 
11
11
  The program, its dependencies and a small, namespaced JavaScript library are
12
- concatenated into a single `js` file. This improves load times by
12
+ concatenated into a single `js` file with optional minification through the [YUI Compressor](http://developer.yahoo.com/yui/compressor/). This improves load times by
13
13
  [minimizing HTTP requests](http://developer.yahoo.com/performance/rules.html#num_http).
14
14
  Further load time performance improvements are made possible by the built-in
15
15
  [lazy evaluation](http://googlecode.blogspot.com/2009/09/gmail-for-mobile-html5-series-reducing.html)
@@ -17,7 +17,12 @@ option. Modules are delivered as JavaScript strings--instead of functions--and a
17
17
  evaluated only when required.
18
18
 
19
19
  The bundled JavaScript library provides each module with the necessary `require`
20
- function and `exports` and `module` free variables.
20
+ function and `exports` and `module` free variables. In its full version, the bundled
21
+ library also provided support for the [`require.ensure`](http://wiki.commonjs.org/wiki/Modules/Async/A) (async module requires) and [`require.define`](http://wiki.commonjs.org/wiki/Modules/Transport/D) (module transport) methods.
22
+
23
+ `modulr` can also be used as a build tool for JavaScript code that will be executed in a regular JS environment. In this case, the global variable defined by the `--global-export` option is assigned the `exports` of the main CommonJS module and asynchronous module requires are not supported.
24
+
25
+ Finally, `modulr` allows you to create handy [dependency graphs](http://modulrjs.org/spec_dependency_graph.html).
21
26
 
22
27
  * [Github repository](http://github.com/codespeaks/modulr)
23
28
  * [Specification](http://wiki.commonjs.org/wiki/Modules/1.0)
@@ -36,9 +41,25 @@ To process a JavaScript source file, just run:
36
41
 
37
42
  $ modulrize filename.js > output.js
38
43
 
39
- For a comprehensive list of options:
40
-
41
- $ modulrize --help"
44
+ Options are as follows:
45
+
46
+ -o, --output=FILE Write the output to FILE. Defaults to stdout.
47
+ -r, --root=DIR Set DIR as root directory. Defaults to the directory containing FILE.
48
+ --lazy-eval [MODULES] Enable lazy evaluation of all JS modules or of those specified by MODULES.
49
+ MODULES accepts a comma-separated list of identifiers.
50
+ --minify Minify output using YUI Compressor.
51
+ --global-export=GLOBAL_VAR Export main module's exports to the GLOBAL_VAR global variable.
52
+ --sync Avoid using require.ensure.
53
+ --dependency-graph[=OUTPUT] Create a dependency graph of the module.
54
+ -h, --help Show this message.
55
+
56
+ Minification options (these are forwarded to YUI Compressor without the "minify-" prefix):
57
+
58
+ --minify-disable-optimizations Disable all micro optimizations.
59
+ --minify-nomunge Minify only, do not obfuscate.
60
+ --minify-verbose Display informational messages and warnings.
61
+ --minify-line-break COLUMN Insert a line break after the specified column number.
62
+ --minify-preserve-semi Preserve all semicolons.
42
63
 
43
64
  Specs
44
65
  -----
data/Rakefile CHANGED
@@ -18,11 +18,6 @@ task :build_sync_example do
18
18
  end
19
19
  end
20
20
 
21
- desc "Concatenate synchronous example file"
22
- task :test do
23
- Modulr.ize(File.join('example', 'program.js'))
24
- end
25
-
26
21
  desc "Run CommonJS Module 1.0 specs"
27
22
  task :spec do
28
23
  specs = ENV["SPECS"] || "**"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.5.0
@@ -35,6 +35,10 @@ opts = OptionParser.new do |opts|
35
35
  options[:global] = global
36
36
  end
37
37
 
38
+ opts.on('--sync', 'Load all dependencies synchronously.') do |global|
39
+ options[:sync] = true
40
+ end
41
+
38
42
  opts.on('--dependency-graph[=OUTPUT]', 'Create a dependency graph of the module.') do |output|
39
43
  options[:dependency_graph] = true
40
44
  options[:output] = output
@@ -87,5 +91,5 @@ begin
87
91
  output.print(result)
88
92
  end
89
93
  ensure
90
- output.close
94
+ output.close if output.respond_to?(:close)
91
95
  end
@@ -4,12 +4,10 @@ module Modulr
4
4
  $:.unshift(LIB_DIR)
5
5
  $:.unshift(PARSER_DIR)
6
6
 
7
- class ModulrError < StandardError
8
- end
9
-
10
7
  require 'modulr/js_module'
11
8
  require 'modulr/parser'
12
9
  require 'modulr/collector'
10
+ require 'modulr/sync_collector'
13
11
  require 'modulr/global_export_collector'
14
12
  require 'modulr/minifier'
15
13
  require 'modulr/dependency_graph'
@@ -22,6 +20,8 @@ module Modulr
22
20
  def self.ize(input_filename, options = {})
23
21
  if options[:global]
24
22
  collector = GlobalExportCollector.new(options)
23
+ elsif options[:sync]
24
+ collector = SyncCollector.new(options)
25
25
  else
26
26
  collector = Collector.new(options)
27
27
  end
@@ -12,7 +12,6 @@ module Modulr
12
12
  @src = File.read(path)
13
13
  @root ||= File.dirname(path)
14
14
  @main = JSModule.new(File.basename(path, '.js'), @root, path)
15
- modules << main
16
15
  collect_dependencies(main)
17
16
  end
18
17
 
@@ -0,0 +1,4 @@
1
+ module Modulr
2
+ class ModulrError < StandardError
3
+ end
4
+ end
@@ -1,5 +1,5 @@
1
1
  module Modulr
2
- class GlobalExportCollector < Collector
2
+ class GlobalExportCollector < SyncCollector
3
3
 
4
4
  def initialize(options = {})
5
5
  @global = options[:global]
@@ -1,3 +1,4 @@
1
+ require 'modulr/error'
1
2
  module Modulr
2
3
  class JSModule
3
4
  include Comparable
@@ -1,4 +1,5 @@
1
1
  require 'rkelly'
2
+ require 'modulr/error'
2
3
 
3
4
  module Modulr
4
5
  class Parser
@@ -25,7 +26,8 @@ module Modulr
25
26
  end
26
27
 
27
28
  def is_a_require_expression?(node)
28
- node.is_a?(RKelly::Nodes::FunctionCallNode) &&
29
+ (node.is_a?(RKelly::Nodes::FunctionCallNode) ||
30
+ node.is_a?(RKelly::Nodes::NewExprNode)) &&
29
31
  node.value.is_a?(RKelly::Nodes::ResolveNode) &&
30
32
  node.value.value == 'require'
31
33
  end
@@ -0,0 +1,16 @@
1
+ module Modulr
2
+ class SyncCollector < Collector
3
+ def parse_file(path)
4
+ super(path)
5
+ modules << main unless modules.include?(main)
6
+ end
7
+
8
+ def to_js(buffer = '')
9
+ buffer << "(function() {\n"
10
+ buffer << File.read(PATH_TO_MODULR_SYNC_JS)
11
+ buffer << transport
12
+ buffer << "\nrequire('#{main.id}');\n"
13
+ buffer << "})();\n"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,53 @@
1
+ require "test/unit"
2
+ $:.unshift(File.join('..', 'vendor', 'rkelly', 'lib'))
3
+ require "../lib/modulr/parser"
4
+
5
+ class TestLibModulrParser < Test::Unit::TestCase
6
+ def assert_found_module(name, src, message="")
7
+ @parser ||= Modulr::Parser.new
8
+ template = "Could not find module ? in JavaScript source code ?."
9
+ message = build_message(message, template, name, src)
10
+ assert_block(message) do
11
+ requires = @parser.get_require_expressions(src)
12
+ requires.first && requires.first[:identifier] == name
13
+ end
14
+ end
15
+
16
+ def test_simple_require_function
17
+ assert_found_module('foo', 'require("foo")')
18
+ end
19
+
20
+ def test_setting_variable
21
+ assert_found_module('foo', "var bar = require('foo');")
22
+ end
23
+
24
+ def test_accessing_property
25
+ assert_found_module('foo', "require('foo').bar;")
26
+ end
27
+
28
+ def test_accessing_nested_property
29
+ assert_found_module('foo', "require('foo').baz.bar;")
30
+ end
31
+
32
+ def test_calling_method
33
+ assert_found_module('foo', "require('foo').bar();")
34
+ end
35
+
36
+ def test_calling_nested_method
37
+ assert_found_module('foo', "require('foo').bar.baz();")
38
+ end
39
+
40
+ def test_instanciating_constructor
41
+ assert_found_module('foo', "new require('foo').Foo();")
42
+ assert_found_module('foo', "new require('foo').Foo;")
43
+ assert_found_module('foo', "new require('foo').Foo(1, 2, 3);")
44
+ assert_found_module('foo', "new (require('foo')).Foo();")
45
+ end
46
+
47
+ def test_instanciating_nested_constructor
48
+ assert_found_module('foo', "new require('foo').bar.Foo();")
49
+ assert_found_module('foo', "new require('foo').bar.Foo;")
50
+ assert_found_module('foo', "new require('foo').bar.Foo(1, 2, 3);")
51
+ assert_found_module('foo', "new (require('foo').bar).Foo();")
52
+ end
53
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 4
7
+ - 5
8
8
  - 0
9
- version: 0.4.0
9
+ version: 0.5.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Tobie Langel
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-13 00:00:00 +02:00
17
+ date: 2010-08-04 00:00:00 +02:00
18
18
  default_executable: modulrize
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -55,10 +55,12 @@ files:
55
55
  - lib/modulr.rb
56
56
  - lib/modulr/collector.rb
57
57
  - lib/modulr/dependency_graph.rb
58
+ - lib/modulr/error.rb
58
59
  - lib/modulr/global_export_collector.rb
59
60
  - lib/modulr/js_module.rb
60
61
  - lib/modulr/minifier.rb
61
62
  - lib/modulr/parser.rb
63
+ - lib/modulr/sync_collector.rb
62
64
  - lib/modulr/version.rb
63
65
  - vendor/rkelly/CHANGELOG.rdoc
64
66
  - vendor/rkelly/Manifest.txt
@@ -290,5 +292,5 @@ rubygems_version: 1.3.6
290
292
  signing_key:
291
293
  specification_version: 3
292
294
  summary: A CommonJS module implementation in Ruby for client-side JavaScript
293
- test_files: []
294
-
295
+ test_files:
296
+ - test/test_parser.rb