-
-
Notifications
You must be signed in to change notification settings - Fork 373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sourceMap.content "auto" option #298
Changes from 4 commits
3905ead
4fb781c
eb56dde
61f068e
09b25f2
0a61ef7
e21dc0a
ff52308
b9e7bb0
37c0bad
0b4f2f0
b73de80
cbd278d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
|
||
require("../tools/exit.js"); | ||
|
||
var execSync = require("child_process").execSync; | ||
var fs = require("fs"); | ||
var info = require("../package.json"); | ||
var path = require("path"); | ||
|
@@ -135,7 +136,7 @@ if (program.output == "ast") { | |
if (program.parse) { | ||
if (!program.parse.acorn && !program.parse.spidermonkey) { | ||
options.parse = program.parse; | ||
} else if (program.sourceMap && program.sourceMap.content == "inline") { | ||
} else if (content == "inline") { | ||
fatal("ERROR: inline source map only works with built-in parser"); | ||
} | ||
} | ||
|
@@ -196,6 +197,7 @@ function run() { | |
UglifyJS.AST_Node.warn_function = function(msg) { | ||
print_error("WARN: " + msg); | ||
}; | ||
var content = program.sourceMap && program.sourceMap.content; | ||
if (program.timings) options.timings = true; | ||
try { | ||
if (program.parse) { | ||
|
@@ -221,6 +223,59 @@ function run() { | |
} catch (ex) { | ||
fatal(ex); | ||
} | ||
if (content == "auto") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would like to use strict equal There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
var to_ascii = function(b64) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! |
||
return new Buffer(b64, "base64").toString(); | ||
}; | ||
|
||
var resolve_source_map_content = function(name, code) { | ||
var sourceMappingURLMatch = /\n\/\/# sourceMappingURL=(.*)/.exec(code); | ||
var sourceMappingURL = sourceMappingURLMatch ? sourceMappingURLMatch[1] : null; | ||
|
||
if (!sourceMappingURL) { | ||
// infer | ||
if (fs.existsSync(name + '.map')) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ESLint: Strings must use doublequote. (quotes) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
return read_file(name + '.map'); | ||
} | ||
if (/\.js$/.test(name) && fs.existsSync(name.slice(0, -2) + 'map')) { | ||
return read_file(name.slice(0, -2) + 'map'); | ||
} | ||
return; | ||
} | ||
|
||
if (sourceMappingURL.indexOf('data:application') == 0) { | ||
var match = /data:application\/json(;.*?)?;base64,(.*)/.exec(sourceMappingURL); | ||
return to_ascii(match[2]); | ||
} | ||
|
||
if (sourceMappingURL.indexOf('http') == 0) { | ||
try { | ||
return execSync('curl -s ' + sourceMappingURL).toString(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On my windows machine curl is not installed.... 😖 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace with the http libs. Required some promises. |
||
} catch (ex) { | ||
fatal(ex); | ||
} | ||
} | ||
|
||
return read_file(path.join(path.dirname(name), sourceMappingURL)); | ||
}; | ||
|
||
// read source map content locations given via CLI | ||
// contents=file1.js*file1.js.map|file2.js*path/to/map.js.map|... | ||
var contents = {}; | ||
if (options.sourceMap.contents) options.sourceMap.contents.replace(/([^|*]+)=([^|]+)/g, function(_, x, y) { | ||
contents[x] = read_file(y, y); | ||
}); | ||
|
||
// attempt to resolve the remaining | ||
for (var name in files) if (!contents[name]) { | ||
var content = resolve_source_map_content(name, files[name]); | ||
if (content) { | ||
contents[name] = content; | ||
} | ||
} | ||
|
||
options.sourceMap.contents = contents; | ||
} | ||
var result = UglifyJS.minify(files, options); | ||
if (result.error) { | ||
var ex = result.error; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,15 +27,23 @@ var to_base64 = typeof btoa == "undefined" ? function(str) { | |
return Buffer.from(str).toString("base64"); | ||
} : btoa; | ||
|
||
function read_source_map(code) { | ||
function read_inline_source_map(name, code) { | ||
var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code); | ||
if (!match) { | ||
AST_Node.warn("inline source map not found"); | ||
AST_Node.warn("inline source map not found: " + name); | ||
return null; | ||
} | ||
return to_ascii(match[2]); | ||
} | ||
|
||
function parse_source_map(content) { | ||
try { | ||
return JSON.parse(content); | ||
} catch (ex) { | ||
throw new Error("invalid input source map: " + content); | ||
} | ||
} | ||
|
||
function set_shorthand(name, options, keys) { | ||
if (options[name]) { | ||
keys.forEach(function(key) { | ||
|
@@ -135,6 +143,7 @@ function minify(files, options) { | |
if (options.sourceMap) { | ||
options.sourceMap = defaults(options.sourceMap, { | ||
content: null, | ||
contents: null, | ||
filename: null, | ||
includeSources: false, | ||
root: null, | ||
|
@@ -148,7 +157,7 @@ function minify(files, options) { | |
}; | ||
} | ||
if (timings) timings.parse = Date.now(); | ||
var toplevel; | ||
var source_maps, toplevel; | ||
if (files instanceof AST_Toplevel) { | ||
toplevel = files; | ||
} else { | ||
|
@@ -157,13 +166,28 @@ function minify(files, options) { | |
} | ||
options.parse = options.parse || {}; | ||
options.parse.toplevel = null; | ||
var source_map_content = options.sourceMap && options.sourceMap.content; | ||
if (typeof source_map_content == "string" && source_map_content != "inline" && source_map_content != "auto") { | ||
source_map_content = parse_source_map(source_map_content); | ||
} | ||
source_maps = source_map_content && Object.create(null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. According to #300 (comment) I guess it would be much better to use smth like: if (source_map_content) source_maps = new Set(); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least it will reduce variety in code which doing same things There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 , but it's actually a Map. |
||
for (var name in files) if (HOP(files, name)) { | ||
options.parse.filename = name; | ||
options.parse.toplevel = parse(files[name], options.parse); | ||
if (options.sourceMap && options.sourceMap.content == "inline") { | ||
if (Object.keys(files).length > 1) | ||
throw new Error("inline source map only works with singular input"); | ||
options.sourceMap.content = read_source_map(files[name]); | ||
if (source_map_content) { | ||
if (options.sourceMap.content == "inline") { | ||
var inlined_content = read_inline_source_map(name, files[name]); | ||
if (inlined_content) { | ||
source_maps[name] = parse_source_map(inlined_content); | ||
} | ||
} else if (source_map_content == "auto") { | ||
var content = options.sourceMap.contents[name]; | ||
if (content) { | ||
source_maps[name] = parse_source_map(content); | ||
} | ||
} else { | ||
source_maps[name] = source_map_content; | ||
} | ||
} | ||
} | ||
toplevel = options.parse.toplevel; | ||
|
@@ -205,12 +229,9 @@ function minify(files, options) { | |
} | ||
if (!HOP(options.output, "code") || options.output.code) { | ||
if (options.sourceMap) { | ||
if (typeof options.sourceMap.content == "string") { | ||
options.sourceMap.content = JSON.parse(options.sourceMap.content); | ||
} | ||
options.output.source_map = SourceMap({ | ||
file: options.sourceMap.filename, | ||
orig: options.sourceMap.content, | ||
orig: source_maps, | ||
root: options.sourceMap.root | ||
}); | ||
if (options.sourceMap.includeSources) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,20 +62,24 @@ function SourceMap(options) { | |
file : options.file, | ||
sourceRoot : options.root | ||
}); | ||
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig); | ||
|
||
if (orig_map) { | ||
orig_map.sources.forEach(function(source) { | ||
var sourceContent = orig_map.sourceContentFor(source, true); | ||
if (sourceContent) { | ||
generator.setSourceContent(source, sourceContent); | ||
} | ||
var maps = options.orig && Object.create(null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 , but it's actually a Map. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My bad) |
||
if (maps) for (var source in options.orig) { | ||
var map = new MOZ_SourceMap.SourceMapConsumer(options.orig[source]); | ||
var sourceContents = [...map._sources.toArray()]; | ||
if (map._sections) for (const section of map._sections) { | ||
sourceContents.push(...section.consumer._sources.toArray()); | ||
} | ||
sourceContents.forEach(function(source) { | ||
var sourceContent = map.sourceContentFor(source, true); | ||
if (sourceContent) generator.setSourceContent(source, sourceContent); | ||
}); | ||
maps[source] = map; | ||
} | ||
|
||
function add(source, gen_line, gen_col, orig_line, orig_col, name) { | ||
if (orig_map) { | ||
var info = orig_map.originalPositionFor({ | ||
var map = maps && maps[source]; | ||
if (map) { | ||
var info = map.originalPositionFor({ | ||
line: orig_line, | ||
column: orig_col | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/usr/bin/env sh | ||
|
||
tsc --sourceMap --inlineSources file.ts | ||
sed -i '' 's/file/mapping/g' file.js | ||
mv file.js.map mapping.js.map | ||
|
||
tsc --sourceMap --inlineSources file.ts --out file2.js | ||
sed -i '' 's/file2/mapping2/g' file2.js | ||
sed -i '' -e '$ d' file2.js | ||
mv file2.js.map mapping2.js.map | ||
|
||
tsc --sourceMap --inlineSources file.ts --out file3.js | ||
sed -i '' 's/file3/mapping2/g' file3.js | ||
sed -i '' -e '$ d' file3.js | ||
mv file3.js.map mapping2.js.map | ||
|
||
tsc --inlineSourceMap --inlineSources inline.ts | ||
|
||
tsc --sourceMap --inlineSources infer1.ts | ||
sed -i '' -e '$ d' infer1.js | ||
|
||
tsc --sourceMap --inlineSources infer2.ts | ||
sed -i '' -e '$ d' infer2.js | ||
mv infer2.js.map infer2.map |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
interface ICar { | ||
model: string | ||
speed: number | ||
cost: number | ||
} | ||
|
||
class Car implements ICar { | ||
model: string = 'nice' | ||
speed: number = 100 | ||
cost: number = 1000000 | ||
} | ||
|
||
var myCar: Car = new Car() | ||
myCar.cost += 1 | ||
|
||
const [blah, blah2] = [1,2] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
var Car = /** @class */ (function () { | ||
function Car() { | ||
this.model = 'nice'; | ||
this.speed = 100; | ||
this.cost = 1000000; | ||
} | ||
return Car; | ||
}()); | ||
var myCar = new Car(); | ||
myCar.cost += 1; | ||
var _a = [1, 2], blah = _a[0], blah2 = _a[1]; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
var Car = /** @class */ (function () { | ||
function Car() { | ||
this.model = 'nice'; | ||
this.speed = 100; | ||
this.cost = 1000000; | ||
} | ||
return Car; | ||
}()); | ||
var myCar = new Car(); | ||
myCar.cost += 1; | ||
var _a = [1, 2], blah = _a[0], blah2 = _a[1]; |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
console.log('infer1.js'); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
console.log('infer1.js'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
console.log('infer2.js'); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
console.log('infer2.js'); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
interface ICar { | ||
model: string | ||
speed: number | ||
cost: number | ||
} | ||
|
||
class Car implements ICar { | ||
model: string = 'bad' | ||
speed: number = 10 | ||
cost: number = 10000 | ||
} | ||
|
||
var myCar: Car = new Car() | ||
myCar.cost += 1 | ||
|
||
const [blah, blah2] = [1,2] |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm little bit worried about this changes..
ESLint: 'content' is not defined. (no-undef)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops!