Big News: Socket Selected for OpenAI's Cybersecurity Grant Program.Details
Socket
Book a DemoSign in
Socket

source-map-loader

Package Overview
Dependencies
Maintainers
8
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

source-map-loader - npm Package Compare versions

Comparing version
0.2.4
to
1.0.0
+6
dist/cjs.js
"use strict";
const loader = require('./index');
module.exports = loader.default;
module.exports.raw = loader.raw;
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = loader;
var _path = _interopRequireDefault(require("path"));
var _schemaUtils = _interopRequireDefault(require("schema-utils"));
var _loaderUtils = require("loader-utils");
var _options = _interopRequireDefault(require("./options.json"));
var _utils = require("./utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
async function loader(input, inputMap) {
const options = (0, _loaderUtils.getOptions)(this);
(0, _schemaUtils.default)(_options.default, options, {
name: 'Source Map Loader',
baseDataPath: 'options'
});
const {
sourceMappingURL,
replacementString
} = (0, _utils.getSourceMappingURL)(input);
const callback = this.async();
if (!sourceMappingURL) {
callback(null, input, inputMap);
return;
}
let sourceURL;
let sourceContent;
try {
({
sourceURL,
sourceContent
} = await (0, _utils.fetchFromURL)(this, this.context, sourceMappingURL));
} catch (error) {
this.emitWarning(error);
callback(null, input, inputMap);
return;
}
if (sourceURL) {
this.addDependency(sourceURL);
}
let map;
try {
map = JSON.parse(sourceContent.replace(/^\)\]\}'/, ''));
} catch (parseError) {
this.emitWarning(new Error(`Failed to parse source map from '${sourceURL}': ${parseError}`));
callback(null, input, inputMap);
return;
}
const context = sourceURL ? _path.default.dirname(sourceURL) : this.context;
if (map.sections) {
// eslint-disable-next-line no-param-reassign
map = await (0, _utils.flattenSourceMap)(map);
}
const resolvedSources = await Promise.all(map.sources.map(async (source, i) => {
// eslint-disable-next-line no-shadow
let sourceURL; // eslint-disable-next-line no-shadow
let sourceContent;
const originalSourceContent = map.sourcesContent && map.sourcesContent[i] ? map.sourcesContent[i] : null;
const skipReading = originalSourceContent !== null;
try {
({
sourceURL,
sourceContent
} = await (0, _utils.fetchFromURL)(this, context, source, map.sourceRoot, skipReading));
} catch (error) {
this.emitWarning(error);
sourceURL = source;
}
if (originalSourceContent) {
sourceContent = originalSourceContent;
}
if (sourceURL) {
this.addDependency(sourceURL);
}
return {
sourceURL,
sourceContent
};
}));
const newMap = { ...map
};
newMap.sources = [];
newMap.sourcesContent = [];
delete newMap.sourceRoot;
resolvedSources.forEach(source => {
// eslint-disable-next-line no-shadow
const {
sourceURL,
sourceContent
} = source;
newMap.sources.push(sourceURL || '');
newMap.sourcesContent.push(sourceContent || '');
});
const sourcesContentIsEmpty = newMap.sourcesContent.filter(entry => Boolean(entry)).length === 0;
if (sourcesContentIsEmpty) {
delete newMap.sourcesContent;
}
callback(null, input.replace(replacementString, ''), newMap);
}
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
const labelToNames = {
'866': 'IBM866',
'unicode-1-1-utf-8': 'UTF-8',
'utf-8': 'UTF-8',
utf8: 'UTF-8',
cp866: 'IBM866',
csibm866: 'IBM866',
ibm866: 'IBM866',
csisolatin2: 'ISO-8859-2',
'iso-8859-2': 'ISO-8859-2',
'iso-ir-101': 'ISO-8859-2',
'iso8859-2': 'ISO-8859-2',
iso88592: 'ISO-8859-2',
'iso_8859-2': 'ISO-8859-2',
'iso_8859-2:1987': 'ISO-8859-2',
l2: 'ISO-8859-2',
latin2: 'ISO-8859-2',
csisolatin3: 'ISO-8859-3',
'iso-8859-3': 'ISO-8859-3',
'iso-ir-109': 'ISO-8859-3',
'iso8859-3': 'ISO-8859-3',
iso88593: 'ISO-8859-3',
'iso_8859-3': 'ISO-8859-3',
'iso_8859-3:1988': 'ISO-8859-3',
l3: 'ISO-8859-3',
latin3: 'ISO-8859-3',
csisolatin4: 'ISO-8859-4',
'iso-8859-4': 'ISO-8859-4',
'iso-ir-110': 'ISO-8859-4',
'iso8859-4': 'ISO-8859-4',
iso88594: 'ISO-8859-4',
'iso_8859-4': 'ISO-8859-4',
'iso_8859-4:1988': 'ISO-8859-4',
l4: 'ISO-8859-4',
latin4: 'ISO-8859-4',
csisolatincyrillic: 'ISO-8859-5',
cyrillic: 'ISO-8859-5',
'iso-8859-5': 'ISO-8859-5',
'iso-ir-144': 'ISO-8859-5',
'iso8859-5': 'ISO-8859-5',
iso88595: 'ISO-8859-5',
'iso_8859-5': 'ISO-8859-5',
'iso_8859-5:1988': 'ISO-8859-5',
arabic: 'ISO-8859-6',
'asmo-708': 'ISO-8859-6',
csiso88596e: 'ISO-8859-6',
csiso88596i: 'ISO-8859-6',
csisolatinarabic: 'ISO-8859-6',
'ecma-114': 'ISO-8859-6',
'iso-8859-6': 'ISO-8859-6',
'iso-8859-6-e': 'ISO-8859-6',
'iso-8859-6-i': 'ISO-8859-6',
'iso-ir-127': 'ISO-8859-6',
'iso8859-6': 'ISO-8859-6',
iso88596: 'ISO-8859-6',
'iso_8859-6': 'ISO-8859-6',
'iso_8859-6:1987': 'ISO-8859-6',
csisolatingreek: 'ISO-8859-7',
'ecma-118': 'ISO-8859-7',
elot_928: 'ISO-8859-7',
greek: 'ISO-8859-7',
greek8: 'ISO-8859-7',
'iso-8859-7': 'ISO-8859-7',
'iso-ir-126': 'ISO-8859-7',
'iso8859-7': 'ISO-8859-7',
iso88597: 'ISO-8859-7',
'iso_8859-7': 'ISO-8859-7',
'iso_8859-7:1987': 'ISO-8859-7',
sun_eu_greek: 'ISO-8859-7',
csiso88598e: 'ISO-8859-8',
csisolatinhebrew: 'ISO-8859-8',
hebrew: 'ISO-8859-8',
'iso-8859-8': 'ISO-8859-8',
'iso-8859-8-e': 'ISO-8859-8',
'iso-ir-138': 'ISO-8859-8',
'iso8859-8': 'ISO-8859-8',
iso88598: 'ISO-8859-8',
'iso_8859-8': 'ISO-8859-8',
'iso_8859-8:1988': 'ISO-8859-8',
visual: 'ISO-8859-8',
csisolatin6: 'ISO-8859-10',
'iso-8859-10': 'ISO-8859-10',
'iso-ir-157': 'ISO-8859-10',
'iso8859-10': 'ISO-8859-10',
iso885910: 'ISO-8859-10',
l6: 'ISO-8859-10',
latin6: 'ISO-8859-10',
'iso-8859-13': 'ISO-8859-13',
'iso8859-13': 'ISO-8859-13',
iso885913: 'ISO-8859-13',
'iso-8859-14': 'ISO-8859-14',
'iso8859-14': 'ISO-8859-14',
iso885914: 'ISO-8859-14',
csisolatin9: 'ISO-8859-15',
'iso-8859-15': 'ISO-8859-15',
'iso8859-15': 'ISO-8859-15',
iso885915: 'ISO-8859-15',
'iso_8859-15': 'ISO-8859-15',
l9: 'ISO-8859-15',
'iso-8859-16': 'ISO-8859-16',
cskoi8r: 'KOI8-R',
koi: 'KOI8-R',
koi8: 'KOI8-R',
'koi8-r': 'KOI8-R',
koi8_r: 'KOI8-R',
'koi8-ru': 'KOI8-U',
'koi8-u': 'KOI8-U',
csmacintosh: 'macintosh',
mac: 'macintosh',
macintosh: 'macintosh',
'x-mac-roman': 'macintosh',
'dos-874': 'windows-874',
'iso-8859-11': 'windows-874',
'iso8859-11': 'windows-874',
iso885911: 'windows-874',
'tis-620': 'windows-874',
'windows-874': 'windows-874',
cp1250: 'windows-1250',
'windows-1250': 'windows-1250',
'x-cp1250': 'windows-1250',
cp1251: 'windows-1251',
'windows-1251': 'windows-1251',
'x-cp1251': 'windows-1251',
'ansi_x3.4-1968': 'windows-1252',
ascii: 'windows-1252',
cp1252: 'windows-1252',
cp819: 'windows-1252',
csisolatin1: 'windows-1252',
ibm819: 'windows-1252',
'iso-8859-1': 'windows-1252',
'iso-ir-100': 'windows-1252',
'iso8859-1': 'windows-1252',
iso88591: 'windows-1252',
'iso_8859-1': 'windows-1252',
'iso_8859-1:1987': 'windows-1252',
l1: 'windows-1252',
latin1: 'windows-1252',
'us-ascii': 'windows-1252',
'windows-1252': 'windows-1252',
'x-cp1252': 'windows-1252',
cp1253: 'windows-1253',
'windows-1253': 'windows-1253',
'x-cp1253': 'windows-1253',
cp1254: 'windows-1254',
csisolatin5: 'windows-1254',
'iso-8859-9': 'windows-1254',
'iso-ir-148': 'windows-1254',
'iso8859-9': 'windows-1254',
iso88599: 'windows-1254',
'iso_8859-9': 'windows-1254',
'iso_8859-9:1989': 'windows-1254',
l5: 'windows-1254',
latin5: 'windows-1254',
'windows-1254': 'windows-1254',
'x-cp1254': 'windows-1254',
cp1255: 'windows-1255',
'windows-1255': 'windows-1255',
'x-cp1255': 'windows-1255',
cp1256: 'windows-1256',
'windows-1256': 'windows-1256',
'x-cp1256': 'windows-1256',
cp1257: 'windows-1257',
'windows-1257': 'windows-1257',
'x-cp1257': 'windows-1257',
cp1258: 'windows-1258',
'windows-1258': 'windows-1258',
'x-cp1258': 'windows-1258',
chinese: 'GBK',
csgb2312: 'GBK',
csiso58gb231280: 'GBK',
gb2312: 'GBK',
gb_2312: 'GBK',
'gb_2312-80': 'GBK',
gbk: 'GBK',
'iso-ir-58': 'GBK',
'x-gbk': 'GBK',
gb18030: 'gb18030',
big5: 'Big5',
'big5-hkscs': 'Big5',
'cn-big5': 'Big5',
csbig5: 'Big5',
'x-x-big5': 'Big5',
cseucpkdfmtjapanese: 'EUC-JP',
'euc-jp': 'EUC-JP',
'x-euc-jp': 'EUC-JP',
csshiftjis: 'Shift_JIS',
ms932: 'Shift_JIS',
ms_kanji: 'Shift_JIS',
'shift-jis': 'Shift_JIS',
shift_jis: 'Shift_JIS',
sjis: 'Shift_JIS',
'windows-31j': 'Shift_JIS',
'x-sjis': 'Shift_JIS',
cseuckr: 'EUC-KR',
csksc56011987: 'EUC-KR',
'euc-kr': 'EUC-KR',
'iso-ir-149': 'EUC-KR',
korean: 'EUC-KR',
'ks_c_5601-1987': 'EUC-KR',
'ks_c_5601-1989': 'EUC-KR',
ksc5601: 'EUC-KR',
ksc_5601: 'EUC-KR',
'windows-949': 'EUC-KR',
'utf-16be': 'UTF-16BE',
'utf-16': 'UTF-16LE',
'utf-16le': 'UTF-16LE'
};
var _default = labelToNames;
exports.default = _default;
{
"type": "object",
"additionalProperties": false
}
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getSourceMappingURL = getSourceMappingURL;
exports.fetchFromURL = fetchFromURL;
exports.flattenSourceMap = flattenSourceMap;
var _path = _interopRequireDefault(require("path"));
var _url = _interopRequireDefault(require("url"));
var _sourceMap = _interopRequireDefault(require("source-map"));
var _dataUrls = _interopRequireDefault(require("data-urls"));
var _iconvLite = require("iconv-lite");
var _loaderUtils = require("loader-utils");
var _labelsToNames = _interopRequireDefault(require("./labels-to-names"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Matches only the last occurrence of sourceMappingURL
const innerRegex = /\s*[#@]\s*sourceMappingURL\s*=\s*([^\s'"]*)\s*/;
/* eslint-disable prefer-template */
const sourceMappingURLRegex = RegExp('(?:' + '/\\*' + '(?:\\s*\r?\n(?://)?)?' + '(?:' + innerRegex.source + ')' + '\\s*' + '\\*/' + '|' + '//(?:' + innerRegex.source + ')' + ')' + '\\s*');
/* eslint-enable prefer-template */
function labelToName(label) {
const labelLowercase = String(label).trim().toLowerCase();
return _labelsToNames.default[labelLowercase] || null;
}
async function flattenSourceMap(map) {
const consumer = await new _sourceMap.default.SourceMapConsumer(map);
const generatedMap = map.file ? new _sourceMap.default.SourceMapGenerator({
file: map.file
}) : new _sourceMap.default.SourceMapGenerator();
consumer.sources.forEach(sourceFile => {
const sourceContent = consumer.sourceContentFor(sourceFile, true);
generatedMap.setSourceContent(sourceFile, sourceContent);
});
consumer.eachMapping(mapping => {
const {
source
} = consumer.originalPositionFor({
line: mapping.generatedLine,
column: mapping.generatedColumn
});
const mappings = {
source,
original: {
line: mapping.originalLine,
column: mapping.originalColumn
},
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn
}
};
if (source) {
generatedMap.addMapping(mappings);
}
});
return generatedMap.toJSON();
}
function getSourceMappingURL(code) {
const lines = code.split(/^/m);
let match;
for (let i = lines.length - 1; i >= 0; i--) {
match = lines[i].match(sourceMappingURLRegex);
if (match) {
break;
}
}
return {
sourceMappingURL: match ? match[1] || match[2] || '' : null,
replacementString: match ? match[0] : null
};
}
function getAbsolutePath(context, url, sourceRoot) {
const request = (0, _loaderUtils.urlToRequest)(url, true);
if (sourceRoot) {
if (_path.default.isAbsolute(sourceRoot)) {
return _path.default.join(sourceRoot, request);
}
return _path.default.join(context, (0, _loaderUtils.urlToRequest)(sourceRoot, true), request);
}
return _path.default.join(context, request);
}
function fetchFromDataURL(loaderContext, sourceURL) {
const dataURL = (0, _dataUrls.default)(sourceURL);
if (dataURL) {
dataURL.encodingName = labelToName(dataURL.mimeType.parameters.get('charset')) || 'UTF-8';
return (0, _iconvLite.decode)(dataURL.body, dataURL.encodingName);
}
throw new Error(`Failed to parse source map from "data" URL: ${sourceURL}`);
}
async function fetchFromFilesystem(loaderContext, sourceURL) {
let buffer;
try {
buffer = await new Promise((resolve, reject) => {
loaderContext.fs.readFile(sourceURL, (error, data) => {
if (error) {
return reject(error);
}
return resolve(data);
});
});
} catch (error) {
throw new Error(`Failed to parse source map from '${sourceURL}' file: ${error}`);
}
return buffer.toString();
}
async function fetchFromURL(loaderContext, context, url, sourceRoot, skipReading = false) {
// 1. It's an absolute url and it is not `windows` path like `C:\dir\file`
if (/^[a-z][a-z0-9+.-]*:/i.test(url) && !_path.default.win32.isAbsolute(url)) {
const {
protocol
} = _url.default.parse(url);
if (protocol === 'data:') {
const sourceContent = fetchFromDataURL(loaderContext, url);
return {
sourceContent
};
}
if (protocol === 'file:') {
const pathFromURL = _url.default.fileURLToPath(url);
const sourceURL = _path.default.normalize(pathFromURL);
let sourceContent;
if (!skipReading) {
sourceContent = await fetchFromFilesystem(loaderContext, sourceURL);
}
return {
sourceURL,
sourceContent
};
}
throw new Error(`Failed to parse source map: "${url}" URL is not supported`);
} // 2. It's a scheme-relative
if (/^\/\//.test(url)) {
throw new Error(`Failed to parse source map: "${url}" URL is not supported`);
} // 3. Absolute path
if (_path.default.isAbsolute(url)) {
const sourceURL = _path.default.normalize(url);
let sourceContent;
if (!skipReading) {
sourceContent = await fetchFromFilesystem(loaderContext, sourceURL);
}
return {
sourceURL,
sourceContent
};
} // 4. Relative path
const sourceURL = getAbsolutePath(context, url, sourceRoot);
let sourceContent;
if (!skipReading) {
sourceContent = await fetchFromFilesystem(loaderContext, sourceURL);
}
return {
sourceURL,
sourceContent
};
}
+25
-1

@@ -1,5 +0,29 @@

# Change Log
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [1.0.0](https://github.com/webpack-contrib/source-map-loader/compare/v0.2.4...v1.0.0) (2020-05-26)
### ⚠ BREAKING CHANGES
* minimum supported Node.js version is `10.13`
* minimum supported `webpack` version is `4`
### Features
* support indexed source maps ([c18d1f9](https://github.com/webpack-contrib/source-map-loader/commit/c18d1f9495fce229d21993aba1d215cc75986d84))
* support `charsert` for Data URLs
### Bug Fixes
* absolute path for sources ([b64f7d8](https://github.com/webpack-contrib/source-map-loader/commit/b64f7d82de27769c8bbd2be280faf4f9f97492d5))
* avoid crash on big data URL source maps ([7f769aa](https://github.com/webpack-contrib/source-map-loader/commit/7f769aa5a09d362cf29eeb52f4c8155360e1afad))
* improve performance ([#101](https://github.com/webpack-contrib/source-map-loader/issues/101)) ([4c39c22](https://github.com/webpack-contrib/source-map-loader/commit/4c39c228ae215b43d6c90fd1727d572dfd3d5929))
* use webpack fs ([#105](https://github.com/webpack-contrib/source-map-loader/issues/105)) ([1e785a1](https://github.com/webpack-contrib/source-map-loader/commit/1e785a1114afe2f40a9f2361d8a326a99b5050e6))
* support `file` protocol
* improve error messages
* avoid conflicts with other source maps
* fix compatibility with `5` version of `webpack`
<a name="0.2.4"></a>

@@ -6,0 +30,0 @@ ## [0.2.4](https://github.com/webpack-contrib/source-map-loader/compare/v0.2.3...v0.2.4) (2018-08-14)

{
"name": "source-map-loader",
"version": "0.2.4",
"version": "1.0.0",
"description": "extracts inlined source map and offers it to webpack",
"license": "MIT",
"repository": "webpack-contrib/source-map-loader",
"author": "Tobias Koppers @sokra",
"description": "extracts inlined source map and offers it to webpack",
"homepage": "https://github.com/webpack-contrib/source-map-loader",
"bugs": "https://github.com/webpack-contrib/source-map-loader/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"main": "dist/cjs.js",
"engines": {
"node": ">= 6"
"node": ">= 10.13.0"
},
"scripts": {
"test": "mocha -R spec",
"travis:test": "mocha -R spec",
"release": "standard-version"
"start": "npm run build -- -w",
"clean": "del-cli dist",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production babel src -d dist --copy-files",
"commitlint": "commitlint --from=master",
"security": "npm audit",
"lint:prettier": "prettier --list-different .",
"lint:js": "eslint --cache .",
"lint": "npm-run-all -l -p \"lint:**\"",
"test:only": "cross-env NODE_ENV=test jest",
"test:watch": "npm run test:only -- --watch",
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
"pretest": "npm run lint",
"test": "npm run test:coverage",
"prepare": "npm run build",
"release": "standard-version",
"defaults": "webpack-defaults"
},
"files": [
"dist"
],
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
},
"dependencies": {
"async": "^2.5.0",
"loader-utils": "^1.1.0"
"data-urls": "^2.0.0",
"iconv-lite": "^0.5.1",
"loader-utils": "^2.0.0",
"schema-utils": "^2.6.6",
"source-map": "^0.6.0"
},
"devDependencies": {
"mocha": "^5.0.5",
"should": "^13.2.1",
"standard-version": "^4.4.0"
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.6",
"@babel/preset-env": "^7.9.6",
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@webpack-contrib/defaults": "^6.3.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^26.0.1",
"cross-env": "^7.0.2",
"del": "^5.1.0",
"del-cli": "^3.0.0",
"eslint": "^7.0.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.20.2",
"husky": "^4.2.5",
"jest": "^26.0.1",
"lint-staged": "^10.2.2",
"memfs": "^3.1.2",
"npm-run-all": "^4.1.5",
"prettier": "^2.0.5",
"standard-version": "^8.0.0",
"webpack": "^4.43.0"
},
"bugs": "https://github.com/webpack-contrib/source-map-loader/issues",
"homepage": "https://github.com/webpack-contrib/source-map-loader",
"repository": "https://github.com/webpack-contrib/source-map-loader.git",
"license": "MIT"
"keywords": [
"webpack"
]
}
+78
-56

@@ -1,17 +0,23 @@

[![npm][npm]][npm-url]
[![deps][deps]][deps-url]
[![chat][chat]][chat-url]
<div align="center">
<!-- replace with accurate logo e.g from https://worldvectorlogo.com/ -->
<a href="https://github.com/webpack/webpack">
<img width="200" height="200" vspace="" hspace="25"
src="https://cdn.rawgit.com/webpack/media/e7485eb2/logo/icon.svg">
<img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
<h1>Sourcemap Loader</h1>
<p>Extracts source maps from existing source files (from their <code>sourceMappingURL</code>).<p>
</div>
<h2 align="center">Install</h2>
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
[![size][size]][size-url]
# source-map-loader
Extracts source maps from existing source files (from their <code>sourceMappingURL</code>).
## Getting Started
To begin, you'll need to install `source-map-loader`:
```bash

@@ -21,10 +27,13 @@ npm i -D source-map-loader

<h2 align="center">Usage</h2>
Then add the plugin to your `webpack` config. For example:
[Documentation: Using loaders](https://webpack.js.org/concepts/#loaders)
**file.js**
```js
import css from 'file.css';
```
### Example webpack config
**webpack.config.js**
``` javascript
```js
module.exports = {

@@ -35,57 +44,70 @@ module: {

test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre"
}
]
}
enforce: 'pre',
use: ['source-map-loader'],
},
],
},
};
```
`source-map-loader` extracts existing source maps from all JavaScript entries. This includes both inline source maps as well as those linked via URL. All source map data is passed to webpack for processing as per a chosen [source map style](https://webpack.js.org/configuration/devtool/) specified by the `devtool` option in [webpack.config.js](https://webpack.js.org/configuration/).
`source-map-loader` extracts existing source maps from all JavaScript entries.
This includes both inline source maps as well as those linked via URL.
All source map data is passed to webpack for processing as per a chosen [source map style](https://webpack.js.org/configuration/devtool/) specified by the `devtool` option in [webpack.config.js](https://webpack.js.org/configuration/).
This loader is especially useful when using 3rd-party libraries having their own source maps.
If not extracted and processed into the source map of the webpack bundle, browsers may misinterpret source map data. `source-map-loader` allows webpack to maintain source map data continuity across libraries so ease of debugging is preserved.
`source-map-loader` will extract from any JavaScript file, including those in the `node_modules` directory.
Be mindful in setting [include](https://webpack.js.org/configuration/module/#rule-include) and [exclude](https://webpack.js.org/configuration/module/#rule-exclude) rule conditions to maximize bundling performance.
This loader is especially useful when using 3rd-party libraries having their own source maps. If not extracted and processed into the source map of the webpack bundle, browsers may misinterpret source map data. `source-map-loader` allows webpack to maintain source map data continuity across libraries so ease of debugging is preserved.
And run `webpack` via your preferred method.
`source-map-loader` will extract from any JavaScript file, including those in the `node_modules` directory. Be mindful in setting [include](https://webpack.js.org/configuration/module/#rule-include) and [exclude](https://webpack.js.org/configuration/module/#rule-exclude) rule conditions to maximize bundling performance.
## Examples
<h2 align="center">Maintainers</h2>
### Ignoring Warnings
<table>
<tbody>
<tr>
<td align="center">
<img width="150" height="150"
src="https://avatars3.githubusercontent.com/u/166921?v=3&s=150">
</br>
<a href="https://github.com/bebraw">Juho Vepsäläinen</a>
</td>
<td align="center">
<img width="150" height="150"
src="https://avatars2.githubusercontent.com/u/8420490?v=3&s=150">
</br>
<a href="https://github.com/d3viant0ne">Joshua Wiens</a>
</td>
<td align="center">
<img width="150" height="150"
src="https://avatars3.githubusercontent.com/u/533616?v=3&s=150">
</br>
<a href="https://github.com/SpaceK33z">Kees Kluskens</a>
</td>
<td align="center">
<img width="150" height="150"
src="https://avatars3.githubusercontent.com/u/3408176?v=3&s=150">
</br>
<a href="https://github.com/TheLarkInn">Sean Larkin</a>
</td>
</tr>
<tbody>
</table>
To ignore warnings, you can use the following configuration:
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
enforce: 'pre',
use: ['source-map-loader'],
},
],
},
stats: {
warningsFilter: [/Failed to parse source map/],
},
};
```
More information about the `warningsFilters` option you can find [here](https://webpack.js.org/configuration/stats/#statswarningsfilter);
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
[CONTRIBUTING](./.github/CONTRIBUTING.md)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/source-map-loader.svg
[npm-url]: https://npmjs.com/package/source-map-loader
[node]: https://img.shields.io/node/v/source-map-loader.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack-contrib/source-map-loader.svg
[deps-url]: https://david-dm.org/webpack-contrib/source-map-loader
[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
[tests]: https://github.com/webpack-contrib/source-map-loader/workflows/source-map-loader/badge.svg
[tests-url]: https://github.com/webpack-contrib/source-map-loader/actions
[cover]: https://codecov.io/gh/webpack-contrib/source-map-loader/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/source-map-loader
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.now.sh/badge?p=source-map-loader
[size-url]: https://packagephobia.now.sh/result?p=source-map-loader
yarn.lock -diff
sudo: false
language: node_js
branches:
only:
- master
matrix:
fast_finish: true
include:
- os: linux
node_js: '8'
env: JOB_PART=test
- os: linux
node_js: '9'
env: JOB_PART=test
before_install:
- nvm --version
- node --version
script:
- npm run travis:$JOB_PART
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var fs = require("fs");
var path = require("path");
var async = require("async");
var loaderUtils = require("loader-utils");
// Matches only the last occurrence of sourceMappingURL
var baseRegex = "\\s*[@#]\\s*sourceMappingURL\\s*=\\s*([^\\s]*)(?![\\S\\s]*sourceMappingURL)",
// Matches /* ... */ comments
regex1 = new RegExp("/\\*"+baseRegex+"\\s*\\*/"),
// Matches // .... comments
regex2 = new RegExp("//"+baseRegex+"($|\n|\r\n?)"),
// Matches DataUrls
regexDataUrl = /data:[^;\n]+(?:;charset=[^;\n]+)?;base64,([a-zA-Z0-9+/]+={0,2})/;
module.exports = function(input, inputMap) {
this.cacheable && this.cacheable();
var resolve = this.resolve;
var addDependency = this.addDependency;
var emitWarning = this.emitWarning || function() {};
var match = input.match(regex1) || input.match(regex2);
if(match) {
var url = match[1];
var dataUrlMatch = regexDataUrl.exec(url);
var callback = this.async();
if(dataUrlMatch) {
var mapBase64 = dataUrlMatch[1];
var mapStr = (new Buffer(mapBase64, "base64")).toString();
var map;
try {
map = JSON.parse(mapStr)
} catch (e) {
emitWarning("Cannot parse inline SourceMap '" + mapBase64.substr(0, 50) + "': " + e);
return untouched();
}
processMap(map, this.context, callback);
} else {
resolve(this.context, loaderUtils.urlToRequest(url, true), function(err, result) {
if(err) {
emitWarning("Cannot find SourceMap '" + url + "': " + err);
return untouched();
}
addDependency(result);
fs.readFile(result, "utf-8", function(err, content) {
if(err) {
emitWarning("Cannot open SourceMap '" + result + "': " + err);
return untouched();
}
var map;
try {
map = JSON.parse(content);
} catch (e) {
emitWarning("Cannot parse SourceMap '" + url + "': " + e);
return untouched();
}
processMap(map, path.dirname(result), callback);
});
}.bind(this));
return;
}
} else {
var callback = this.callback;
return untouched();
}
function untouched() {
callback(null, input, inputMap);
}
function processMap(map, context, callback) {
if(!map.sourcesContent || map.sourcesContent.length < map.sources.length) {
var sourcePrefix = map.sourceRoot ? map.sourceRoot + "/" : "";
map.sources = map.sources.map(function(s) { return sourcePrefix + s; });
delete map.sourceRoot;
var missingSources = map.sourcesContent ? map.sources.slice(map.sourcesContent.length) : map.sources;
async.map(missingSources, function(source, callback) {
resolve(context, loaderUtils.urlToRequest(source, true), function(err, result) {
if(err) {
emitWarning("Cannot find source file '" + source + "': " + err);
return callback(null, null);
}
addDependency(result);
fs.readFile(result, "utf-8", function(err, content) {
if(err) {
emitWarning("Cannot open source file '" + result + "': " + err);
return callback(null, null);
}
callback(null, {
source: result,
content: content
});
});
});
}, function(err, info) {
map.sourcesContent = map.sourcesContent || [];
info.forEach(function(res) {
if(res) {
map.sources[map.sourcesContent.length] = res.source;
map.sourcesContent.push(res.content);
} else {
map.sourcesContent.push(null);
}
});
processMap(map, context, callback);
});
return;
}
callback(null, input.replace(match[0], ''), map);
}
}
with SourceMap
//#sourceMappingURL=absolute-sourceRoot-source-map.map
// comment
with SourceMap
// @ sourceMappingURL = data:application/source-map;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhcnNldC1pbmxpbmUtc291cmNlLW1hcC5qcyIsInNvdXJjZXMiOlsiY2hhcnNldC1pbmxpbmUtc291cmNlLW1hcC50eHQiXSwic291cmNlc0NvbnRlbnQiOlsid2l0aCBTb3VyY2VNYXAiXSwibWFwcGluZ3MiOiJBQUFBIn0=
// comment
{"version":3,"file":"external-source-map2.js","sources":["../external-source-map2.txt"],"mappings":"AAAA"}
with SourceMap
//#sourceMappingURL=external-source-map.map
// comment
{"version":3,"file":"external-source-map.js","sources":["external-source-map.txt"],"sourcesContent":["with SourceMap"],"mappings":"AAAA"}
with SourceMap
//#sourceMappingURL=data/external-source-map2.map
// comment
with SourceMap
// @ sourceMappingURL = data:application/source-map;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5saW5lLXNvdXJjZS1tYXAuanMiLCJzb3VyY2VzIjpbImlubGluZS1zb3VyY2UtbWFwLnR4dCJdLCJzb3VyY2VzQ29udGVudCI6WyJ3aXRoIFNvdXJjZU1hcCJdLCJtYXBwaW5ncyI6IkFBQUEifQ==
// comment
without SourceMap
// @sourceMappingURL=data:application/source-map;base64,"something invalid"
// comment
without SourceMap
// @sourceMappingURL=data:application/source-map;base64,invalid/base64=
// comment
with SourceMap
//#sourceMappingURL=invalid-source-map.map
// comment
{"version":3,"file":"invalid-source-map.js","sources":["../invalid-source-map.txt"],"mappings":"AAAA"}"}
with SourceMap
//#sourceMappingURL=missing-source-map.map
// comment
with SourceMap
//#sourceMappingURL=missing-source-map2.map
// comment
{"version":3,"file":"missing-source-map2.js","sources":["missing-source-map2.txt"],"mappings":"AAAA"}
with SourceMap
anInvalidDirective = "\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))))+" */";
// @ sourceMappingURL = data:application/source-map;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5saW5lLXNvdXJjZS1tYXAuanMiLCJzb3VyY2VzIjpbImlubGluZS1zb3VyY2UtbWFwLnR4dCJdLCJzb3VyY2VzQ29udGVudCI6WyJ3aXRoIFNvdXJjZU1hcCJdLCJtYXBwaW5ncyI6IkFBQUEifQ==
// comment
without SourceMap
with SourceMap
//#sourceMappingURL=relative-sourceRoot-source-map.map
// comment
{"version":3,"file":"relative-sourceRoot-source-map.js","sourceRoot":"../fixtures/data/","sources":["relative-sourceRoot-source-map.txt"],"mappings":"AAAA"}
var path = require("path");
var fs = require("fs");
var should = require("should");
var loader = require("../");
function execLoader(filename, callback) {
var async = false;
var deps = [];
var warns = [];
var context = {
context: path.dirname(filename),
resolve: function(context, request, callback) {
process.nextTick(function() {
var p = path.isAbsolute(request) ? request : path.resolve(context, request);
if(fs.existsSync(p))
callback(null, p);
else
callback(new Error("File not found"));
});
},
addDependency: function(dep) {
deps.push(dep);
},
emitWarning: function(warn) {
warns.push(warn);
},
callback: function(err, res, map) {
async = true;
callback(err, res, map, deps, warns);
},
async: function() {
async = true;
return this.callback;
}
};
// Remove CRs to make test line ending invariant
var fixtureContent = fs.readFileSync(filename, "utf-8").replace(/\r/g, '');
var res = loader.call(context, fixtureContent);
if(!async) return callback(null, res, null, deps, warns);
}
describe("source-map-loader", function() {
const fixturesPath = path.join(__dirname, "fixtures");
const dataPath = path.join(fixturesPath, "data");
it("should leave normal files untouched", function(done) {
execLoader(path.join(fixturesPath, "normal-file.js"), function(err, res, map, deps, warns) {
should.equal(err, null);
warns.should.be.eql([]);
should.equal(res, "without SourceMap"),
should.equal(map, null);
deps.should.be.eql([]);
done();
});
});
it("should process inlined SourceMaps", function(done) {
execLoader(path.join(fixturesPath, "inline-source-map.js"), function(err, res, map, deps, warns) {
should.equal(err, null);
warns.should.be.eql([]);
should.equal(res, "with SourceMap\n// comment"),
map.should.be.eql({
"version":3,
"file":"inline-source-map.js",
"sources":[
"inline-source-map.txt"
],
"sourcesContent":["with SourceMap"],
"mappings":"AAAA"
});
deps.should.be.eql([]);
done();
});
});
it("should process external SourceMaps", function(done) {
execLoader(path.join(fixturesPath, "external-source-map.js"), function(err, res, map, deps, warns) {
should.equal(err, null);
warns.should.be.eql([]);
should.equal(res, "with SourceMap\n// comment"),
map.should.be.eql({
"version":3,
"file":"external-source-map.js",
"sources":[
"external-source-map.txt"
],
"sourcesContent":["with SourceMap"],
"mappings":"AAAA"
});
deps.should.be.eql([
path.join(fixturesPath, "external-source-map.map")
]);
done();
});
});
it("should process external SourceMaps (external sources)", function(done) {
execLoader(path.join(fixturesPath, "external-source-map2.js"), function(err, res, map, deps, warns) {
should.equal(err, null);
warns.should.be.eql([]);
should.equal(res, "with SourceMap\n// comment"),
map.should.be.eql({
"version":3,
"file":"external-source-map2.js",
"sources":[
path.join(fixturesPath, "external-source-map2.txt")
],
"sourcesContent":["with SourceMap"],
"mappings":"AAAA"
});
deps.should.be.eql([
path.join(dataPath, "external-source-map2.map"),
path.join(fixturesPath, "external-source-map2.txt")
]);
done();
});
});
it("should use last SourceMap directive", function (done) {
execLoader(path.join(fixturesPath, "multi-source-map.js"), function (err, res, map, deps, warns) {
should.equal(err, null);
warns.should.be.eql([]);
should.equal(res, "with SourceMap\nanInvalidDirective = \"\\n/*# sourceMappingURL=data:application/json;base64,\"+btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))))+\" */\";\n// comment"),
map.should.be.eql({
"version": 3,
"file": "inline-source-map.js",
"sources": [
"inline-source-map.txt"
],
"sourcesContent": ["with SourceMap"],
"mappings": "AAAA"
});
deps.should.be.eql([]);
done();
});
});
it("should skip invalid base64 SourceMap", function (done) {
execLoader(path.join(fixturesPath, "invalid-inline-source-map.js"), function (err, res, map, deps, warns) {
should.equal(err, null);
warns.should.be.eql([]);
should.equal(res, "without SourceMap\n// @sourceMappingURL=data:application/source-map;base64,\"something invalid\"\n// comment");
should.equal(map, null);
deps.should.be.eql([]);
done();
});
});
it("should warn on invalid base64 SourceMap", function (done) {
execLoader(path.join(fixturesPath, "invalid-inline-source-map2.js"), function (err, res, map, deps, warns) {
should.equal(err, null);
warns.should.matchEach(
new RegExp("Cannot parse inline SourceMap 'invalid\/base64=': SyntaxError: Unexpected token")
);
should.equal(res, "without SourceMap\n// @sourceMappingURL=data:application/source-map;base64,invalid/base64=\n// comment");
should.equal(map, null);
deps.should.be.eql([]);
done();
});
});
it("should warn on invalid SourceMap", function (done) {
execLoader(path.join(fixturesPath, "invalid-source-map.js"), function (err, res, map, deps, warns) {
should.equal(err, null);
warns.should.matchEach(
new RegExp("Cannot parse SourceMap 'invalid-source-map.map': SyntaxError: Unexpected string in JSON at position 102")
);
should.equal(res, "with SourceMap\n//#sourceMappingURL=invalid-source-map.map\n// comment");
should.equal(map, null);
deps.should.be.eql([
path.join(fixturesPath, "invalid-source-map.map")
]);
done();
});
});
it("should warn on missing SourceMap", function(done) {
execLoader(path.join(fixturesPath, "missing-source-map.js"), function(err, res, map, deps, warns) {
should.equal(err, null);
warns.should.be.eql([
"Cannot find SourceMap 'missing-source-map.map': Error: File not found"
]);
should.equal(res, "with SourceMap\n//#sourceMappingURL=missing-source-map.map\n// comment"),
should.equal(map, null);
deps.should.be.eql([]);
done();
});
});
it("should warn on missing source file", function(done) {
execLoader(path.join(fixturesPath, "missing-source-map2.js"), function(err, res, map, deps, warns) {
should.equal(err, null);
warns.should.be.eql([
"Cannot find source file 'missing-source-map2.txt': Error: File not found"
]);
should.equal(res, "with SourceMap\n// comment"),
map.should.be.eql({
"version":3,
"file":"missing-source-map2.js",
"sources":[
"missing-source-map2.txt"
],
"sourcesContent":[null],
"mappings":"AAAA"
});
deps.should.be.eql([
path.join(fixturesPath, "missing-source-map2.map")
]);
done();
});
});
it("should process inlined SourceMaps with charset", function(done) {
execLoader(path.join(fixturesPath, "charset-inline-source-map.js"), function(err, res, map, deps, warns) {
should.equal(err, null);
warns.should.be.eql([]);
should.equal(res, "with SourceMap\n// comment"),
map.should.be.eql({
"version":3,
"file":"charset-inline-source-map.js",
"sources":[
"charset-inline-source-map.txt"
],
"sourcesContent":["with SourceMap"],
"mappings":"AAAA"
});
deps.should.be.eql([]);
done();
});
});
it("should support absolute sourceRoot paths in sourcemaps", (done) => {
const sourceRoot = path.join(fixturesPath);
const javaScriptFilename = "absolute-sourceRoot-source-map.js";
const sourceFilename = "absolute-sourceRoot-source-map.txt";
const rootRelativeSourcePath = path.join(sourceRoot, sourceFilename);
const sourceMapPath = path.join(sourceRoot, "absolute-sourceRoot-source-map.map");
// Create the sourcemap file
const rawSourceMap = {
"version": 3,
"file": javaScriptFilename,
"sourceRoot": sourceRoot,
"sources": [
sourceFilename
],
"mappings": "AAAA"
};
fs.writeFileSync(sourceMapPath, JSON.stringify(rawSourceMap));
execLoader(
path.join(fixturesPath, javaScriptFilename),
(err, res, map, deps, warns) => {
should.equal(err, null);
warns.should.be.eql([]);
should.equal(res, "with SourceMap\n// comment"),
map.should.be.eql({
"version": 3,
"file": javaScriptFilename,
"sources": [
rootRelativeSourcePath
],
"sourcesContent": [
"with SourceMap\n// comment"
],
"mappings": "AAAA"
});
deps.should.be.eql([
sourceMapPath,
rootRelativeSourcePath
]);
done();
}
);
});
it("should support relative sourceRoot paths in sourcemaps", (done) => {
const javaScriptFilename = "relative-sourceRoot-source-map.js";
const sourceFilename = "relative-sourceRoot-source-map.txt";
const rootRelativeSourcePath = path.join(dataPath, sourceFilename);
const sourceMapPath = path.join(fixturesPath, "relative-sourceRoot-source-map.map");
execLoader(
path.join(fixturesPath, javaScriptFilename),
(err, res, map, deps, warns) => {
should.equal(err, null);
warns.should.be.eql([]);
should.equal(res, "with SourceMap\n// comment"),
map.should.be.eql({
"version": 3,
"file": javaScriptFilename,
"sources": [
rootRelativeSourcePath
],
"sourcesContent": [
"with SourceMap\n// comment"
],
"mappings": "AAAA"
});
deps.should.be.eql([
sourceMapPath,
rootRelativeSourcePath
]);
done();
}
);
});
});