modulr 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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