squash_javascript 1.0.3 → 2.0.5
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.
- checksums.yaml +5 -13
- data/README.md +49 -8
- data/bin/upload_source_map +10 -4
- data/lib/squash/javascript/capistrano.rb +16 -0
- data/lib/squash/javascript/patches.rb +33 -0
- data/lib/squash/javascript/railtie.rb +5 -0
- data/lib/squash/javascript/source_mapping_coffeescript_template.rb +27 -0
- data/lib/squash/javascript/source_mapping_javascript_minifier.rb +36 -0
- data/lib/squash/javascript/tasks/sourcemaps.rake +73 -0
- data/lib/squash/javascript.rb +4 -1
- data/lib/tasks/squash.cap +30 -0
- data/vendor/assets/javascripts/squash_javascript/{client.coffee → client.js.coffee} +1 -1
- data/vendor/assets/javascripts/squash_javascript/tracekit.js +1000 -996
- data/vendor/assets/javascripts/squash_javascript.min.js +24 -24
- data/vendor/assets/javascripts/squash_javascript.orig.js +1 -1
- metadata +47 -29
- data/lib/squash/javascript/source_map.rb +0 -181
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NWVkMTA3NTMzYTQyZDExYjlmMDdiNzNmNDJhM2IzMTgxNjYzMmM4NA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f8d9f1fd8dff2720d5a08a2842c3d47b7432f43f
|
4
|
+
data.tar.gz: 39c29285f2daca8d0caf179d33fd99d0dd7504c9
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
OWI3ZTkyZDgyMmMzNjg1OTdjMGI0NTc5OWIwMzdlMGNmMzQ1OGMwMGZjZjI1
|
11
|
-
ODc0MjE1NzA0NjkwMmU2ZGM5YjAzZjAyNmI0ZDAxYTRjMzEwYmI=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MzhkODM0MzVmNjM0YmI4NTE2NmRmNzcxODZmOTVhODU1NmUzZmI1NjkwNmRj
|
14
|
-
NDA0ZjQxOWE0NmM0NmVlZDBmNzZlM2EwMGEwMzJhZDk2ODk1YTIwOWI0ZDgz
|
15
|
-
ODNlNzkzNzNiMWZkOTk2MDNkNjU5Y2ZhYjBlZWU1NmE5NWQ3OTk=
|
6
|
+
metadata.gz: d6a8223c1f281122cb38da8c24cd68bd2574bd21372dd3a1541181375835f9cb84d510d525327bcae127388f0e2c24e1302ce3eaeaac36bfee189f51c8e01033
|
7
|
+
data.tar.gz: 4938f74e4e02ed2afa346bc5463a0e2f93edf9b1cea24a95ac74ad452edc1ad1ec4b70eeac6c972b116eef32888a086e33efb9139efb8f6b7af48ecb8a92fe48
|
data/README.md
CHANGED
@@ -42,11 +42,15 @@ The library is included in this project. For Rails projects, a Sprockets include
|
|
42
42
|
file is provided. For non-Rails projects, the output of `rake minify` rolls in
|
43
43
|
the library.
|
44
44
|
|
45
|
-
|
46
|
-
|
45
|
+
**The included version of TraceKit has been modified somewhat:**
|
46
|
+
|
47
|
+
* `window.onerror` support was expanded to include changes in recent versions of
|
48
|
+
modern browsers (namely, passing the column and error object as parameters).
|
49
|
+
* TraceKit was causing unexpected behavior on Chrome and Firefox, and parts of
|
50
|
+
it are commented out. (The jQuery hooks were disabled.)
|
47
51
|
|
48
52
|
Installation
|
49
|
-
|
53
|
+
------------
|
50
54
|
|
51
55
|
### Rails
|
52
56
|
|
@@ -252,20 +256,57 @@ still be re-raised, but the failsafe error will be "eaten."
|
|
252
256
|
Source Mapping
|
253
257
|
--------------
|
254
258
|
|
255
|
-
|
259
|
+
### Rails and Sprockets
|
260
|
+
|
261
|
+
Squash JavaScript can integrate with Sprockets to automatically generate source
|
262
|
+
maps for each stage of the asset compilation pipeline, then integrate with
|
263
|
+
Capistrano to upload the source maps to Squash. To use this feature, configure
|
264
|
+
your project like so:
|
265
|
+
|
266
|
+
1. Replace your JavaScript compiler gem with Closure, if you aren't already
|
267
|
+
using it.
|
268
|
+
|
269
|
+
```` diff
|
270
|
+
-gem 'uglifier'
|
271
|
+
+gem 'closure-compiler'
|
272
|
+
````
|
273
|
+
|
274
|
+
2. Use Squash's source-mapping Tilt engines for CoffeeScript and JavaScript.
|
275
|
+
|
276
|
+
These Tilt engines wrap existing Tilt template engines, but also generate
|
277
|
+
source maps to `tmp/sourcemaps`.
|
278
|
+
|
279
|
+
```` ruby
|
280
|
+
Sprockets.register_engine '.coffee', Squash::Javascript::SourceMappingCoffeescriptTemplate
|
281
|
+
config.assets.js_compressor = Squash::Javascript::SourceMappingJavascriptMinifier
|
282
|
+
````
|
283
|
+
|
284
|
+
3. Add the Squash Capistrano tasks to your Capfile:
|
285
|
+
|
286
|
+
```` ruby
|
287
|
+
require 'squash/javascript/capistrano'
|
288
|
+
````
|
289
|
+
|
290
|
+
If you do not use Capistrano 3, you can use the `rake sourcemaps:upload:all`
|
291
|
+
task to upload your generated source maps to Squash.
|
292
|
+
|
293
|
+
### Other Projects
|
294
|
+
|
295
|
+
If you can generate a source map for your minified JavaScript files (Closure
|
256
296
|
can), you can use this gem to upload that source map to Squash, where it will
|
257
297
|
be used to convert minified stack traces to their original format, which can
|
258
298
|
then benefit from Git-blaming, context, and other features of Squash.
|
259
299
|
|
260
300
|
To upload the source map to squash, run the `upload_source_map` binary included
|
261
|
-
with this gem, and pass it four arguments: 1) your
|
262
|
-
|
263
|
-
hosted. Example:
|
301
|
+
with this gem, and pass it four arguments: 1) your Squash host, 2) your API key,
|
302
|
+
3) the environment name, and 4) the path to the JSON source map. Example:
|
264
303
|
|
265
304
|
````
|
266
|
-
upload_source_map abc-123-abc-123-abc-123 production artifacts/mapping.json
|
305
|
+
upload_source_map http://your.squash.host abc-123-abc-123-abc-123 production artifacts/mapping.json
|
267
306
|
````
|
268
307
|
|
308
|
+
Use `--help` to learn about additional options.
|
309
|
+
|
269
310
|
Specs
|
270
311
|
-----
|
271
312
|
|
data/bin/upload_source_map
CHANGED
@@ -36,9 +36,15 @@ project_dir = Dir.getwd
|
|
36
36
|
ignore_root = false
|
37
37
|
revision = nil
|
38
38
|
options = {}
|
39
|
+
from = 'hosted'
|
40
|
+
to = 'original'
|
39
41
|
|
40
42
|
parser = OptionParser.new do |parser|
|
41
|
-
parser.banner = "Usage: upload_source_map [options] YOUR_SQUASH_HOST YOUR_API_KEY ENVIRONMENT /path/to/mapping.json
|
43
|
+
parser.banner = "Usage: upload_source_map [options] YOUR_SQUASH_HOST YOUR_API_KEY ENVIRONMENT /path/to/mapping.json"
|
44
|
+
|
45
|
+
parser.on('-f', '--from S', "The type of stack trace element this source map converts from (hosted [default], concatenated, etc.)") { |f| from = f }
|
46
|
+
parser.on('-t', '--to S', "The type of stack trace element this source map converts to (compiled, original [default], coffee, etc.)") { |t| to = t }
|
47
|
+
|
42
48
|
parser.on('-o', '--open-timeout N', Integer, "HTTP connection open timeout") { |ot| options[:open_timeout] = ot }
|
43
49
|
parser.on('-r', '--read-timeout N', Integer, "HTTP connection data received timeout") { |rt| options[:read_timeout] = rt }
|
44
50
|
parser.on('-k', '--[no-]skip-verification', "Do not perform SSL peer verification") { |sv| options[:skip_verification] = sv }
|
@@ -62,14 +68,14 @@ host = ARGV.shift
|
|
62
68
|
api_key = ARGV.shift
|
63
69
|
environment = ARGV.shift
|
64
70
|
map_file = ARGV.shift
|
65
|
-
route = ARGV.shift
|
66
71
|
revision = revision || git_revision(project_dir)
|
67
72
|
|
68
|
-
map = Squash::Javascript::SourceMap.from_sourcemap(map_file, route, root: ignore_root ? project_dir : nil)
|
69
73
|
Squash::Uploader.new(host, options).transmit '/api/1.0/sourcemap.json',
|
70
74
|
{
|
71
75
|
'api_key' => api_key,
|
72
76
|
'environment' => environment,
|
73
77
|
'revision' => revision,
|
74
|
-
'sourcemap' => Base64.encode64(Zlib::Deflate.deflate(
|
78
|
+
'sourcemap' => Base64.encode64(Zlib::Deflate.deflate(File.read(map_file))),
|
79
|
+
'from' => from,
|
80
|
+
'to' => to
|
75
81
|
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Copyright 2014 Square Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
load(File.dirname(__FILE__) + '/../../tasks/squash.cap')
|
16
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'source_map'
|
2
|
+
require 'sprockets'
|
3
|
+
|
4
|
+
# @private
|
5
|
+
class Sprockets::Asset
|
6
|
+
def sourcemap
|
7
|
+
relative_path = if pathname.to_s.include?(Rails.root.to_s)
|
8
|
+
pathname.relative_path_from(Rails.root)
|
9
|
+
else
|
10
|
+
pathname
|
11
|
+
end.to_s
|
12
|
+
# any extensions after the ".js" can be removed, because they will have
|
13
|
+
# already been processed
|
14
|
+
relative_path.gsub! /(?<=\.js)\..*$/, ''
|
15
|
+
resource_path = [Rails.application.config.assets.prefix, logical_path].join('/')
|
16
|
+
|
17
|
+
mappings = Array.new
|
18
|
+
to_s.lines.each_with_index do |_, index|
|
19
|
+
offset = SourceMap::Offset.new(index, 0)
|
20
|
+
mappings << SourceMap::Mapping.new(relative_path, offset, offset)
|
21
|
+
end
|
22
|
+
SourceMap::Map.new(mappings, resource_path)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# @private
|
27
|
+
class Sprockets::BundledAsset < Sprockets::Asset
|
28
|
+
def sourcemap
|
29
|
+
to_a.inject(SourceMap::Map.new) do |map, asset|
|
30
|
+
map + asset.sourcemap
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'digest/sha2'
|
2
|
+
|
3
|
+
class Squash::Javascript::SourceMappingCoffeescriptTemplate < Tilt::CoffeeScriptTemplate
|
4
|
+
def evaluate(scope, locals, &block)
|
5
|
+
@output ||= begin
|
6
|
+
result = CoffeeScript.compile(data, options.merge(sourceMap: true))
|
7
|
+
|
8
|
+
relative_path = if file.include?(Rails.root.to_s)
|
9
|
+
Pathname.new(file).relative_path_from(Rails.root)
|
10
|
+
else
|
11
|
+
Pathname.new(file)
|
12
|
+
end
|
13
|
+
|
14
|
+
map = JSON.parse(result['v3SourceMap'])
|
15
|
+
map['file'] = relative_path.to_s.sub(/\.coffee$/, '')
|
16
|
+
map['sources'] = [relative_path.to_s]
|
17
|
+
|
18
|
+
map_path = Rails.root.join('tmp', 'sourcemaps', 'compiled', Digest::SHA2.hexdigest(relative_path.to_s) + '.json')
|
19
|
+
FileUtils.mkdir_p map_path.dirname
|
20
|
+
Rails.root.join('tmp', 'sourcemaps', map_path).open('w') do |f|
|
21
|
+
f.puts map.to_json
|
22
|
+
end
|
23
|
+
|
24
|
+
result['js']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
class Squash::Javascript::SourceMappingJavascriptMinifier < Tilt::Template
|
4
|
+
def prepare() end
|
5
|
+
|
6
|
+
def evaluate(context, locals)
|
7
|
+
source_map_file = Tempfile.new('sourcemap')
|
8
|
+
compressor = Closure::Compiler.new(create_source_map: source_map_file.path)
|
9
|
+
minified = compressor.compress(data)
|
10
|
+
|
11
|
+
minified_file = Tempfile.new('minified')
|
12
|
+
minified_file.write minified
|
13
|
+
|
14
|
+
map = JSON.parse(source_map_file.read)
|
15
|
+
minified_filename = [Rails.application.config.assets.prefix, "#{context.logical_path}-#{digest(minified)}.js"].join('/')
|
16
|
+
concatenated_filename = [Rails.application.config.assets.prefix, "#{context.logical_path}.js"].join('/')
|
17
|
+
map['file'] = minified_filename
|
18
|
+
map['sources'] = [concatenated_filename]
|
19
|
+
|
20
|
+
path = source_map_path(digest(minified))
|
21
|
+
FileUtils.mkdir_p path.dirname
|
22
|
+
File.open(path, 'w') { |f| f.puts map.to_json }
|
23
|
+
|
24
|
+
return minified
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def digest(io)
|
30
|
+
Rails.application.assets.digest.update(io).hexdigest
|
31
|
+
end
|
32
|
+
|
33
|
+
def source_map_path(digest)
|
34
|
+
Rails.root.join 'tmp', 'sourcemaps', 'minified', "#{digest}.json"
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'squash/uploader'
|
2
|
+
|
3
|
+
namespace :sourcemaps do
|
4
|
+
namespace :upload do
|
5
|
+
task all: [:minified, :concatenated, :compiled]
|
6
|
+
|
7
|
+
task minified: :environment do
|
8
|
+
manifest_path = Rails.root.join('public',
|
9
|
+
Rails.application.config.assets.prefix.sub(/^\//, ''),
|
10
|
+
'manifest-*.json')
|
11
|
+
manifest_path = Dir.glob(manifest_path.to_s).first
|
12
|
+
raise "You must precompile your static assets before running this task." unless manifest_path
|
13
|
+
|
14
|
+
manifest = JSON.parse(File.read(manifest_path))
|
15
|
+
manifest['files'].each do |path, metadata|
|
16
|
+
sourcemap_path = Rails.root.join('tmp', 'sourcemaps', 'minified', "#{metadata['digest']}.json")
|
17
|
+
if sourcemap_path.exist?
|
18
|
+
Squash::Uploader.new(Squash::Ruby.configuration(:api_host),
|
19
|
+
skip_verification: Squash::Ruby.configuration(:skip_verification)
|
20
|
+
).transmit '/api/1.0/sourcemap.json',
|
21
|
+
{
|
22
|
+
'api_key' => Squash::Ruby.configuration(:api_key),
|
23
|
+
'environment' => Rails.env,
|
24
|
+
'revision' => Squash::Ruby.current_revision,
|
25
|
+
'sourcemap' => Base64.encode64(Zlib::Deflate.deflate(File.read(sourcemap_path))),
|
26
|
+
'from' => 'hosted',
|
27
|
+
'to' => 'concatenated'
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
task concatenated: :environment do
|
34
|
+
Rails.application.assets.each_logical_path(Rails.application.config.assets.precompile) do |path|
|
35
|
+
next unless path.end_with?('.js')
|
36
|
+
asset = Rails.application.assets.find_asset(path)
|
37
|
+
next unless asset.kind_of?(Sprockets::BundledAsset)
|
38
|
+
map = asset.sourcemap
|
39
|
+
Squash::Uploader.new(Squash::Ruby.configuration(:api_host),
|
40
|
+
skip_verification: Squash::Ruby.configuration(:skip_verification)
|
41
|
+
).transmit '/api/1.0/sourcemap.json',
|
42
|
+
{
|
43
|
+
'api_key' => Squash::Ruby.configuration(:api_key),
|
44
|
+
'environment' => Rails.env,
|
45
|
+
'revision' => Squash::Ruby.current_revision,
|
46
|
+
'sourcemap' => Base64.encode64(Zlib::Deflate.deflate(map.as_json.to_json)),
|
47
|
+
'from' => 'concatenated',
|
48
|
+
'to' => 'compiled',
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
task compiled: :environment do
|
54
|
+
Dir.glob(Rails.root.join('tmp', 'sourcemaps', 'compiled', '*.json')).each do |file|
|
55
|
+
Squash::Uploader.new(Squash::Ruby.configuration(:api_host),
|
56
|
+
skip_verification: Squash::Ruby.configuration(:skip_verification)
|
57
|
+
).transmit '/api/1.0/sourcemap.json',
|
58
|
+
{
|
59
|
+
'api_key' => Squash::Ruby.configuration(:api_key),
|
60
|
+
'environment' => Rails.env,
|
61
|
+
'revision' => Squash::Ruby.current_revision,
|
62
|
+
'sourcemap' => Base64.encode64(Zlib::Deflate.deflate(File.read(file))),
|
63
|
+
'from' => 'compiled',
|
64
|
+
'to' => 'original'
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
task :clean do
|
71
|
+
system 'rm', '-rf', 'tmp/sourcemaps/*'
|
72
|
+
end
|
73
|
+
end
|
data/lib/squash/javascript.rb
CHANGED
@@ -22,5 +22,8 @@ module Squash
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
require 'squash/javascript/
|
25
|
+
require 'squash/javascript/patches'
|
26
|
+
require 'squash/javascript/source_mapping_coffeescript_template'
|
27
|
+
require 'squash/javascript/source_mapping_javascript_minifier'
|
26
28
|
require 'squash/javascript/engine'
|
29
|
+
require 'squash/javascript/railtie'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright 2014 Square Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
namespace :squash do
|
16
|
+
namespace :sourcemaps do
|
17
|
+
desc "Uploads JavaScript source maps to Squash"
|
18
|
+
task :upload do
|
19
|
+
on roles(:web), limit: 1 do
|
20
|
+
within release_path do
|
21
|
+
with rails_env: fetch(:rails_env) do
|
22
|
+
rake 'sourcemaps:upload:all'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
after 'deploy:finishing', 'squash:sourcemaps:upload'
|
@@ -203,7 +203,7 @@ class _SquashJavascript
|
|
203
203
|
for line in stack
|
204
204
|
context = line.context
|
205
205
|
context = null if context && any(context, (cline) -> cline && cline.length > 200)
|
206
|
-
backtraces.push {url: line.url, line: line.line, column: line.column, symbol: line.func, context: context, type: '
|
206
|
+
backtraces.push {url: line.url, line: line.line, column: line.column, symbol: line.func, context: context, type: 'js:hosted'}
|
207
207
|
return [ {name: "Active Thread", faulted: true, backtrace: backtraces} ]
|
208
208
|
|
209
209
|
ISODateString = (d) ->
|