Skip to content

Commit

Permalink
Support inline base64 source maps
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett committed Jul 22, 2018
1 parent 00c87e1 commit 2fd004f
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 33 deletions.
36 changes: 26 additions & 10 deletions src/assets/JSAsset.js
Expand Up @@ -23,6 +23,8 @@ const GLOBAL_RE = /\b(?:process|__dirname|__filename|global|Buffer|define)\b/;
const FS_RE = /\breadFileSync\b/;
const SW_RE = /\bnavigator\s*\.\s*serviceWorker\s*\.\s*register\s*\(/;
const WORKER_RE = /\bnew\s*Worker\s*\(/;
const SOURCEMAP_RE = /\/\/\s*[@#]\s*sourceMappingURL\s*=\s*([^\s]+)/;
const DATA_URL_RE = /^data:[^;]+(?:;charset=[^;]+)?;base64,(.*)/;

class JSAsset extends Asset {
constructor(name, options) {
Expand Down Expand Up @@ -107,26 +109,40 @@ class JSAsset extends Asset {
walk.ancestor(this.ast, collectDependencies, this);
}

async pretransform() {
async loadSourceMap() {
// Get original sourcemap if there is any
let sourceMapLine = this.contents.lastIndexOf('//# sourceMappingURL=');
if (sourceMapLine > -1) {
let sourceMapReference = this.contents.substring(sourceMapLine + 21);
this.contents = this.contents.substring(0, sourceMapLine);
let match = this.contents.match(SOURCEMAP_RE);
if (match) {
this.contents = this.contents.replace(SOURCEMAP_RE, '');

let url = match[1];
let dataURLMatch = url.match(DATA_URL_RE);

try {
this.sourceMap = JSON.parse(
await fs.readFile(
path.join(path.dirname(this.name), sourceMapReference)
)
);
let json;
if (dataURLMatch) {
json = new Buffer(dataURLMatch[1], 'base64').toString();
} else {
json = await fs.readFile(
path.join(path.dirname(this.name), url),
'utf8'
);
}

this.sourceMap = JSON.parse(json);

// Add as a dep so we watch the source map for changes.
this.addDependency(match[1], {includedInParent: true});
} catch (e) {
logger.warn(
`Could not load existing sourcemap of ${this.relativeName}.`
);
}
}
}

async pretransform() {
await this.loadSourceMap();
await babel(this);

// Inline environment variables
Expand Down
1 change: 1 addition & 0 deletions test/graphql.js
Expand Up @@ -31,6 +31,7 @@ describe('graphql', function() {
firstName
lastName
}
`.definitions
);
});
Expand Down
14 changes: 9 additions & 5 deletions test/integration/sourcemap-existing/sum.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 6 additions & 14 deletions test/integration/sourcemap-existing/sum.map
@@ -1,19 +1,11 @@
{
"version": 3,
"file": "sum.js",
"sourceRoot": "",
"sources": [
"sum.js"
"sum.coffee"
],
"names": [
"sum",
"a",
"b",
"module",
"exports"
],
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAASA,GAAT,CAAaC,CAAb,EAAgBC,CAAhB,EAAmB;AACjB,SAAOD,IAAIC,CAAX;AACD;;AAEDC,OAAOC,OAAP,GAAiBJ,GAAjB",
"file": "sum.map",
"sourceRoot": '',
"sourcesContent": [
"function sum(a, b) {\n return a + b;\n}\n\nmodule.exports = sum;\n\n"
]
"names": [],
"mappings": ";AAAA;EAAA,MAAM,CAAC,OAAP,GAAiB,CAAA,SAAA,KAAA;WAAA,SAAC,CAAD,EAAI,CAAJ;aAAU,CAAA,GAAI;IAAd;EAAA,CAAA,CAAA,CAAA,IAAA;AAAjB",
"sourcesContent": ["module.exports = (a, b) => a + b"]
}
5 changes: 5 additions & 0 deletions test/integration/sourcemap-inline/index.js
@@ -0,0 +1,5 @@
const sum = require('./sum');

module.exports = function() {
return sum(1, 2);
}
9 changes: 9 additions & 0 deletions test/integration/sourcemap-inline/sum.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 38 additions & 4 deletions test/sourcemaps.js
Expand Up @@ -220,7 +220,7 @@ describe('sourcemaps', function() {
]
});

let jsOutput = fs.readFileSync(b.name).toString();
let jsOutput = await fs.readFile(b.name, 'utf8');

let sourcemapReference = path.join(
__dirname,
Expand All @@ -229,13 +229,47 @@ describe('sourcemaps', function() {
);

assert(
fs.existsSync(path.join(sourcemapReference)),
await fs.exists(path.join(sourcemapReference)),
'referenced sourcemap should exist'
);

let map = await fs.readFile(path.join(sourcemapReference), 'utf8');
assert(
map.indexOf('module.exports = (a, b) => a + b') > -1,
'Sourcemap should contain the existing sourcemap'
);
mapValidator(jsOutput, map);
});

it('should load inline sourcemaps of libraries', async function() {
let b = await bundle(__dirname + '/integration/sourcemap-inline/index.js');

assertBundleTree(b, {
name: 'index.js',
assets: ['index.js', 'sum.js'],
childBundles: [
{
type: 'map'
}
]
});

let jsOutput = await fs.readFile(b.name, 'utf8');

let sourcemapReference = path.join(
__dirname,
'/dist/',
jsOutput.substring(jsOutput.lastIndexOf('//# sourceMappingURL') + 22)
);

assert(
await fs.exists(path.join(sourcemapReference)),
'referenced sourcemap should exist'
);

let map = fs.readFileSync(path.join(sourcemapReference)).toString();
let map = await fs.readFile(path.join(sourcemapReference), 'utf8');
assert(
map.indexOf('return a + b;') > -1,
map.indexOf('module.exports = (a, b) => a + b') > -1,
'Sourcemap should contain the existing sourcemap'
);
mapValidator(jsOutput, map);
Expand Down

0 comments on commit 2fd004f

Please sign in to comment.