source: imaps-frontend/node_modules/@ampproject/remapping/README.md@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 7.1 KB
Line 
1# @ampproject/remapping
2
3> Remap sequential sourcemaps through transformations to point at the original source code
4
5Remapping allows you to take the sourcemaps generated through transforming your code and "remap"
6them to the original source locations. Think "my minified code, transformed with babel and bundled
7with webpack", all pointing to the correct location in your original source code.
8
9With remapping, none of your source code transformations need to be aware of the input's sourcemap,
10they only need to generate an output sourcemap. This greatly simplifies building custom
11transformations (think a find-and-replace).
12
13## Installation
14
15```sh
16npm install @ampproject/remapping
17```
18
19## Usage
20
21```typescript
22function remapping(
23 map: SourceMap | SourceMap[],
24 loader: (file: string, ctx: LoaderContext) => (SourceMap | null | undefined),
25 options?: { excludeContent: boolean, decodedMappings: boolean }
26): SourceMap;
27
28// LoaderContext gives the loader the importing sourcemap, tree depth, the ability to override the
29// "source" location (where child sources are resolved relative to, or the location of original
30// source), and the ability to override the "content" of an original source for inclusion in the
31// output sourcemap.
32type LoaderContext = {
33 readonly importer: string;
34 readonly depth: number;
35 source: string;
36 content: string | null | undefined;
37}
38```
39
40`remapping` takes the final output sourcemap, and a `loader` function. For every source file pointer
41in the sourcemap, the `loader` will be called with the resolved path. If the path itself represents
42a transformed file (it has a sourcmap associated with it), then the `loader` should return that
43sourcemap. If not, the path will be treated as an original, untransformed source code.
44
45```js
46// Babel transformed "helloworld.js" into "transformed.js"
47const transformedMap = JSON.stringify({
48 file: 'transformed.js',
49 // 1st column of 2nd line of output file translates into the 1st source
50 // file, line 3, column 2
51 mappings: ';CAEE',
52 sources: ['helloworld.js'],
53 version: 3,
54});
55
56// Uglify minified "transformed.js" into "transformed.min.js"
57const minifiedTransformedMap = JSON.stringify({
58 file: 'transformed.min.js',
59 // 0th column of 1st line of output file translates into the 1st source
60 // file, line 2, column 1.
61 mappings: 'AACC',
62 names: [],
63 sources: ['transformed.js'],
64 version: 3,
65});
66
67const remapped = remapping(
68 minifiedTransformedMap,
69 (file, ctx) => {
70
71 // The "transformed.js" file is an transformed file.
72 if (file === 'transformed.js') {
73 // The root importer is empty.
74 console.assert(ctx.importer === '');
75 // The depth in the sourcemap tree we're currently loading.
76 // The root `minifiedTransformedMap` is depth 0, and its source children are depth 1, etc.
77 console.assert(ctx.depth === 1);
78
79 return transformedMap;
80 }
81
82 // Loader will be called to load transformedMap's source file pointers as well.
83 console.assert(file === 'helloworld.js');
84 // `transformed.js`'s sourcemap points into `helloworld.js`.
85 console.assert(ctx.importer === 'transformed.js');
86 // This is a source child of `transformed`, which is a source child of `minifiedTransformedMap`.
87 console.assert(ctx.depth === 2);
88 return null;
89 }
90);
91
92console.log(remapped);
93// {
94// file: 'transpiled.min.js',
95// mappings: 'AAEE',
96// sources: ['helloworld.js'],
97// version: 3,
98// };
99```
100
101In this example, `loader` will be called twice:
102
1031. `"transformed.js"`, the first source file pointer in the `minifiedTransformedMap`. We return the
104 associated sourcemap for it (its a transformed file, after all) so that sourcemap locations can
105 be traced through it into the source files it represents.
1062. `"helloworld.js"`, our original, unmodified source code. This file does not have a sourcemap, so
107 we return `null`.
108
109The `remapped` sourcemap now points from `transformed.min.js` into locations in `helloworld.js`. If
110you were to read the `mappings`, it says "0th column of the first line output line points to the 1st
111column of the 2nd line of the file `helloworld.js`".
112
113### Multiple transformations of a file
114
115As a convenience, if you have multiple single-source transformations of a file, you may pass an
116array of sourcemap files in the order of most-recent transformation sourcemap first. Note that this
117changes the `importer` and `depth` of each call to our loader. So our above example could have been
118written as:
119
120```js
121const remapped = remapping(
122 [minifiedTransformedMap, transformedMap],
123 () => null
124);
125
126console.log(remapped);
127// {
128// file: 'transpiled.min.js',
129// mappings: 'AAEE',
130// sources: ['helloworld.js'],
131// version: 3,
132// };
133```
134
135### Advanced control of the loading graph
136
137#### `source`
138
139The `source` property can overridden to any value to change the location of the current load. Eg,
140for an original source file, it allows us to change the location to the original source regardless
141of what the sourcemap source entry says. And for transformed files, it allows us to change the
142relative resolving location for child sources of the loaded sourcemap.
143
144```js
145const remapped = remapping(
146 minifiedTransformedMap,
147 (file, ctx) => {
148
149 if (file === 'transformed.js') {
150 // We pretend the transformed.js file actually exists in the 'src/' directory. When the nested
151 // source files are loaded, they will now be relative to `src/`.
152 ctx.source = 'src/transformed.js';
153 return transformedMap;
154 }
155
156 console.assert(file === 'src/helloworld.js');
157 // We could futher change the source of this original file, eg, to be inside a nested directory
158 // itself. This will be reflected in the remapped sourcemap.
159 ctx.source = 'src/nested/transformed.js';
160 return null;
161 }
162);
163
164console.log(remapped);
165// {
166// …,
167// sources: ['src/nested/helloworld.js'],
168// };
169```
170
171
172#### `content`
173
174The `content` property can be overridden when we encounter an original source file. Eg, this allows
175you to manually provide the source content of the original file regardless of whether the
176`sourcesContent` field is present in the parent sourcemap. It can also be set to `null` to remove
177the source content.
178
179```js
180const remapped = remapping(
181 minifiedTransformedMap,
182 (file, ctx) => {
183
184 if (file === 'transformed.js') {
185 // transformedMap does not include a `sourcesContent` field, so usually the remapped sourcemap
186 // would not include any `sourcesContent` values.
187 return transformedMap;
188 }
189
190 console.assert(file === 'helloworld.js');
191 // We can read the file to provide the source content.
192 ctx.content = fs.readFileSync(file, 'utf8');
193 return null;
194 }
195);
196
197console.log(remapped);
198// {
199// …,
200// sourcesContent: [
201// 'console.log("Hello world!")',
202// ],
203// };
204```
205
206### Options
207
208#### excludeContent
209
210By default, `excludeContent` is `false`. Passing `{ excludeContent: true }` will exclude the
211`sourcesContent` field from the returned sourcemap. This is mainly useful when you want to reduce
212the size out the sourcemap.
213
214#### decodedMappings
215
216By default, `decodedMappings` is `false`. Passing `{ decodedMappings: true }` will leave the
217`mappings` field in a [decoded state](https://github.com/rich-harris/sourcemap-codec) instead of
218encoding into a VLQ string.
Note: See TracBrowser for help on using the repository browser.