| 1 | /*
|
|---|
| 2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
|---|
| 3 | Author Tobias Koppers @sokra
|
|---|
| 4 | */
|
|---|
| 5 |
|
|---|
| 6 | "use strict";
|
|---|
| 7 |
|
|---|
| 8 | const makeSerializable = require("../util/makeSerializable");
|
|---|
| 9 | const WebpackError = require("./WebpackError");
|
|---|
| 10 |
|
|---|
| 11 | /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
|
|---|
| 12 | /** @typedef {import("../Dependency").SourcePosition} SourcePosition */
|
|---|
| 13 | /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
|
|---|
| 14 | /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
|
|---|
| 15 |
|
|---|
| 16 | const WASM_HEADER = Buffer.from([0x00, 0x61, 0x73, 0x6d]);
|
|---|
| 17 |
|
|---|
| 18 | class ModuleParseError extends WebpackError {
|
|---|
| 19 | /**
|
|---|
| 20 | * Creates an instance of ModuleParseError.
|
|---|
| 21 | * @param {string | Buffer} source source code
|
|---|
| 22 | * @param {Error & { loc?: SourcePosition }} err the parse error
|
|---|
| 23 | * @param {string[]} loaders the loaders used
|
|---|
| 24 | * @param {string} type module type
|
|---|
| 25 | */
|
|---|
| 26 | constructor(source, err, loaders, type) {
|
|---|
| 27 | let message = `Module parse failed: ${err && err.message}`;
|
|---|
| 28 | /** @type {undefined | DependencyLocation} */
|
|---|
| 29 | let loc;
|
|---|
| 30 |
|
|---|
| 31 | if (
|
|---|
| 32 | ((Buffer.isBuffer(source) && source.subarray(0, 4).equals(WASM_HEADER)) ||
|
|---|
| 33 | (typeof source === "string" && /^\0asm/.test(source))) &&
|
|---|
| 34 | !type.startsWith("webassembly")
|
|---|
| 35 | ) {
|
|---|
| 36 | message +=
|
|---|
| 37 | "\nThe module seem to be a WebAssembly module, but module is not flagged as WebAssembly module for webpack.";
|
|---|
| 38 | message +=
|
|---|
| 39 | "\nBREAKING CHANGE: Since webpack 5 WebAssembly is not enabled by default and flagged as experimental feature.";
|
|---|
| 40 | message +=
|
|---|
| 41 | "\nYou need to enable one of the WebAssembly experiments via 'experiments.asyncWebAssembly: true' (based on async modules) or 'experiments.syncWebAssembly: true' (like webpack 4, deprecated).";
|
|---|
| 42 | message +=
|
|---|
| 43 | "\nFor files that transpile to WebAssembly, make sure to set the module type in the 'module.rules' section of the config (e. g. 'type: \"webassembly/async\"').";
|
|---|
| 44 | } else if (!loaders) {
|
|---|
| 45 | message +=
|
|---|
| 46 | "\nYou may need an appropriate loader to handle this file type. " +
|
|---|
| 47 | "See https://webpack.js.org/concepts/loaders";
|
|---|
| 48 | } else if (loaders.length >= 1) {
|
|---|
| 49 | message += `\nFile was processed with these loaders:${loaders
|
|---|
| 50 | .map((loader) => `\n * ${loader}`)
|
|---|
| 51 | .join("")}`;
|
|---|
| 52 | message +=
|
|---|
| 53 | "\nYou may need an additional loader to handle the result of these loaders.";
|
|---|
| 54 | } else {
|
|---|
| 55 | message +=
|
|---|
| 56 | "\nYou may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders";
|
|---|
| 57 | }
|
|---|
| 58 |
|
|---|
| 59 | if (
|
|---|
| 60 | err &&
|
|---|
| 61 | err.loc &&
|
|---|
| 62 | typeof err.loc === "object" &&
|
|---|
| 63 | typeof err.loc.line === "number"
|
|---|
| 64 | ) {
|
|---|
| 65 | const lineNumber = err.loc.line;
|
|---|
| 66 |
|
|---|
| 67 | if (
|
|---|
| 68 | Buffer.isBuffer(source) ||
|
|---|
| 69 | // eslint-disable-next-line no-control-regex
|
|---|
| 70 | /[\0\u0001\u0002\u0003\u0004\u0005\u0006\u0007]/.test(source)
|
|---|
| 71 | ) {
|
|---|
| 72 | // binary file
|
|---|
| 73 | message += "\n(Source code omitted for this binary file)";
|
|---|
| 74 | } else {
|
|---|
| 75 | const sourceLines = source.split(/\r?\n/);
|
|---|
| 76 | const start = Math.max(0, lineNumber - 3);
|
|---|
| 77 | const linesBefore = sourceLines.slice(start, lineNumber - 1);
|
|---|
| 78 | const theLine = sourceLines[lineNumber - 1];
|
|---|
| 79 | const linesAfter = sourceLines.slice(lineNumber, lineNumber + 2);
|
|---|
| 80 |
|
|---|
| 81 | message += `${linesBefore
|
|---|
| 82 | .map((l) => `\n| ${l}`)
|
|---|
| 83 | .join(
|
|---|
| 84 | ""
|
|---|
| 85 | )}\n> ${theLine}${linesAfter.map((l) => `\n| ${l}`).join("")}`;
|
|---|
| 86 | }
|
|---|
| 87 |
|
|---|
| 88 | loc = { start: err.loc };
|
|---|
| 89 | } else if (err && err.stack) {
|
|---|
| 90 | message += `\n${err.stack}`;
|
|---|
| 91 | }
|
|---|
| 92 |
|
|---|
| 93 | super(message);
|
|---|
| 94 |
|
|---|
| 95 | /** @type {string} */
|
|---|
| 96 | this.name = "ModuleParseError";
|
|---|
| 97 | /** @type {undefined | DependencyLocation} */
|
|---|
| 98 | this.loc = loc;
|
|---|
| 99 | /** @type {Error} */
|
|---|
| 100 | this.error = err;
|
|---|
| 101 | }
|
|---|
| 102 |
|
|---|
| 103 | /**
|
|---|
| 104 | * Serializes this instance into the provided serializer context.
|
|---|
| 105 | * @param {ObjectSerializerContext} context context
|
|---|
| 106 | */
|
|---|
| 107 | serialize(context) {
|
|---|
| 108 | const { write } = context;
|
|---|
| 109 |
|
|---|
| 110 | write(this.error);
|
|---|
| 111 |
|
|---|
| 112 | super.serialize(context);
|
|---|
| 113 | }
|
|---|
| 114 |
|
|---|
| 115 | /**
|
|---|
| 116 | * Restores this instance from the provided deserializer context.
|
|---|
| 117 | * @param {ObjectDeserializerContext} context context
|
|---|
| 118 | */
|
|---|
| 119 | deserialize(context) {
|
|---|
| 120 | const { read } = context;
|
|---|
| 121 |
|
|---|
| 122 | this.error = read();
|
|---|
| 123 |
|
|---|
| 124 | super.deserialize(context);
|
|---|
| 125 | }
|
|---|
| 126 | }
|
|---|
| 127 |
|
|---|
| 128 | makeSerializable(ModuleParseError, "webpack/lib/errors/ModuleParseError");
|
|---|
| 129 |
|
|---|
| 130 | module.exports = ModuleParseError;
|
|---|