nibjs 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +45 -0
- data/LICENCE.js +7 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +16 -0
- data/README.md +64 -0
- data/Rakefile +53 -0
- data/bin/nibjs +4 -0
- data/lib/nibjs/loader.rb +2 -0
- data/lib/nibjs/main.rb +288 -0
- data/lib/nibjs/version.rb +14 -0
- data/lib/nibjs.rb +9 -0
- data/nibjs.gemspec +194 -0
- data/nibjs.noespec +41 -0
- data/src/nibjs.coffee +124 -0
- data/tasks/debug_mail.rake +78 -0
- data/tasks/debug_mail.txt +13 -0
- data/tasks/dist.rake +14 -0
- data/tasks/gem.rake +68 -0
- data/tasks/test.rake +72 -0
- data/tasks/yard.rake +51 -0
- data/test/command/header.js +1 -0
- data/test/command/nibjs_spec.rb +52 -0
- data/test/command/run.rb +3 -0
- data/test/command/sc_coffee_1.exp +31 -0
- data/test/command/sc_coffee_2.exp +26 -0
- data/test/command/sc_coffee_3.exp +25 -0
- data/test/command/sc_coffee_4.exp +26 -0
- data/test/command/sc_coffee_5.exp +24 -0
- data/test/command/sc_common_0.exp +31 -0
- data/test/command/sc_common_1.exp +31 -0
- data/test/command/sc_common_2.exp +32 -0
- data/test/command/sc_common_3.exp +32 -0
- data/test/command/sc_common_4.exp +1 -0
- data/test/command/sc_common_5.exp +1 -0
- data/test/command/scenarios.rb +73 -0
- data/test/fixture.coffee/app.coffee +6 -0
- data/test/fixture.coffee/dependent.coffee +8 -0
- data/test/fixture.coffee/index.coffee +3 -0
- data/test/fixture.js/app.js +9 -0
- data/test/fixture.js/dependent.js +10 -0
- data/test/fixture.js/index.js +3 -0
- data/test/fixture.min.js +28 -0
- data/test/integration/index.html +42 -0
- data/test/integration/integration_test.coffee +29 -0
- data/test/integration/integration_test.js +34 -0
- data/test/integration/integration_test.rb +37 -0
- data/test/integration/jquery-1.4.4.min.js +167 -0
- data/test/jasmine/nibjs_spec.coffee +31 -0
- data/test/jasmine/run.coffee +14 -0
- data/test/nibjs.js +74 -0
- metadata +325 -0
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
nibjs (1.0.0)
|
5
|
+
bundler (~> 1.0)
|
6
|
+
quickl (~> 0.2.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
bluecloth (2.0.10)
|
12
|
+
diff-lcs (1.1.2)
|
13
|
+
quickl (0.2.0)
|
14
|
+
rack (1.2.1)
|
15
|
+
rake (0.8.7)
|
16
|
+
rcov (0.9.9)
|
17
|
+
rspec (2.4.0)
|
18
|
+
rspec-core (~> 2.4.0)
|
19
|
+
rspec-expectations (~> 2.4.0)
|
20
|
+
rspec-mocks (~> 2.4.0)
|
21
|
+
rspec-core (2.4.0)
|
22
|
+
rspec-expectations (2.4.0)
|
23
|
+
diff-lcs (~> 1.1.2)
|
24
|
+
rspec-mocks (2.4.0)
|
25
|
+
sinatra (1.1.2)
|
26
|
+
rack (~> 1.1)
|
27
|
+
tilt (~> 1.2)
|
28
|
+
tilt (1.2.2)
|
29
|
+
wlang (0.10.1)
|
30
|
+
yard (0.6.4)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
bluecloth (~> 2.0.9)
|
37
|
+
bundler (~> 1.0)
|
38
|
+
nibjs!
|
39
|
+
quickl (~> 0.2.0)
|
40
|
+
rake (~> 0.8.7)
|
41
|
+
rcov (~> 0.9)
|
42
|
+
rspec (~> 2.4.0)
|
43
|
+
sinatra (> 0)
|
44
|
+
wlang (~> 0.10.1)
|
45
|
+
yard (~> 0.6.4)
|
data/LICENCE.js
ADDED
data/LICENCE.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# The MIT Licence
|
2
|
+
|
3
|
+
Copyright (c) 2011 - Bernard Lambeau
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
# NibJS
|
2
|
+
|
3
|
+
nib.js - Package and embed node.js or coffeescript libraries in the browser
|
4
|
+
|
5
|
+
nib.js is a NibJS javascript library allowing to maintain javascript/coffeescript projects
|
6
|
+
ala 'node.js' (modules, exports, require) while also targetting a web browser as execution
|
7
|
+
platform. It contains a simple packager command (nibjs) that will convert your sources to a
|
8
|
+
single and minified .js file to be embedded in the browser. Node.js's exports and require
|
9
|
+
are correctly bounded.
|
10
|
+
|
11
|
+
## Getting started
|
12
|
+
|
13
|
+
gem install nibjs
|
14
|
+
nibjs --help
|
15
|
+
|
16
|
+
## How to use it
|
17
|
+
|
18
|
+
Let assume that your project has the structure below.
|
19
|
+
|
20
|
+
mylib/
|
21
|
+
dist/
|
22
|
+
src/
|
23
|
+
foo.[js,coffee] # exports.Foo = ...
|
24
|
+
bar.[js,coffee] # require('./foo')
|
25
|
+
index.[js,coffee] # exports.X = ...
|
26
|
+
spec/
|
27
|
+
foo_spec.[js,coffee]
|
28
|
+
bar_spec.[js,coffee]
|
29
|
+
package.json
|
30
|
+
|
31
|
+
### EXAMPLE 1 (embedded javascript):
|
32
|
+
|
33
|
+
In a shell:
|
34
|
+
|
35
|
+
# if the sources are .js
|
36
|
+
nibjs --libname=mylib --output=mylib.js src
|
37
|
+
|
38
|
+
# if the sources are .coffee
|
39
|
+
nibjs --coffee --libname=mylib --output=mylib.js src
|
40
|
+
|
41
|
+
In the browser:
|
42
|
+
|
43
|
+
<script src="js/nibjs.js" type="text/javascript">
|
44
|
+
<script src="js/mylib.js" type="text/javascript">
|
45
|
+
<script>
|
46
|
+
var mylib = NibJS.require('mylib')
|
47
|
+
</script>
|
48
|
+
|
49
|
+
### EXAMPLE 2 (embedded coffeescript):
|
50
|
+
|
51
|
+
In a shell:
|
52
|
+
|
53
|
+
nibjs --coffee --no-coffee-compile --libname=mylib --output=mylib.coffee src
|
54
|
+
|
55
|
+
In the browser:
|
56
|
+
|
57
|
+
<script src="js/coffee-script.js" type="text/javascript">
|
58
|
+
<script src="js/nibjs.js" type="text/javascript">
|
59
|
+
<script src="js/mylib.coffee" type="text/coffeescript">
|
60
|
+
<script>
|
61
|
+
/* But be warned of coffeescript's issue 1054
|
62
|
+
https://github.com/jashkenas/coffee-script/issues/#issue/1054 */
|
63
|
+
var mylib = NibJS.require('mylib')
|
64
|
+
</script>
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
begin
|
2
|
+
gem "bundler", "~> 1.0"
|
3
|
+
require "bundler/setup"
|
4
|
+
rescue LoadError => ex
|
5
|
+
puts ex.message
|
6
|
+
abort "Bundler failed to load, (did you run 'gem install bundler' ?)"
|
7
|
+
end
|
8
|
+
|
9
|
+
# Runs a command, returns result on STDOUT. If the exit status was no 0,
|
10
|
+
# a RuntimeError is raised.
|
11
|
+
def shell_safe_exec(cmd)
|
12
|
+
puts cmd
|
13
|
+
unless system(cmd)
|
14
|
+
raise RuntimeError, "Error while executing #{cmd}"
|
15
|
+
end
|
16
|
+
$?
|
17
|
+
end
|
18
|
+
|
19
|
+
def _(path)
|
20
|
+
File.join(File.dirname(__FILE__), path)
|
21
|
+
end
|
22
|
+
|
23
|
+
def dist(target)
|
24
|
+
shell_safe_exec("cat src/nibjs.coffee | coffee --bare --compile --stdio > #{target}")
|
25
|
+
code = ""
|
26
|
+
code += File.read("LICENCE.js")
|
27
|
+
code += "(function(exports){\n"
|
28
|
+
code += File.read(target).gsub(/^/m, " ")
|
29
|
+
code += "}).call(this, this)"
|
30
|
+
File.open(target, "w"){|io| io << code}
|
31
|
+
end
|
32
|
+
|
33
|
+
def nibjs(*args)
|
34
|
+
nibjs = _('bin/nibjs')
|
35
|
+
shell_safe_exec "#{nibjs} #{args.flatten.join(' ')}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# Dynamically load the gem spec
|
39
|
+
$gemspec_file = File.expand_path('../nibjs.gemspec', __FILE__)
|
40
|
+
$gemspec = Kernel.eval(File.read($gemspec_file))
|
41
|
+
|
42
|
+
# We run tests by default
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
#
|
46
|
+
# Install all tasks found in tasks folder
|
47
|
+
#
|
48
|
+
# See .rake files there for complete documentation.
|
49
|
+
#
|
50
|
+
Dir["tasks/*.rake"].each do |taskfile|
|
51
|
+
instance_eval File.read(taskfile), taskfile
|
52
|
+
end
|
53
|
+
|
data/bin/nibjs
ADDED
data/lib/nibjs/loader.rb
ADDED
data/lib/nibjs/main.rb
ADDED
@@ -0,0 +1,288 @@
|
|
1
|
+
require 'nibjs'
|
2
|
+
module NibJS
|
3
|
+
#
|
4
|
+
# nibjs - Package and embed node.js/coffeescript application in your browser
|
5
|
+
#
|
6
|
+
# SYNOPSIS
|
7
|
+
# #{program_name} [--help] [--version] [FOLDER]
|
8
|
+
#
|
9
|
+
# OPTIONS
|
10
|
+
# #{summarized_options}
|
11
|
+
#
|
12
|
+
# DESCRIPTION
|
13
|
+
# This command packages a complete javascript/coffeescript as a single .js file
|
14
|
+
# to be embedded in the browser. Basically, it defines Node.js's exports and
|
15
|
+
# require to work nicely. For this, we expect a project structure that respect
|
16
|
+
# Node.js's package conventions (exports, require, index):
|
17
|
+
#
|
18
|
+
# mylib/
|
19
|
+
# dist/
|
20
|
+
# src/
|
21
|
+
# foo.[js,coffee] # exports.Foo = ...
|
22
|
+
# bar.[js,coffee] # require('./foo')
|
23
|
+
# index.[js,coffee] # exports.X = ...
|
24
|
+
# spec/
|
25
|
+
# foo_spec.[js,coffee]
|
26
|
+
# bar_spec.[js,coffee]
|
27
|
+
#
|
28
|
+
# EXAMPLE 1 (embedded javascript):
|
29
|
+
#
|
30
|
+
# In a shell:
|
31
|
+
#
|
32
|
+
# # if the sources are .js
|
33
|
+
# nibjs --libname=mylib --output=mylib.js src
|
34
|
+
#
|
35
|
+
# # if the sources are .coffee
|
36
|
+
# nibjs --coffee --libname=mylib --output=mylib.js src
|
37
|
+
#
|
38
|
+
# In the browser:
|
39
|
+
#
|
40
|
+
# <script src="js/coffee-script.js" type="text/javascript">
|
41
|
+
# <script src="js/nibjs.js" type="text/javascript">
|
42
|
+
# <script src="js/mylib.js" type="text/javascript">
|
43
|
+
# <script>
|
44
|
+
# var mylib = NibJS.require('mylib')
|
45
|
+
# </script>
|
46
|
+
#
|
47
|
+
# EXAMPLE 2 (embedded coffeescript):
|
48
|
+
#
|
49
|
+
# In a shell:
|
50
|
+
#
|
51
|
+
# nibjs --coffee --no-coffee-compile --libname=mylib --output=mylib.coffee src
|
52
|
+
#
|
53
|
+
# In the browser:
|
54
|
+
#
|
55
|
+
# <script src="js/nibjs.js" type="text/javascript">
|
56
|
+
# <script src="js/mylib.coffee" type="text/coffeescript">
|
57
|
+
# <script>
|
58
|
+
# /* But be warned of coffeescript's issue 1054
|
59
|
+
# https://github.com/jashkenas/coffee-script/issues/#issue/1054 */
|
60
|
+
# var mylib = NibJS.require('mylib')
|
61
|
+
# </script>
|
62
|
+
#
|
63
|
+
class Main < Quickl::Command(__FILE__, __LINE__)
|
64
|
+
|
65
|
+
# Name of the library which is packaged
|
66
|
+
attr_accessor :libname
|
67
|
+
|
68
|
+
# Look for .coffee files
|
69
|
+
attr_accessor :coffee
|
70
|
+
|
71
|
+
# Compile .coffee files
|
72
|
+
attr_accessor :coffee_compile
|
73
|
+
|
74
|
+
# Join the sources instead of treating them separately
|
75
|
+
attr_accessor :join
|
76
|
+
|
77
|
+
# Invoke ugligyjs on result
|
78
|
+
attr_accessor :uglify
|
79
|
+
|
80
|
+
# Add 'libname = NibJS.require(libname)' at end of script
|
81
|
+
attr_accessor :autorequire
|
82
|
+
|
83
|
+
# Path to a licencing file to add as header
|
84
|
+
attr_accessor :header
|
85
|
+
|
86
|
+
# IO or filename where to output result
|
87
|
+
attr_accessor :output
|
88
|
+
|
89
|
+
def initialize
|
90
|
+
@output = STDOUT
|
91
|
+
end
|
92
|
+
|
93
|
+
# Install options
|
94
|
+
options do |opt|
|
95
|
+
@libname = nil
|
96
|
+
opt.on("--libname=X", "Specify the main library name") do |value|
|
97
|
+
@libname = value
|
98
|
+
end
|
99
|
+
@autorequire = false
|
100
|
+
opt.on('-a','--autorequire', "Add 'libname = NibJS.require(libname)' at end of script") do
|
101
|
+
@autorequire = true
|
102
|
+
end
|
103
|
+
@coffee = false
|
104
|
+
opt.on("-c", "--coffee", "Look for .coffee instead of .js files (requires coffee)") do
|
105
|
+
@coffee = true
|
106
|
+
end
|
107
|
+
@coffee_compile = true
|
108
|
+
opt.on("--[no-]coffee-compile", "Compile .coffee sources to javascript (requires coffee)") do |value|
|
109
|
+
@coffee_compile = value
|
110
|
+
end
|
111
|
+
@join = false
|
112
|
+
opt.on('-j', '--join', "Join the sources instead of treating them separately") do |value|
|
113
|
+
@join = true
|
114
|
+
end
|
115
|
+
@uglify = false
|
116
|
+
opt.on('-u', '--[no-]uglify', "Invoke ugligyjs on result (requires uglifyjs)") do |value|
|
117
|
+
@uglify = value
|
118
|
+
end
|
119
|
+
opt.separator('')
|
120
|
+
@header = nil
|
121
|
+
opt.on("--header=FILE", "Add a (licencing) header from a file") do |value|
|
122
|
+
@header = value
|
123
|
+
end
|
124
|
+
#@output = STDOUT
|
125
|
+
opt.on("-o", "--output=FILE", "Output in a specific file") do |value|
|
126
|
+
@output = value
|
127
|
+
end
|
128
|
+
opt.on_tail("--help", "Show help") do
|
129
|
+
raise Quickl::Help
|
130
|
+
end
|
131
|
+
opt.on_tail("--version", "Show version") do
|
132
|
+
raise Quickl::Exit, "#{program_name} #{NibJS::VERSION} (c) 2011, Bernard Lambeau"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
### In coffee
|
137
|
+
|
138
|
+
def with_coffee_registration(file)
|
139
|
+
code = ""
|
140
|
+
code += "nibjs.register '#{file}', (exports, require)->\n"
|
141
|
+
code += yield.strip.gsub(/^/m, ' ') + "\n"
|
142
|
+
code += "\n"
|
143
|
+
end
|
144
|
+
|
145
|
+
def with_coffee_define(package)
|
146
|
+
code = ""
|
147
|
+
code += "NibJS.define '#{package}', (nibjs)->\n"
|
148
|
+
code += yield.strip.gsub(/^/m, ' ') + "\n"
|
149
|
+
code += "\n"
|
150
|
+
code += " nibjs.require './index'\n"
|
151
|
+
end
|
152
|
+
|
153
|
+
### In javascript
|
154
|
+
|
155
|
+
def with_js_registration(file)
|
156
|
+
code = ""
|
157
|
+
code += "nibjs.register('#{file}', function(exports, require) {\n"
|
158
|
+
code += yield.strip.gsub(/^/m, ' ') + "\n"
|
159
|
+
code += "});\n"
|
160
|
+
end
|
161
|
+
|
162
|
+
def with_js_define(package)
|
163
|
+
code = ""
|
164
|
+
code += "NibJS.define('#{package}', function(nibjs) {\n"
|
165
|
+
code += yield.strip.gsub(/^/m, ' ') + "\n"
|
166
|
+
code += " return nibjs.require('./index');\n"
|
167
|
+
code += "});\n"
|
168
|
+
end
|
169
|
+
|
170
|
+
###
|
171
|
+
|
172
|
+
# Runs a command, returns result on STDOUT. If the exit status was no 0,
|
173
|
+
# a RuntimeError is raised.
|
174
|
+
def safe_run(cmd)
|
175
|
+
res = `#{cmd}`
|
176
|
+
unless $?.exitstatus == 0
|
177
|
+
raise RuntimeError, "Error while executing #{cmd}"
|
178
|
+
end
|
179
|
+
res
|
180
|
+
end
|
181
|
+
|
182
|
+
def with_temp_file(content)
|
183
|
+
require "tempfile"
|
184
|
+
file = Tempfile.new('nibjs')
|
185
|
+
file << content
|
186
|
+
file.close
|
187
|
+
res = yield(file)
|
188
|
+
file.unlink
|
189
|
+
res
|
190
|
+
end
|
191
|
+
|
192
|
+
###
|
193
|
+
|
194
|
+
def file2require(root_folder, file)
|
195
|
+
root_folder, file = File.expand_path(root_folder), File.expand_path(file)
|
196
|
+
stripped = file[(1+root_folder.size)..-1]
|
197
|
+
stripped =~ /(.*)\.(js|coffee)$/
|
198
|
+
"./#{$1}"
|
199
|
+
end
|
200
|
+
|
201
|
+
###
|
202
|
+
|
203
|
+
def collect_on_files(folder)
|
204
|
+
files = if coffee
|
205
|
+
Dir["#{folder}/**/*.coffee"]
|
206
|
+
else
|
207
|
+
Dir["#{folder}/**/*.js"]
|
208
|
+
end
|
209
|
+
if join
|
210
|
+
files.sort!
|
211
|
+
content = files.collect{|f| File.read(f)}.join("\n")
|
212
|
+
[ with_temp_file(content){|f| yield(f.path, './index')} ]
|
213
|
+
else
|
214
|
+
files.collect{|f| yield(f, file2require(folder, f))}
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def compile_coffee_source(code)
|
219
|
+
with_temp_file(code){|f|
|
220
|
+
safe_run("cat #{f.path} | coffee --compile --stdio --bare")
|
221
|
+
}
|
222
|
+
end
|
223
|
+
|
224
|
+
def compile(folder)
|
225
|
+
folder = File.expand_path(folder)
|
226
|
+
self.libname ||= File.basename(folder)
|
227
|
+
if self.libname =~ /(.*)\.\w/
|
228
|
+
self.libname = $1
|
229
|
+
end
|
230
|
+
|
231
|
+
code = if coffee
|
232
|
+
code = with_coffee_define(libname){
|
233
|
+
collect_on_files(folder){|filepath, reqname|
|
234
|
+
with_coffee_registration(reqname){ File.read(filepath) }
|
235
|
+
}.join
|
236
|
+
}
|
237
|
+
if coffee_compile
|
238
|
+
compile_coffee_source(code)
|
239
|
+
else
|
240
|
+
code
|
241
|
+
end
|
242
|
+
else
|
243
|
+
with_js_define(libname){
|
244
|
+
collect_on_files(folder){|filepath, reqname|
|
245
|
+
with_js_registration(reqname){ File.read(filepath) }
|
246
|
+
}.join
|
247
|
+
}
|
248
|
+
end
|
249
|
+
|
250
|
+
# Add the autorequire line if requested
|
251
|
+
if autorequire
|
252
|
+
if (!coffee || coffee_compile)
|
253
|
+
code += "var #{libname} = NibJS.require('#{libname}');\n"
|
254
|
+
else
|
255
|
+
code += "#{libname} = NibJS.require '#{libname}'\n"
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
if header
|
260
|
+
code = File.read(header) + "\n" + code
|
261
|
+
end
|
262
|
+
|
263
|
+
# Uglify result now
|
264
|
+
if uglify
|
265
|
+
code = with_temp_file(code){|f| safe_run("uglifyjs #{f.path}") }
|
266
|
+
end
|
267
|
+
|
268
|
+
code
|
269
|
+
end
|
270
|
+
|
271
|
+
def with_output
|
272
|
+
if String === output
|
273
|
+
File.open(output, 'w'){|io| yield(io) }
|
274
|
+
else
|
275
|
+
yield(output)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def execute(args)
|
280
|
+
if args.size == 1
|
281
|
+
with_output{|io| io << compile(args[0]) }
|
282
|
+
else
|
283
|
+
raise Quickl::Help
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
end # class Main
|
288
|
+
end # module NibJS
|