Repository: webpack-contrib/source-map-loader (js)

Issue:
Add support for disable `emitWarning`
Currently the loader warns on 3rd party packages which have some invalid source maps. As this is typically not in the hand of the user to fix those (other than send bug reports/PRs) we should offer an option to disable warnings. 

A pretty common error seems to be that source maps are included in the package, but the source maps do not contain the original source content. The references to any files break because the source files are not bundled in the npm packages.

Affected packages in my case are:

- All packages from formatjs (intl-messageformat, ...)
- All packages from Apollo (apollo-client, ...)


Pull request description:
docs: ignore example
<!--
  HOLY CRAP a Pull Request. We ❤️ those!

  If you remove or skip this template, you'll make the 🐼 sad and the mighty god
  of Github will appear and pile-drive the close button from a great height
  while making animal noises.

  Please place an x (no spaces!) in all [ ] that apply
-->

This PR contains a:

- [ ] **bugfix**
- [ ] new **feature**
- [x] **code refactor**
- [x] **test update** <!-- if bug or feature is checked, this should be too -->
- [ ] **typo fix**
- [x] **metadata update**

### Motivation / Use-Case

fixes #49

### Breaking Changes

Potential yes

### Additional Info

No

Patch:
diff --git a/README.md b/README.md
index 9f1e8f6..7a75d13 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,33 @@ Be mindful in setting [include](https://webpack.js.org/configuration/module/#rul
 
 And run `webpack` via your preferred method.
 
+## Examples
+
+### Ignoring Warnings
+
+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.
diff --git a/src/index.js b/src/index.js
index 8c7f703..77c6da1 100644
--- a/src/index.js
+++ b/src/index.js
@@ -54,7 +54,7 @@ export default async function loader(input, inputMap) {
     map = JSON.parse(sourceContent.replace(/^\)\]\}'/, ''));
   } catch (parseError) {
     this.emitWarning(
-      new Error(`Cannot parse source map from '${sourceURL}': ${parseError}`)
+      new Error(`Failed to parse source map from '${sourceURL}': ${parseError}`)
     );
 
     callback(null, input, inputMap);
diff --git a/src/utils.js b/src/utils.js
index aa1336c..3ec26f8 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -109,7 +109,7 @@ function fetchFromDataURL(loaderContext, sourceURL) {
     return decode(dataURL.body, dataURL.encodingName);
   }
 
-  throw new Error(`Can not parse inline source map: ${sourceURL}`);
+  throw new Error(`Failed to parse source map from "data" URL: ${sourceURL}`);
 }
 
 async function fetchFromFilesystem(loaderContext, sourceURL) {
@@ -126,7 +126,9 @@ async function fetchFromFilesystem(loaderContext, sourceURL) {
       });
     });
   } catch (error) {
-    throw new Error(`Cannot read '${sourceURL}' file: ${error}`);
+    throw new Error(
+      `Failed to parse source map from '${sourceURL}' file: ${error}`
+    );
   }
 
   return buffer.toString();
@@ -163,12 +165,16 @@ async function fetchFromURL(
       return { sourceURL, sourceContent };
     }
 
-    throw new Error(`Absolute '${url}' URL is not supported`);
+    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(`Scheme-relative '${url}' URL is not supported`);
+    throw new Error(
+      `Failed to parse source map: "${url}" URL is not supported`
+    );
   }
 
   // 3. Absolute path


Test patch:
diff --git a/test/__snapshots__/loader.test.js.snap b/test/__snapshots__/loader.test.js.snap
index 7ece89b..d41f4d9 100644
--- a/test/__snapshots__/loader.test.js.snap
+++ b/test/__snapshots__/loader.test.js.snap
@@ -1,5 +1,20 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`source-map-loader should allow to filter warnings: css 1`] = `
+"without SourceMap
+// @sourceMappingURL=data:application/source-map;base64,invalid/base64=
+// comment"
+`;
+
+exports[`source-map-loader should allow to filter warnings: errors 1`] = `Array []`;
+
+exports[`source-map-loader should allow to filter warnings: warnings 1`] = `
+Array [
+  "ModuleWarning: Module Warning (from \`replaced original path\`):
+Failed to parse source map from \\"data\\" URL: data:application/source-map;base64,invalid/base64=",
+]
+`;
+
 exports[`source-map-loader should leave normal files untouched: css 1`] = `"without SourceMap"`;
 
 exports[`source-map-loader should leave normal files untouched: errors 1`] = `Array []`;
@@ -116,14 +131,14 @@ anInvalidDirective = \\"\\\\n/*# sourceMappingURL=data:application/json;base64,\
 exports[`source-map-loader should process css sourceMap: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Absolute 'webpack:///./src/app/app.scss' URL is not supported",
+Failed to parse source map: \\"webpack:///./src/app/app.scss\\" URL is not supported",
 ]
 `;
 
 exports[`source-map-loader should process css sourceMap: warnings 2`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Cannot read '/test/fixtures/unresolved-file.js' file: Error: ENOENT: no such file or directory, open '/test/fixtures/unresolved-file.js'",
+Failed to parse source map from '/test/fixtures/unresolved-file.js' file: Error: ENOENT: no such file or directory, open '/test/fixtures/unresolved-file.js'",
 ]
 `;
 
@@ -255,7 +270,7 @@ exports[`source-map-loader should process protocol-relative-url-path: errors 1`]
 exports[`source-map-loader should process protocol-relative-url-path: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Scheme-relative '//sampledomain.com/external-source-map2.map' URL is not supported",
+Failed to parse source map: \\"//sampledomain.com/external-source-map2.map\\" URL is not supported",
 ]
 `;
 
@@ -271,7 +286,7 @@ exports[`source-map-loader should reject http SourceMaps: errors 1`] = `Array []
 exports[`source-map-loader should reject http SourceMaps: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Absolute 'http://sampledomain.com/external-source-map2.map' URL is not supported",
+Failed to parse source map: \\"http://sampledomain.com/external-source-map2.map\\" URL is not supported",
 ]
 `;
 
@@ -291,7 +306,7 @@ exports[`source-map-loader should reject not support url: errors 1`] = `Array []
 exports[`source-map-loader should reject not support url: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Absolute 'ftp://exampleurl.com' URL is not supported",
+Failed to parse source map: \\"ftp://exampleurl.com\\" URL is not supported",
 ]
 `;
 
@@ -306,7 +321,7 @@ exports[`source-map-loader should skip invalid base64 SourceMap: errors 1`] = `A
 exports[`source-map-loader should skip invalid base64 SourceMap: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Cannot parse source map from 'undefined': SyntaxError: Unexpected end of JSON input",
+Failed to parse source map from 'undefined': SyntaxError: Unexpected end of JSON input",
 ]
 `;
 
@@ -481,9 +496,9 @@ anInvalidDirective = \\"\\\\n/*# sourceMappingURL=data:application/json;base64,\
 exports[`source-map-loader should support mixed paths in sources with sourceRoot: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Absolute 'ftp://path-to-map.com' URL is not supported",
+Failed to parse source map: \\"ftp://path-to-map.com\\" URL is not supported",
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Absolute 'http://path-to-map.com' URL is not supported",
+Failed to parse source map: \\"http://path-to-map.com\\" URL is not supported",
 ]
 `;
 
@@ -519,9 +534,9 @@ anInvalidDirective = \\"\\\\n/*# sourceMappingURL=data:application/json;base64,\
 exports[`source-map-loader should support mixed paths in sources without sourceRoot: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Absolute 'ftp://path-to-map.com' URL is not supported",
+Failed to parse source map: \\"ftp://path-to-map.com\\" URL is not supported",
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Absolute 'http://path-to-map.com' URL is not supported",
+Failed to parse source map: \\"http://path-to-map.com\\" URL is not supported",
 ]
 `;
 
@@ -584,7 +599,7 @@ exports[`source-map-loader should warn on invalid SourceMap: errors 1`] = `Array
 exports[`source-map-loader should warn on invalid SourceMap: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Cannot parse source map from '/test/fixtures/invalid-source-map.map': SyntaxError: Unexpected string in JSON at position 102",
+Failed to parse source map from '/test/fixtures/invalid-source-map.map': SyntaxError: Unexpected string in JSON at position 102",
 ]
 `;
 
@@ -599,7 +614,7 @@ exports[`source-map-loader should warn on invalid base64 SourceMap: errors 1`] =
 exports[`source-map-loader should warn on invalid base64 SourceMap: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Can not parse inline source map: data:application/source-map;base64,invalid/base64=",
+Failed to parse source map from \\"data\\" URL: data:application/source-map;base64,invalid/base64=",
 ]
 `;
 
@@ -614,7 +629,7 @@ exports[`source-map-loader should warn on missing SourceMap: errors 1`] = `Array
 exports[`source-map-loader should warn on missing SourceMap: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Cannot read '/test/fixtures/missing-source-map.map' file: Error: ENOENT: no such file or directory, open '/test/fixtures/missing-source-map.map'",
+Failed to parse source map from '/test/fixtures/missing-source-map.map' file: Error: ENOENT: no such file or directory, open '/test/fixtures/missing-source-map.map'",
 ]
 `;
 
@@ -639,6 +654,6 @@ Object {
 exports[`source-map-loader should warn on missing source file: warnings 1`] = `
 Array [
   "ModuleWarning: Module Warning (from \`replaced original path\`):
-Cannot read '/test/fixtures/missing-source-map2.txt' file: Error: ENOENT: no such file or directory, open '/test/fixtures/missing-source-map2.txt'",
+Failed to parse source map from '/test/fixtures/missing-source-map2.txt' file: Error: ENOENT: no such file or directory, open '/test/fixtures/missing-source-map2.txt'",
 ]
 `;
diff --git a/test/loader.test.js b/test/loader.test.js
index 338ec03..6f74f06 100644
--- a/test/loader.test.js
+++ b/test/loader.test.js
@@ -576,4 +576,19 @@ describe('source-map-loader', () => {
     expect(getWarnings(stats)).toMatchSnapshot('warnings');
     expect(getErrors(stats)).toMatchSnapshot('errors');
   });
+
+  it('should allow to filter warnings', async () => {
+    const testId = 'invalid-inline-source-map2.js';
+    const compiler = getCompiler(testId);
+    const stats = await compile(compiler);
+    const codeFromBundle = getCodeFromBundle(stats, compiler);
+
+    expect(
+      stats.toString({ warningsFilter: /Failed to parse source map/ })
+    ).not.toContain('Failed to parse source map');
+    expect(codeFromBundle.map).toBeUndefined();
+    expect(codeFromBundle.css).toMatchSnapshot('css');
+    expect(getWarnings(stats)).toMatchSnapshot('warnings');
+    expect(getErrors(stats)).toMatchSnapshot('errors');
+  });
 });