1 |
3a515b92
|
cagy
|
Overview [](https://travis-ci.org/lydell/source-map-resolve)
|
2 |
|
|
========
|
3 |
|
|
|
4 |
|
|
Resolve the source map and/or sources for a generated file.
|
5 |
|
|
|
6 |
|
|
```js
|
7 |
|
|
var sourceMapResolve = require("source-map-resolve")
|
8 |
|
|
var sourceMap = require("source-map")
|
9 |
|
|
|
10 |
|
|
var code = [
|
11 |
|
|
"!function(){...}();",
|
12 |
|
|
"/*# sourceMappingURL=foo.js.map */"
|
13 |
|
|
].join("\n")
|
14 |
|
|
|
15 |
|
|
sourceMapResolve.resolveSourceMap(code, "/js/foo.js", fs.readFile, function(error, result) {
|
16 |
|
|
if (error) {
|
17 |
|
|
return notifyFailure(error)
|
18 |
|
|
}
|
19 |
|
|
result
|
20 |
|
|
// {
|
21 |
|
|
// map: {file: "foo.js", mappings: "...", sources: ["/coffee/foo.coffee"], names: []},
|
22 |
|
|
// url: "/js/foo.js.map",
|
23 |
|
|
// sourcesRelativeTo: "/js/foo.js.map",
|
24 |
|
|
// sourceMappingURL: "foo.js.map"
|
25 |
|
|
// }
|
26 |
|
|
|
27 |
|
|
sourceMapResolve.resolveSources(result.map, result.sourcesRelativeTo, fs.readFile, function(error, result) {
|
28 |
|
|
if (error) {
|
29 |
|
|
return notifyFailure(error)
|
30 |
|
|
}
|
31 |
|
|
result
|
32 |
|
|
// {
|
33 |
|
|
// sourcesResolved: ["/coffee/foo.coffee"],
|
34 |
|
|
// sourcesContent: ["<contents of /coffee/foo.coffee>"]
|
35 |
|
|
// }
|
36 |
|
|
})
|
37 |
|
|
})
|
38 |
|
|
|
39 |
|
|
sourceMapResolve.resolve(code, "/js/foo.js", fs.readFile, function(error, result) {
|
40 |
|
|
if (error) {
|
41 |
|
|
return notifyFailure(error)
|
42 |
|
|
}
|
43 |
|
|
result
|
44 |
|
|
// {
|
45 |
|
|
// map: {file: "foo.js", mappings: "...", sources: ["/coffee/foo.coffee"], names: []},
|
46 |
|
|
// url: "/js/foo.js.map",
|
47 |
|
|
// sourcesRelativeTo: "/js/foo.js.map",
|
48 |
|
|
// sourceMappingURL: "foo.js.map",
|
49 |
|
|
// sourcesResolved: ["/coffee/foo.coffee"],
|
50 |
|
|
// sourcesContent: ["<contents of /coffee/foo.coffee>"]
|
51 |
|
|
// }
|
52 |
|
|
result.map.sourcesContent = result.sourcesContent
|
53 |
|
|
var map = new sourceMap.sourceMapConsumer(result.map)
|
54 |
|
|
map.sourceContentFor("/coffee/foo.coffee")
|
55 |
|
|
// "<contents of /coffee/foo.coffee>"
|
56 |
|
|
})
|
57 |
|
|
```
|
58 |
|
|
|
59 |
|
|
|
60 |
|
|
Installation
|
61 |
|
|
============
|
62 |
|
|
|
63 |
|
|
- `npm install source-map-resolve`
|
64 |
|
|
- `bower install source-map-resolve`
|
65 |
|
|
- `component install lydell/source-map-resolve`
|
66 |
|
|
|
67 |
|
|
Works with CommonJS, AMD and browser globals, through UMD.
|
68 |
|
|
|
69 |
|
|
Note: This module requires `setImmediate` and `atob`.
|
70 |
|
|
Use polyfills if needed, such as:
|
71 |
|
|
|
72 |
|
|
- <https://github.com/NobleJS/setImmediate>
|
73 |
|
|
- <https://github.com/davidchambers/Base64.js>
|
74 |
|
|
|
75 |
|
|
|
76 |
|
|
Usage
|
77 |
|
|
=====
|
78 |
|
|
|
79 |
|
|
### `sourceMapResolve.resolveSourceMap(code, codeUrl, read, callback)` ###
|
80 |
|
|
|
81 |
|
|
- `code` is a string of code that may or may not contain a sourceMappingURL
|
82 |
|
|
comment. Such a comment is used to resolve the source map.
|
83 |
|
|
- `codeUrl` is the url to the file containing `code`. If the sourceMappingURL
|
84 |
|
|
is relative, it is resolved against `codeUrl`.
|
85 |
|
|
- `read(url, callback)` is a function that reads `url` and responds using
|
86 |
|
|
`callback(error, content)`. In Node.js you might want to use `fs.readFile`,
|
87 |
|
|
while in the browser you might want to use an asynchronus `XMLHttpRequest`.
|
88 |
|
|
- `callback(error, result)` is a function that is invoked with either an error
|
89 |
|
|
or `null` and the result.
|
90 |
|
|
|
91 |
|
|
The result is an object with the following properties:
|
92 |
|
|
|
93 |
|
|
- `map`: The source map for `code`, as an object (not a string).
|
94 |
|
|
- `url`: The url to the source map. If the source map came from a data uri,
|
95 |
|
|
this property is `null`, since then there is no url to it.
|
96 |
|
|
- `sourcesRelativeTo`: The url that the sources of the source map are relative
|
97 |
|
|
to. Since the sources are relative to the source map, and the url to the
|
98 |
|
|
source map is provided as the `url` property, this property might seem
|
99 |
|
|
superfluos. However, remember that the `url` property can be `null` if the
|
100 |
|
|
source map came from a data uri. If so, the sources are relative to the file
|
101 |
|
|
containing the data uri—`codeUrl`. This property will be identical to the
|
102 |
|
|
`url` property or `codeUrl`, whichever is appropriate. This way you can
|
103 |
|
|
conveniently resolve the sources without having to think about where the
|
104 |
|
|
source map came from.
|
105 |
|
|
- `sourceMappingURL`: The url of the sourceMappingURL comment in `code`.
|
106 |
|
|
|
107 |
|
|
If `code` contains no sourceMappingURL, the result is `null`.
|
108 |
|
|
|
109 |
|
|
### `sourceMapResolve.resolveSources(map, mapUrl, read, [options], callback)` ###
|
110 |
|
|
|
111 |
|
|
- `map` is a source map, as an object (not a string).
|
112 |
|
|
- `mapUrl` is the url to the file containing `map`. Relative sources in the
|
113 |
|
|
source map, if any, are resolved against `mapUrl`.
|
114 |
|
|
- `read(url, callback)` is a function that reads `url` and responds using
|
115 |
|
|
`callback(error, content)`. In Node.js you might want to use `fs.readFile`,
|
116 |
|
|
while in the browser you might want to use an asynchronus `XMLHttpRequest`.
|
117 |
|
|
- `options` is an optional object with any of the following properties:
|
118 |
|
|
- `sourceRoot`: Override the `sourceRoot` property of the source map, which
|
119 |
|
|
might only be relevant when resolving sources in the browser. This lets you
|
120 |
|
|
bypass it when using the module outside of a browser, if needed. Pass a
|
121 |
|
|
string to replace the `sourceRoot` property with, or `false` to ignore it.
|
122 |
|
|
Defaults to `undefined`.
|
123 |
|
|
- `callback(error, result)` is a function that is invoked with either an error
|
124 |
|
|
or `null` and the result.
|
125 |
|
|
|
126 |
|
|
The result is an object with the following properties:
|
127 |
|
|
|
128 |
|
|
- `sourcesResolved`: The same as `map.sources`, except all the sources are
|
129 |
|
|
fully resolved.
|
130 |
|
|
- `sourcesContent`: An array with the contents of all sources in `map.sources`,
|
131 |
|
|
in the same order as `map.sources`. If getting the contents of a source fails,
|
132 |
|
|
an error object is put into the array instead.
|
133 |
|
|
|
134 |
|
|
### `sourceMapResolve.resolve(code, codeUrl, read, [options], callback)` ###
|
135 |
|
|
|
136 |
|
|
The arguments are identical to `sourceMapResolve.resolveSourceMap`, except that
|
137 |
|
|
you may also provide the same `options` as in `sourceMapResolve.resolveSources`.
|
138 |
|
|
|
139 |
|
|
This is a convenience method that first resolves the source map and then its
|
140 |
|
|
sources. You could also do this by first calling
|
141 |
|
|
`sourceMapResolve.resolveSourceMap` and then `sourceMapResolve.resolveSources`.
|
142 |
|
|
|
143 |
|
|
The result is identical to `sourceMapResolve.resolveSourceMap`, with the
|
144 |
|
|
properties from `sourceMapResolve.resolveSources` merged into it.
|
145 |
|
|
|
146 |
|
|
There is one extra feature available, though. If `code` is `null`, `codeUrl` is
|
147 |
|
|
treated as a url to the source map instead of to `code`, and will be read. This
|
148 |
|
|
is handy if you _sometimes_ get the source map url from the `SourceMap: <url>`
|
149 |
|
|
header (see the [Notes] section). In this case, the `sourceMappingURL` property
|
150 |
|
|
of the result is `null`.
|
151 |
|
|
|
152 |
|
|
|
153 |
|
|
[Notes]: #notes
|
154 |
|
|
|
155 |
|
|
### `sourceMapResolve.*Sync()` ###
|
156 |
|
|
|
157 |
|
|
There are also sync versions of the three previous functions. They are identical
|
158 |
|
|
to the async versions, except:
|
159 |
|
|
|
160 |
|
|
- They expect a sync reading function. In Node.js you might want to use
|
161 |
|
|
`fs.readFileSync`, while in the browser you might want to use a synchronus
|
162 |
|
|
`XMLHttpRequest`.
|
163 |
|
|
- They throw errors and return the result instead of using a callback.
|
164 |
|
|
|
165 |
|
|
`sourceMapResolve.resolveSourcesSync` also accepts `null` as the `read`
|
166 |
|
|
parameter. The result is the same as when passing a function as the `read
|
167 |
|
|
parameter`, except that the `sourcesContent` property of the result will be an
|
168 |
|
|
empty array. In other words, the sources aren’t read. You only get the
|
169 |
|
|
`sourcesResolved` property. (This only supported in the synchronus version, since
|
170 |
|
|
there is no point doing it asynchronusly.)
|
171 |
|
|
|
172 |
|
|
### `sourceMapResolve.parseMapToJSON(string, [data])` ###
|
173 |
|
|
|
174 |
|
|
The spec says that if a source map (as a string) starts with `)]}'`, it should
|
175 |
|
|
be stripped off. This is to prevent XSSI attacks. This function does that and
|
176 |
|
|
returns the result of `JSON.parse`ing what’s left.
|
177 |
|
|
|
178 |
|
|
If this function throws `error`, `error.sourceMapData === data`.
|
179 |
|
|
|
180 |
|
|
### Errors
|
181 |
|
|
|
182 |
|
|
All errors passed to callbacks or thrown by this module have a `sourceMapData`
|
183 |
|
|
property that contain as much as possible of the intended result of the function
|
184 |
|
|
up until the error occurred.
|
185 |
|
|
|
186 |
|
|
Note that while the `map` property of result objects always is an object,
|
187 |
|
|
`error.sourceMapData.map` will be a string if parsing that string fails.
|
188 |
|
|
|
189 |
|
|
|
190 |
|
|
Note
|
191 |
|
|
====
|
192 |
|
|
|
193 |
|
|
This module resolves the source map for a given generated file by looking for a
|
194 |
|
|
sourceMappingURL comment. The spec defines yet a way to provide the URL to the
|
195 |
|
|
source map: By sending the `SourceMap: <url>` header along with the generated
|
196 |
|
|
file. Since this module doesn’t retrive the generated code for you (instead
|
197 |
|
|
_you_ give the generated code to the module), it’s up to you to look for such a
|
198 |
|
|
header when you retrieve the file (should the need arise).
|
199 |
|
|
|
200 |
|
|
|
201 |
|
|
Development
|
202 |
|
|
===========
|
203 |
|
|
|
204 |
|
|
Tests
|
205 |
|
|
-----
|
206 |
|
|
|
207 |
|
|
First off, run `npm install` to install testing modules and browser polyfills.
|
208 |
|
|
|
209 |
|
|
`npm test` lints the code and runs the test suite in Node.js.
|
210 |
|
|
|
211 |
|
|
x-package.json5
|
212 |
|
|
---------------
|
213 |
|
|
|
214 |
|
|
package.json, component.json and bower.json are all generated from
|
215 |
|
|
x-package.json5 by using [`xpkg`]. Only edit x-package.json5, and remember to
|
216 |
|
|
run `xpkg` before commiting!
|
217 |
|
|
|
218 |
|
|
[`xpkg`]: https://github.com/kof/node-xpkg
|
219 |
|
|
|
220 |
|
|
Generating the browser version
|
221 |
|
|
------------------------------
|
222 |
|
|
|
223 |
|
|
source-map-resolve.js is generated from source-map-resolve-node.js and
|
224 |
|
|
source-map-resolve-template.js. Only edit the two latter files, _not_
|
225 |
|
|
source-map-resolve.js! To generate it, run `npm run build`.
|
226 |
|
|
|
227 |
|
|
|
228 |
|
|
License
|
229 |
|
|
=======
|
230 |
|
|
|
231 |
|
|
[MIT](LICENSE).
|