UNPKG

8.67 kBMarkdownView Raw
1# Source Map Support
2[![Build Status](https://travis-ci.org/evanw/node-source-map-support.svg?branch=master)](https://travis-ci.org/evanw/node-source-map-support)
3
4This module provides source map support for stack traces in node via the [V8 stack trace API](https://github.com/v8/v8/wiki/Stack-Trace-API). It uses the [source-map](https://github.com/mozilla/source-map) module to replace the paths and line numbers of source-mapped files with their original paths and line numbers. The output mimics node's stack trace format with the goal of making every compile-to-JS language more of a first-class citizen. Source maps are completely general (not specific to any one language) so you can use source maps with multiple compile-to-JS languages in the same node process.
5
6## Installation and Usage
7
8#### Node support
9
10```
11$ npm install source-map-support
12```
13
14Source maps can be generated using libraries such as [source-map-index-generator](https://github.com/twolfson/source-map-index-generator). Once you have a valid source map, place a source mapping comment somewhere in the file (usually done automatically or with an option by your transpiler):
15
16```
17//# sourceMappingURL=path/to/source.map
18```
19
20If multiple sourceMappingURL comments exist in one file, the last sourceMappingURL comment will be
21respected (e.g. if a file mentions the comment in code, or went through multiple transpilers).
22The path should either be absolute or relative to the compiled file.
23
24From here you have two options.
25
26##### CLI Usage
27
28```bash
29node -r source-map-support/register compiled.js
30```
31
32##### Programmatic Usage
33
34Put the following line at the top of the compiled file.
35
36```js
37require('source-map-support').install();
38```
39
40It is also possible to install the source map support directly by
41requiring the `register` module which can be handy with ES6:
42
43```js
44import 'source-map-support/register'
45
46// Instead of:
47import sourceMapSupport from 'source-map-support'
48sourceMapSupport.install()
49```
50Note: if you're using babel-register, it includes source-map-support already.
51
52It is also very useful with Mocha:
53
54```
55$ mocha --require source-map-support/register tests/
56```
57
58#### Browser support
59
60This library also works in Chrome. While the DevTools console already supports source maps, the V8 engine doesn't and `Error.prototype.stack` will be incorrect without this library. Everything will just work if you deploy your source files using [browserify](http://browserify.org/). Just make sure to pass the `--debug` flag to the browserify command so your source maps are included in the bundled code.
61
62This library also works if you use another build process or just include the source files directly. In this case, include the file `browser-source-map-support.js` in your page and call `sourceMapSupport.install()`. It contains the whole library already bundled for the browser using browserify.
63
64```html
65<script src="browser-source-map-support.js"></script>
66<script>sourceMapSupport.install();</script>
67```
68
69This library also works if you use AMD (Asynchronous Module Definition), which is used in tools like [RequireJS](http://requirejs.org/). Just list `browser-source-map-support` as a dependency:
70
71```html
72<script>
73 define(['browser-source-map-support'], function(sourceMapSupport) {
74 sourceMapSupport.install();
75 });
76</script>
77```
78
79## Options
80
81This module installs two things: a change to the `stack` property on `Error` objects and a handler for uncaught exceptions that mimics node's default exception handler (the handler can be seen in the demos below). You may want to disable the handler if you have your own uncaught exception handler. This can be done by passing an argument to the installer:
82
83```js
84require('source-map-support').install({
85 handleUncaughtExceptions: false
86});
87```
88
89This module loads source maps from the filesystem by default. You can provide alternate loading behavior through a callback as shown below. For example, [Meteor](https://github.com/meteor) keeps all source maps cached in memory to avoid disk access.
90
91```js
92require('source-map-support').install({
93 retrieveSourceMap: function(source) {
94 if (source === 'compiled.js') {
95 return {
96 url: 'original.js',
97 map: fs.readFileSync('compiled.js.map', 'utf8')
98 };
99 }
100 return null;
101 }
102});
103```
104
105The module will by default assume a browser environment if XMLHttpRequest and window are defined. If either of these do not exist it will instead assume a node environment.
106In some rare cases, e.g. when running a browser emulation and where both variables are also set, you can explictly specify the environment to be either 'browser' or 'node'.
107
108```js
109require('source-map-support').install({
110 environment: 'node'
111});
112```
113
114To support files with inline source maps, the `hookRequire` options can be specified, which will monitor all source files for inline source maps.
115
116
117```js
118require('source-map-support').install({
119 hookRequire: true
120});
121```
122
123This monkey patches the `require` module loading chain, so is not enabled by default and is not recommended for any sort of production usage.
124
125## Demos
126
127#### Basic Demo
128
129original.js:
130
131```js
132throw new Error('test'); // This is the original code
133```
134
135compiled.js:
136
137```js
138require('source-map-support').install();
139
140throw new Error('test'); // This is the compiled code
141// The next line defines the sourceMapping.
142//# sourceMappingURL=compiled.js.map
143```
144
145compiled.js.map:
146
147```json
148{
149 "version": 3,
150 "file": "compiled.js",
151 "sources": ["original.js"],
152 "names": [],
153 "mappings": ";;AAAA,MAAM,IAAI"
154}
155```
156
157Run compiled.js using node (notice how the stack trace uses original.js instead of compiled.js):
158
159```
160$ node compiled.js
161
162original.js:1
163throw new Error('test'); // This is the original code
164 ^
165Error: test
166 at Object.<anonymous> (original.js:1:7)
167 at Module._compile (module.js:456:26)
168 at Object.Module._extensions..js (module.js:474:10)
169 at Module.load (module.js:356:32)
170 at Function.Module._load (module.js:312:12)
171 at Function.Module.runMain (module.js:497:10)
172 at startup (node.js:119:16)
173 at node.js:901:3
174```
175
176#### TypeScript Demo
177
178demo.ts:
179
180```typescript
181declare function require(name: string);
182require('source-map-support').install();
183class Foo {
184 constructor() { this.bar(); }
185 bar() { throw new Error('this is a demo'); }
186}
187new Foo();
188```
189
190Compile and run the file using the TypeScript compiler from the terminal:
191
192```
193$ npm install source-map-support typescript
194$ node_modules/typescript/bin/tsc -sourcemap demo.ts
195$ node demo.js
196
197demo.ts:5
198 bar() { throw new Error('this is a demo'); }
199 ^
200Error: this is a demo
201 at Foo.bar (demo.ts:5:17)
202 at new Foo (demo.ts:4:24)
203 at Object.<anonymous> (demo.ts:7:1)
204 at Module._compile (module.js:456:26)
205 at Object.Module._extensions..js (module.js:474:10)
206 at Module.load (module.js:356:32)
207 at Function.Module._load (module.js:312:12)
208 at Function.Module.runMain (module.js:497:10)
209 at startup (node.js:119:16)
210 at node.js:901:3
211```
212
213#### CoffeeScript Demo
214
215demo.coffee:
216
217```coffee
218require('source-map-support').install()
219foo = ->
220 bar = -> throw new Error 'this is a demo'
221 bar()
222foo()
223```
224
225Compile and run the file using the CoffeeScript compiler from the terminal:
226
227```sh
228$ npm install source-map-support coffee-script
229$ node_modules/coffee-script/bin/coffee --map --compile demo.coffee
230$ node demo.js
231
232demo.coffee:3
233 bar = -> throw new Error 'this is a demo'
234 ^
235Error: this is a demo
236 at bar (demo.coffee:3:22)
237 at foo (demo.coffee:4:3)
238 at Object.<anonymous> (demo.coffee:5:1)
239 at Object.<anonymous> (demo.coffee:1:1)
240 at Module._compile (module.js:456:26)
241 at Object.Module._extensions..js (module.js:474:10)
242 at Module.load (module.js:356:32)
243 at Function.Module._load (module.js:312:12)
244 at Function.Module.runMain (module.js:497:10)
245 at startup (node.js:119:16)
246```
247
248## Tests
249
250This repo contains both automated tests for node and manual tests for the browser. The automated tests can be run using mocha (type `mocha` in the root directory). To run the manual tests:
251
252* Build the tests using `build.js`
253* Launch the HTTP server (`npm run serve-tests`) and visit
254 * http://127.0.0.1:1336/amd-test
255 * http://127.0.0.1:1336/browser-test
256 * http://127.0.0.1:1336/browserify-test - **Currently not working** due to a bug with browserify (see [pull request #66](https://github.com/evanw/node-source-map-support/pull/66) for details).
257* For `header-test`, run `server.js` inside that directory and visit http://127.0.0.1:1337/
258
259## License
260
261This code is available under the [MIT license](http://opensource.org/licenses/MIT).