Skip to content

Commit

Permalink
feat: add the ability to ignore-list sources (#243)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
bmeurer and antfu committed Feb 22, 2023
1 parent d4e9c31 commit e238f04
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 9 deletions.
16 changes: 13 additions & 3 deletions README.md
Expand Up @@ -66,10 +66,11 @@ You can pass an options argument:

```js
const s = new MagicString(someCode, {
// both these options will be used if you later
// call `bundle.addSource( s )` - see below
// these options will be used if you later call `bundle.addSource( s )` - see below
filename: 'foo.js',
indentExclusionRanges: [/*...*/]
indentExclusionRanges: [/*...*/],
// market source as ignore in DevTools, see below #Bundling
ignoreList: false
});
```

Expand Down Expand Up @@ -251,6 +252,15 @@ bundle.addSource({
content: new MagicString('console.log( answer )')
});

// Sources can be marked as ignore-listed, which provides a hint to debuggers
// to not step into this code and also don't show the source files depending
// on user preferences.
bundle.addSource({
filename: 'some-3rdparty-library.js',
content: new MagicString('function myLib(){}'),
ignoreList: false // <--
})

// Advanced: a source can include an `indentExclusionRanges` property
// alongside `filename` and `content`. This will be passed to `s.indent()`
// - see documentation above
Expand Down
20 changes: 15 additions & 5 deletions index.d.ts
Expand Up @@ -65,7 +65,17 @@ export class SourceMap {

export class Bundle {
constructor(options?: BundleOptions);
addSource(source: MagicString | { filename?: string, content: MagicString }): Bundle;
/**
* Adds the specified source to the bundle, which can either be a `MagicString` object directly,
* or an options object that holds a magic string `content` property and optionally provides
* a `filename` for the source within the bundle, as well as an optional `ignoreList` hint
* (which defaults to `false`). The `filename` is used when constructing the source map for the
* bundle, to identify this `source` in the source map's `sources` field. The `ignoreList` hint
* is used to populate the `x_google_ignoreList` extension field in the source map, which is a
* mechanism for tools to signal to debuggers that certain sources should be ignored by default
* (depending on user preferences).
*/
addSource(source: MagicString | { filename?: string, content: MagicString, ignoreList?: boolean }): Bundle;
append(str: string, options?: BundleOptions): Bundle;
clone(): Bundle;
generateMap(options?: SourceMapOptions): SourceMap;
Expand Down Expand Up @@ -117,7 +127,7 @@ export default class MagicString {
append(content: string): MagicString;
/**
* Appends the specified content at the index in the original string.
* If a range *ending* with index is subsequently moved, the insert will be moved with it.
* If a range *ending* with index is subsequently moved, the insert will be moved with it.
* See also `s.prependLeft(...)`.
*/
appendLeft(index: number, content: string): MagicString;
Expand Down Expand Up @@ -162,13 +172,13 @@ export default class MagicString {
*/
move(start: number, end: number, index: number): MagicString;
/**
* Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in
* Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in
* that range. The same restrictions as `s.remove()` apply.
*
* The fourth argument is optional. It can have a storeName property — if true, the original name will be stored
* for later inclusion in a sourcemap's names array — and a contentOnly property which determines whether only
* the content is overwritten, or anything that was appended/prepended to the range as well.
*
*
* It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content.
*/
overwrite(start: number, end: number, content: string, options?: boolean | OverwriteOptions): MagicString;
Expand All @@ -181,7 +191,7 @@ export default class MagicString {
*/
update(start: number, end: number, content: string, options?: boolean | UpdateOptions): MagicString;
/**
* Prepends the string with the specified content.
* Prepends the string with the specified content.
*/
prepend(content: string): MagicString;
/**
Expand Down
11 changes: 10 additions & 1 deletion src/Bundle.js
Expand Up @@ -31,7 +31,7 @@ export default class Bundle {
);
}

['filename', 'indentExclusionRanges', 'separator'].forEach((option) => {
['filename', 'ignoreList', 'indentExclusionRanges', 'separator'].forEach((option) => {
if (!hasOwnProp.call(source, option)) source[option] = source.content[option];
});

Expand Down Expand Up @@ -84,6 +84,7 @@ export default class Bundle {

generateDecodedMap(options = {}) {
const names = [];
let x_google_ignoreList = undefined;
this.sources.forEach((source) => {
Object.keys(source.content.storedNames).forEach((name) => {
if (!~names.indexOf(name)) names.push(name);
Expand Down Expand Up @@ -141,6 +142,13 @@ export default class Bundle {
if (magicString.outro) {
mappings.advance(magicString.outro);
}

if (source.ignoreList && sourceIndex !== -1) {
if (x_google_ignoreList === undefined) {
x_google_ignoreList = [];
}
x_google_ignoreList.push(sourceIndex);
}
});

return {
Expand All @@ -153,6 +161,7 @@ export default class Bundle {
}),
names,
mappings: mappings.raw,
x_google_ignoreList,
};
}

Expand Down
2 changes: 2 additions & 0 deletions src/MagicString.js
Expand Up @@ -34,6 +34,7 @@ export default class MagicString {
sourcemapLocations: { writable: true, value: new BitSet() },
storedNames: { writable: true, value: {} },
indentStr: { writable: true, value: undefined },
ignoreList: { writable: true, value: options.ignoreList },
});

if (DEBUG) {
Expand Down Expand Up @@ -168,6 +169,7 @@ export default class MagicString {
sourcesContent: options.includeContent ? [this.original] : undefined,
names,
mappings: mappings.raw,
x_google_ignoreList: this.ignoreList ? [sourceIndex] : undefined
};
}

Expand Down
38 changes: 38 additions & 0 deletions test/MagicString.Bundle.js
Expand Up @@ -27,17 +27,32 @@ describe('MagicString.Bundle', () => {
assert.strictEqual(b.sources[0].indentExclusionRanges, array);
});

it('should accept ignore-list hint', () => {
const b = new MagicString.Bundle();
const foo = new MagicString('foo', {filename: 'foo.js'});
const bar = new MagicString('bar', {filename: 'bar.js'});

b.addSource({content: foo, ignoreList: true});
b.addSource({content: bar, ignoreList: false});
assert.strictEqual(b.sources[0].content, foo);
assert.strictEqual(b.sources[0].ignoreList, true);
assert.strictEqual(b.sources[1].content, bar);
assert.strictEqual(b.sources[1].ignoreList, false);
});

it('respects MagicString init options with { content: source }', () => {
const b = new MagicString.Bundle();
const array = [];
const source = new MagicString('abcdefghijkl', {
filename: 'foo.js',
ignoreList: false,
indentExclusionRanges: array
});

b.addSource({ content: source });
assert.strictEqual(b.sources[0].content, source);
assert.strictEqual(b.sources[0].filename, 'foo.js');
assert.strictEqual(b.sources[0].ignoreList, false);
assert.strictEqual(b.sources[0].indentExclusionRanges, array);
});
});
Expand Down Expand Up @@ -345,6 +360,29 @@ describe('MagicString.Bundle', () => {
assert.equal(loc.source, 'three.js');
});

it('should generate x_google_ignoreList correctly', () => {
const b = new MagicString.Bundle();

const one = new MagicString('function one () {}', { filename: 'one.js' });
const two = new MagicString('function two () {}', { filename: 'two.js' });
const three = new MagicString('function three () {}', { filename: 'three.js' });
const four = new MagicString('function four () {}', { filename: 'four.js' });

b.addSource({ content: one, ignoreList: false });
b.addSource({ content: two, ignoreList: true });
b.addSource({ content: three, ignoreList: true });
b.addSource({ content: four });

const map = b.generateMap({
file: 'output.js'
});

assert.deepEqual(map.x_google_ignoreList, [
map.sources.indexOf('two.js'),
map.sources.indexOf('three.js')
]);
});

it('handles prepended content', () => {
const b = new MagicString.Bundle();

Expand Down
16 changes: 16 additions & 0 deletions test/MagicString.js
Expand Up @@ -13,6 +13,12 @@ describe('MagicString', () => {

assert.equal(s.filename, 'foo.js');
});

it('stores ignore-list hint', () => {
const s = new MagicString('abc', { ignoreList: true });

assert.equal(s.ignoreList, true);
});
});

describe('append', () => {
Expand Down Expand Up @@ -418,6 +424,16 @@ describe('MagicString', () => {
const map = s.generateMap();
assert.equal(map.mappings, 'IAAA');
});

it('generates x_google_ignoreList', () => {
const s = new MagicString('function foo(){}', {
ignoreList: true
});

const map = s.generateMap({ source: 'foo.js' });
assert.deepEqual(map.sources, ['foo.js']);
assert.deepEqual(map.x_google_ignoreList, [0]);
});
});

describe('getIndentString', () => {
Expand Down

0 comments on commit e238f04

Please sign in to comment.