Skip to content

Commit

Permalink
handle webpack:// prefix in SourceMap sources
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Dec 27, 2019
1 parent dcc45dd commit 6b9884e
Show file tree
Hide file tree
Showing 23 changed files with 411 additions and 18 deletions.
5 changes: 5 additions & 0 deletions lib/EvalSourceMapDevToolModuleTemplatePlugin.js
Expand Up @@ -6,6 +6,7 @@

const { RawSource } = require("webpack-sources");
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
const { absolutify } = require("./util/identifier");

const cache = new WeakMap();

Expand Down Expand Up @@ -60,7 +61,11 @@ class EvalSourceMapDevToolModuleTemplatePlugin {
obj[key] = sourceMap[key];
return obj;
}, {});
const context = this.compilation.compiler.options.context;
const modules = sourceMap.sources.map(source => {
if (source.startsWith("webpack://")) {
source = absolutify(context, source.slice(10));
}
const module = self.compilation.findModule(source);
return module || source;
});
Expand Down
36 changes: 20 additions & 16 deletions lib/SourceMapDevToolPlugin.js
Expand Up @@ -9,6 +9,7 @@ const { ConcatSource, RawSource } = require("webpack-sources");
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
const SourceMapDevToolModuleOptionsPlugin = require("./SourceMapDevToolModuleOptionsPlugin");
const createHash = require("./util/createHash");
const { absolutify } = require("./util/identifier");

const validateOptions = require("schema-utils");
const schema = require("../schemas/plugins/SourceMapDevToolPlugin.json");
Expand Down Expand Up @@ -68,16 +69,24 @@ const getTaskForFile = (file, asset, chunk, options, compilation) => {
sourceMap = asset.map(options);
source = asset.source();
}
if (sourceMap) {
return {
chunk,
file,
asset,
source,
sourceMap,
modules: undefined
};
}
if (!sourceMap || typeof source !== "string") return;
const context = compilation.options.context;
const modules = sourceMap.sources.map(source => {
if (source.startsWith("webpack://")) {
source = absolutify(context, source.slice(10));
}
const module = compilation.findModule(source);
return module || source;
});

return {
chunk,
file,
asset,
source,
sourceMap,
modules
};
};

class SourceMapDevToolPlugin {
Expand Down Expand Up @@ -212,10 +221,7 @@ class SourceMapDevToolPlugin {
);

if (task) {
const modules = task.sourceMap.sources.map(source => {
const module = compilation.findModule(source);
return module || source;
});
const modules = task.modules;

for (let idx = 0; idx < modules.length; idx++) {
const module = modules[idx];
Expand All @@ -234,8 +240,6 @@ class SourceMapDevToolPlugin {
}
}

task.modules = modules;

tasks.push(task);
}
});
Expand Down
25 changes: 25 additions & 0 deletions lib/util/identifier.js
@@ -1,6 +1,17 @@
"use strict";
const path = require("path");

/**
* @param {string} context context for relative path
* @param {string} relativePath path
* @returns {string} absolute path
*/
const requestToAbsolute = (context, relativePath) => {
if (relativePath.startsWith("./") || relativePath.startsWith("../"))
return path.join(context, relativePath);
return relativePath;
};

/**
* @typedef {Object} MakeRelativePathsCache
* @property {Map<string, Map<string, string>>=} relativePaths
Expand Down Expand Up @@ -100,3 +111,17 @@ exports.contextify = (context, request) => {
})
.join("!");
};

/**
* @param {string} context absolute context path
* @param {string} request any request string
* @returns {string} a new request string using absolute paths when possible
*/
const _absolutify = (context, request) => {
return request
.split("!")
.map(r => requestToAbsolute(context, r))
.join("!");
};

exports.absolutify = _absolutify;
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -30,10 +30,12 @@
"webpack-sources": "^1.4.1"
},
"devDependencies": {
"@babel/core": "^7.7.2",
"@types/node": "^10.12.21",
"@types/tapable": "^1.0.1",
"@types/webpack-sources": "^0.1.4",
"@yarnpkg/lockfile": "^1.1.0",
"babel-loader": "^8.0.6",
"benchmark": "^2.1.1",
"bundle-loader": "~0.5.0",
"coffee-loader": "^0.9.0",
Expand Down
12 changes: 12 additions & 0 deletions test/StatsTestCases.test.js
Expand Up @@ -59,6 +59,17 @@ describe("StatsTestCases", () => {
if (fs.existsSync(path.join(base, testName, "webpack.config.js"))) {
options = require(path.join(base, testName, "webpack.config.js"));
}
let testConfig = {};
try {
// try to load a test file
testConfig = Object.assign(
testConfig,
require(path.join(base, testName, "test.config.js"))
);
} catch (e) {
// ignored
}

(Array.isArray(options) ? options : [options]).forEach(options => {
if (!options.context) options.context = path.join(base, testName);
if (!options.output) options.output = options.output || {};
Expand Down Expand Up @@ -152,6 +163,7 @@ describe("StatsTestCases", () => {
.replace(/(\w)\\(\w)/g, "$1/$2")
.replace(/ dependencies:Xms/g, "");
expect(actual).toMatchSnapshot();
if (testConfig.validate) testConfig.validate(stats, stderr.toString());
done();
});
});
Expand Down
56 changes: 56 additions & 0 deletions test/__snapshots__/StatsTestCases.test.js.snap
Expand Up @@ -692,6 +692,62 @@ exports[`StatsTestCases should print correct stats for concat-and-sideeffects 1`
ModuleConcatenation bailout: Module is not in any chunk"
`;

exports[`StatsTestCases should print correct stats for context-independence 1`] = `
"Hash: 05b3bf99e7372023e97905b3bf99e7372023e979db9f3b8e4ef7c772a36ddb9f3b8e4ef7c772a36d
Child
Hash: 05b3bf99e7372023e979
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
1-4dcf1f7bb7b9da3c54c7.js 424 bytes 1 [emitted] [immutable]
1-4dcf1f7bb7b9da3c54c7.js.map 336 bytes 1 [emitted] [dev]
main-95e076639e5472415472.js 8.32 KiB 0 [emitted] [immutable] main
main-95e076639e5472415472.js.map 8.32 KiB 0 [emitted] [dev] main
Entrypoint main = main-95e076639e5472415472.js main-95e076639e5472415472.js.map
[0] ./a/index.js 40 bytes {0} [built]
[1] ./a/chunk.js + 1 modules 66 bytes {1} [built]
| ./a/chunk.js 47 bytes [built]
| ./a/module.js 19 bytes [built]
Child
Hash: 05b3bf99e7372023e979
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
1-4dcf1f7bb7b9da3c54c7.js 424 bytes 1 [emitted] [immutable]
1-4dcf1f7bb7b9da3c54c7.js.map 336 bytes 1 [emitted] [dev]
main-95e076639e5472415472.js 8.32 KiB 0 [emitted] [immutable] main
main-95e076639e5472415472.js.map 8.32 KiB 0 [emitted] [dev] main
Entrypoint main = main-95e076639e5472415472.js main-95e076639e5472415472.js.map
[0] ./b/index.js 40 bytes {0} [built]
[1] ./b/chunk.js + 1 modules 66 bytes {1} [built]
| ./b/chunk.js 47 bytes [built]
| ./b/module.js 19 bytes [built]
Child
Hash: db9f3b8e4ef7c772a36d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
1-4dcf1f7bb7b9da3c54c7.js 940 bytes 1 [emitted] [immutable]
main-95e076639e5472415472.js 8.66 KiB 0 [emitted] [immutable] main
Entrypoint main = main-95e076639e5472415472.js
[0] ./a/index.js 40 bytes {0} [built]
[1] ./a/chunk.js + 1 modules 66 bytes {1} [built]
| ./a/chunk.js 47 bytes [built]
| ./a/module.js 19 bytes [built]
Child
Hash: db9f3b8e4ef7c772a36d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
1-4dcf1f7bb7b9da3c54c7.js 940 bytes 1 [emitted] [immutable]
main-95e076639e5472415472.js 8.66 KiB 0 [emitted] [immutable] main
Entrypoint main = main-95e076639e5472415472.js
[0] ./b/index.js 40 bytes {0} [built]
[1] ./b/chunk.js + 1 modules 66 bytes {1} [built]
| ./b/chunk.js 47 bytes [built]
| ./b/module.js 19 bytes [built]"
`;

exports[`StatsTestCases should print correct stats for define-plugin 1`] = `
"Hash: 97d5f15cb3086ba8eb8878ce8186fd9442bfeb83c3284590614d84a86804
Child
Expand Down
@@ -0,0 +1,19 @@
it("should run", () => {
require("./loader-source-root!");
require("./loader-source-root-slash!");
require("./loader-source-root-source-slash!");
require("./loader-source-root-2-slash!");
require("./loader-no-source-root!");
require("./loader-pre-relative!");
});

it("should generate the correct SourceMap", function() {
var fs = require("fs");
var source = JSON.parse(fs.readFileSync(__filename + ".map", "utf-8"));
expect(source.sources).toContain("webpack:///./folder/test1.txt");
expect(source.sources).toContain("webpack:///./folder/test2.txt");
expect(source.sources).toContain("webpack:///./folder/test3.txt");
expect(source.sources).toContain("webpack:///./folder/test4.txt");
expect(source.sources).toContain("webpack:///./folder/test5.txt");
expect(source.sources).toContain("webpack:///./folder/test6.txt");
});
@@ -0,0 +1,10 @@
const path = require("path");
module.exports = function() {
this.callback(null, "module.exports = 'ok';", {
version: 3,
file: "/should/be/removed",
sources: [path.join(__dirname, "folder", "test5.txt")],
sourcesContent: ["Test"],
mappings: "AAAA"
});
};
@@ -0,0 +1,9 @@
module.exports = function() {
this.callback(null, "module.exports = 'ok';", {
version: 3,
file: "/should/be/removed",
sources: ["webpack://./folder/test6.txt"],
sourcesContent: ["Test"],
mappings: "AAAA"
});
};
@@ -0,0 +1,11 @@
const path = require("path");
module.exports = function() {
this.callback(null, "module.exports = 'ok';", {
version: 3,
file: "/should/be/removed",
sourceRoot: path.join(__dirname, "folder") + "/",
sources: ["/test4.txt"],
sourcesContent: ["Test"],
mappings: "AAAA"
});
};
@@ -0,0 +1,11 @@
const path = require("path");
module.exports = function() {
this.callback(null, "module.exports = 'ok';", {
version: 3,
file: "/should/be/removed",
sourceRoot: path.join(__dirname, "folder") + "/",
sources: ["test3.txt"],
sourcesContent: ["Test"],
mappings: "AAAA"
});
};
@@ -0,0 +1,11 @@
const path = require("path");
module.exports = function() {
this.callback(null, "module.exports = 'ok';", {
version: 3,
file: "/should/be/removed",
sourceRoot: path.join(__dirname, "folder"),
sources: ["/test2.txt"],
sourcesContent: ["Test"],
mappings: "AAAA"
});
};
@@ -0,0 +1,11 @@
const path = require("path");
module.exports = function() {
this.callback(null, "module.exports = 'ok';", {
version: 3,
file: "/should/be/removed",
sourceRoot: path.join(__dirname, "folder"),
sources: ["test1.txt"],
sourcesContent: ["Test"],
mappings: "AAAA"
});
};
@@ -0,0 +1,8 @@
module.exports = {
mode: "development",
node: {
__dirname: false,
__filename: false
},
devtool: "source-map"
};
2 changes: 2 additions & 0 deletions test/statsCases/context-independence/a/chunk.js
@@ -0,0 +1,2 @@
import test from "./module";
console.log(test);
2 changes: 2 additions & 0 deletions test/statsCases/context-independence/a/index.js
@@ -0,0 +1,2 @@
console.log("test");
import("./chunk");
1 change: 1 addition & 0 deletions test/statsCases/context-independence/a/module.js
@@ -0,0 +1 @@
export default 42;
2 changes: 2 additions & 0 deletions test/statsCases/context-independence/b/chunk.js
@@ -0,0 +1,2 @@
import test from "./module";
console.log(test);
2 changes: 2 additions & 0 deletions test/statsCases/context-independence/b/index.js
@@ -0,0 +1,2 @@
console.log("test");
import("./chunk");
1 change: 1 addition & 0 deletions test/statsCases/context-independence/b/module.js
@@ -0,0 +1 @@
export default 42;
10 changes: 10 additions & 0 deletions test/statsCases/context-independence/test.config.js
@@ -0,0 +1,10 @@
module.exports = {
validate(stats) {
const a = stats.stats[0].compilation.hash;
const b = stats.stats[1].compilation.hash;
expect(a).toBe(b);
const c = stats.stats[2].compilation.hash;
const d = stats.stats[3].compilation.hash;
expect(c).toBe(d);
}
};

0 comments on commit 6b9884e

Please sign in to comment.