first commit
This commit is contained in:
21
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/LICENSE
generated
vendored
Normal file
21
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Geoffroy Warin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
162
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/README.md
generated
vendored
Normal file
162
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/README.md
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
# Friendly-errors-webpack-plugin
|
||||
|
||||
[](https://www.npmjs.com/package/@soda/friendly-errors-webpack-plugin)
|
||||
[](https://travis-ci.org/sodatea/friendly-errors-webpack-plugin)
|
||||
[](https://ci.appveyor.com/project/sodatea/friendly-errors-webpack-plugin/branch/master)
|
||||
|
||||
Friendly-errors-webpack-plugin recognizes certain classes of webpack
|
||||
errors and cleans, aggregates and prioritizes them to provide a better
|
||||
Developer Experience.
|
||||
|
||||
It is easy to add types of errors so if you would like to see more
|
||||
errors get handled, please open a [PR](https://help.github.com/articles/creating-a-pull-request/)!
|
||||
|
||||
## Getting started
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
npm install @soda/friendly-errors-webpack-plugin --save-dev
|
||||
```
|
||||
|
||||
### Basic usage
|
||||
|
||||
Simply add `FriendlyErrorsWebpackPlugin` to the plugin section in your Webpack config.
|
||||
|
||||
```javascript
|
||||
var FriendlyErrorsWebpackPlugin = require('@soda/friendly-errors-webpack-plugin');
|
||||
|
||||
var webpackConfig = {
|
||||
// ...
|
||||
plugins: [
|
||||
new FriendlyErrorsWebpackPlugin(),
|
||||
],
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Turn off errors
|
||||
|
||||
You need to turn off all error logging by setting your webpack config quiet option to true.
|
||||
|
||||
```javascript
|
||||
app.use(require('webpack-dev-middleware')(compiler, {
|
||||
// ...
|
||||
logLevel: 'silent',
|
||||
// ...
|
||||
}));
|
||||
```
|
||||
|
||||
If you use the webpack-dev-server, there is a setting in webpack's ```devServer``` options:
|
||||
|
||||
```javascript
|
||||
// webpack config root
|
||||
{
|
||||
// ...
|
||||
devServer: {
|
||||
// ...
|
||||
quiet: true,
|
||||
// ...
|
||||
},
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
If you use webpack-hot-middleware, that is done by setting the log option to `false`. You can do something sort of like this, depending upon your setup:
|
||||
|
||||
```javascript
|
||||
app.use(require('webpack-hot-middleware')(compiler, {
|
||||
log: false
|
||||
}));
|
||||
```
|
||||
|
||||
_Thanks to [webpack-dashboard](https://github.com/FormidableLabs/webpack-dashboard) for this piece of info._
|
||||
|
||||
## Demo
|
||||
|
||||
### Build success
|
||||
|
||||

|
||||
|
||||
### eslint-loader errors
|
||||
|
||||

|
||||
|
||||
### babel-loader syntax errors
|
||||
|
||||

|
||||
|
||||
### Module not found
|
||||
|
||||

|
||||
|
||||
## Options
|
||||
|
||||
You can pass options to the plugin:
|
||||
|
||||
```js
|
||||
new FriendlyErrorsPlugin({
|
||||
compilationSuccessInfo: {
|
||||
messages: ['You application is running here http://localhost:3000'],
|
||||
notes: ['Some additional notes to be displayed upon successful compilation']
|
||||
},
|
||||
onErrors: function (severity, errors) {
|
||||
// You can listen to errors transformed and prioritized by the plugin
|
||||
// severity can be 'error' or 'warning'
|
||||
},
|
||||
// should the console be cleared between each compilation?
|
||||
// default is true
|
||||
clearConsole: true,
|
||||
|
||||
// add formatters and transformers (see below)
|
||||
additionalFormatters: [],
|
||||
additionalTransformers: []
|
||||
})
|
||||
```
|
||||
|
||||
## Adding desktop notifications
|
||||
|
||||
The plugin has no native support for desktop notifications but it is easy
|
||||
to add them thanks to [node-notifier](https://www.npmjs.com/package/node-notifier) for instance.
|
||||
|
||||
```js
|
||||
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
|
||||
var notifier = require('node-notifier');
|
||||
var ICON = path.join(__dirname, 'icon.png');
|
||||
|
||||
new FriendlyErrorsPlugin({
|
||||
onErrors: (severity, errors) => {
|
||||
if (severity !== 'error') {
|
||||
return;
|
||||
}
|
||||
const error = errors[0];
|
||||
notifier.notify({
|
||||
title: "Webpack error",
|
||||
message: severity + ': ' + error.name,
|
||||
subtitle: error.file || '',
|
||||
icon: ICON
|
||||
});
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Transformers and formatters
|
||||
|
||||
Webpack's errors processing, is done in four phases:
|
||||
|
||||
1. Extract relevant info from webpack errors. This is done by the plugin [here](https://github.com/sodatea/friendly-errors-webpack-plugin/blob/master/src/core/extractWebpackError.js)
|
||||
2. Apply transformers to all errors to identify and annotate well know errors and give them a priority
|
||||
3. Get only top priority error or top priority warnings if no errors are thrown
|
||||
4. Apply formatters to all annotated errors
|
||||
|
||||
You can add transformers and formatters. Please see [transformErrors](https://github.com/sodatea/friendly-errors-webpack-plugin/blob/master/src/core/transformErrors.js),
|
||||
and [formatErrors](https://github.com/sodatea/friendly-errors-webpack-plugin/blob/master/src/core/formatErrors.js)
|
||||
in the source code and take a look a the [default transformers](https://github.com/sodatea/friendly-errors-webpack-plugin/tree/master/src/transformers)
|
||||
and the [default formatters](https://github.com/sodatea/friendly-errors-webpack-plugin/tree/master/src/formatters).
|
||||
|
||||
## TODO
|
||||
|
||||
- [x] Make it compatible with node 4
|
||||
|
5
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/index.js
generated
vendored
Normal file
5
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/index.js
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
const FriendlyErrorsWebpackPlugin = require('./src/friendly-errors-plugin');
|
||||
|
||||
module.exports = FriendlyErrorsWebpackPlugin;
|
||||
module.exports.default = FriendlyErrorsWebpackPlugin;
|
74
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/package.json
generated
vendored
Normal file
74
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/package.json
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
{
|
||||
"name": "@soda/friendly-errors-webpack-plugin",
|
||||
"version": "1.8.1",
|
||||
"description": "Recognizes certain classes of webpack errors and cleans, aggregates and prioritizes them to provide a better Developer Experience",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "eslint --ignore-pattern \"test/**\" . && jest --testEnvironment node"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"friendly",
|
||||
"errors",
|
||||
"webpack",
|
||||
"plugin"
|
||||
],
|
||||
"author": "Geoffroy Warin",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sodatea/friendly-errors-webpack-plugin.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sodatea/friendly-errors-webpack-plugin/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"jest": {
|
||||
"testEnvironment": "node",
|
||||
"transformIgnorePatterns": [
|
||||
"node_modules",
|
||||
"src",
|
||||
"index.js"
|
||||
]
|
||||
},
|
||||
"peerDependencies": {
|
||||
"webpack": "^4.0.0 || ^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.5.4",
|
||||
"@babel/plugin-transform-async-to-generator": "^7.5.0",
|
||||
"autoprefixer": "^9.6.0",
|
||||
"babel-core": "6.26.3",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-preset-react": "^6.23.0",
|
||||
"babel-loader-7": "npm:babel-loader@7.1.5",
|
||||
"babel-loader": "^8.0.6",
|
||||
"css-loader": "^2.1.1",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-7": "npm:eslint@^7.14.0",
|
||||
"eslint-loader": "^2.1.2",
|
||||
"eslint-plugin-node": "^9.0.1",
|
||||
"eslint-webpack-plugin": "^2.4.0",
|
||||
"expect": "^24.8.0",
|
||||
"jest": "^24.8.0",
|
||||
"memory-fs": "^0.4.1",
|
||||
"mini-css-extract-plugin": "^0.6.0",
|
||||
"node-sass": "^4.12.0",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"sass": "^1.20.1",
|
||||
"sass-loader": "^7.1.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"webpack": "^4.31.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "^3.0.0",
|
||||
"error-stack-parser": "^2.0.6",
|
||||
"string-width": "^4.2.3",
|
||||
"strip-ansi": "^6.0.1"
|
||||
}
|
||||
}
|
65
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/core/extractWebpackError.js
generated
vendored
Normal file
65
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/core/extractWebpackError.js
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
'use strict';
|
||||
|
||||
const ErrorStackParser = require('error-stack-parser');
|
||||
const RequestShortener = require("webpack/lib/RequestShortener");
|
||||
|
||||
// TODO: allow the location to be customized in options
|
||||
const requestShortener = new RequestShortener(process.cwd());
|
||||
|
||||
/*
|
||||
This logic is mostly duplicated from webpack/lib/Stats.js#toJson()
|
||||
See: https://github.com/webpack/webpack/blob/2f618e733aab4755deb42e9d8e859609005607c0/lib/Stats.js#L89
|
||||
*/
|
||||
|
||||
function extractError (e) {
|
||||
return {
|
||||
message: e.message,
|
||||
file: getFile(e),
|
||||
origin: getOrigin(e),
|
||||
name: e.name,
|
||||
severity: 0,
|
||||
webpackError: e,
|
||||
originalStack: getOriginalErrorStack(e)
|
||||
};
|
||||
}
|
||||
|
||||
function getOriginalErrorStack(e) {
|
||||
while (e.error != null) {
|
||||
e = e.error;
|
||||
}
|
||||
if (e.stack) {
|
||||
return ErrorStackParser.parse(e);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
function getFile (e) {
|
||||
if (e.file) {
|
||||
return e.file;
|
||||
} else if (e.module && e.module.readableIdentifier && typeof e.module.readableIdentifier === "function") {
|
||||
return e.module.readableIdentifier(requestShortener);
|
||||
}
|
||||
}
|
||||
|
||||
function getOrigin (e) {
|
||||
let origin = '';
|
||||
if (e.dependencies && e.origin) {
|
||||
origin += '\n @ ' + e.origin.readableIdentifier(requestShortener);
|
||||
e.dependencies.forEach(function (dep) {
|
||||
if (!dep.loc) return;
|
||||
if (typeof dep.loc === "string") return;
|
||||
if (!dep.loc.start) return;
|
||||
if (!dep.loc.end) return;
|
||||
origin += ' ' + dep.loc.start.line + ':' + dep.loc.start.column + '-' +
|
||||
(dep.loc.start.line !== dep.loc.end.line ? dep.loc.end.line + ':' : '') + dep.loc.end.column;
|
||||
});
|
||||
var current = e.origin;
|
||||
while (current.issuer && typeof current.issuer.readableIdentifier === 'function') {
|
||||
current = current.issuer;
|
||||
origin += '\n @ ' + current.readableIdentifier(requestShortener);
|
||||
}
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
|
||||
module.exports = extractError;
|
18
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/core/formatErrors.js
generated
vendored
Normal file
18
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/core/formatErrors.js
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Applies formatters to all AnnotatedErrors.
|
||||
*
|
||||
* A formatter has the following signature: FormattedError => Array<String>.
|
||||
* It takes a formatted error produced by a transformer and returns a list
|
||||
* of log statements to print.
|
||||
*
|
||||
*/
|
||||
function formatErrors(errors, formatters, errorType) {
|
||||
const format = (formatter) => formatter(errors, errorType) || [];
|
||||
const flatten = (accum, curr) => accum.concat(curr);
|
||||
|
||||
return formatters.map(format).reduce(flatten, [])
|
||||
}
|
||||
|
||||
module.exports = formatErrors;
|
34
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/core/transformErrors.js
generated
vendored
Normal file
34
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/core/transformErrors.js
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
const extractError = require('./extractWebpackError');
|
||||
|
||||
/**
|
||||
* Applies all transformers to all errors and returns "annotated"
|
||||
* errors.
|
||||
*
|
||||
* Each transformer should have the following signature WebpackError => AnnotatedError
|
||||
*
|
||||
* A WebpackError has the following fields:
|
||||
* - message
|
||||
* - file
|
||||
* - origin
|
||||
* - name
|
||||
* - severity
|
||||
* - webpackError (original error)
|
||||
*
|
||||
* An AnnotatedError should be an extension (Object.assign) of the WebpackError
|
||||
* and add whatever information is convenient for formatting.
|
||||
* In particular, they should have a 'priority' field.
|
||||
*
|
||||
* The plugin will only display errors having maximum priority at the same time.
|
||||
*
|
||||
* If they don't have a 'type' field, the will be handled by the default formatter.
|
||||
*/
|
||||
function processErrors (errors, transformers) {
|
||||
const transform = (error, transformer) => transformer(error);
|
||||
const applyTransformations = (error) => transformers.reduce(transform, error);
|
||||
|
||||
return errors.map(extractError).map(applyTransformations);
|
||||
}
|
||||
|
||||
module.exports = processErrors;
|
43
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/formatters/defaultError.js
generated
vendored
Normal file
43
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/formatters/defaultError.js
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
'use strict';
|
||||
|
||||
const concat = require('../utils').concat;
|
||||
const formatTitle = require('../utils/colors').formatTitle;
|
||||
|
||||
function displayError(severity, error) {
|
||||
const baseError = formatTitle(severity, severity);
|
||||
|
||||
return concat(
|
||||
`${baseError} ${removeLoaders(error.file)}`,
|
||||
'',
|
||||
error.message,
|
||||
(error.origin ? error.origin : undefined),
|
||||
'',
|
||||
error.infos
|
||||
);
|
||||
}
|
||||
|
||||
function removeLoaders(file) {
|
||||
if (!file) {
|
||||
return "";
|
||||
}
|
||||
const split = file.split('!');
|
||||
const filePath = split[split.length - 1];
|
||||
return `in ${filePath}`;
|
||||
}
|
||||
|
||||
function isDefaultError(error) {
|
||||
return !error.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format errors without a type
|
||||
*/
|
||||
function format(errors, type) {
|
||||
return errors
|
||||
.filter(isDefaultError)
|
||||
.reduce((accum, error) => (
|
||||
accum.concat(displayError(type, error))
|
||||
), []);
|
||||
}
|
||||
|
||||
module.exports = format;
|
31
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/formatters/eslintError.js
generated
vendored
Normal file
31
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/formatters/eslintError.js
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
const concat = require('../utils').concat;
|
||||
const chalk = require('chalk');
|
||||
|
||||
const infos = [
|
||||
'You may use special comments to disable some warnings.',
|
||||
'Use ' + chalk.yellow('// eslint-disable-next-line') + ' to ignore the next line.',
|
||||
'Use ' + chalk.yellow('/* eslint-disable */') + ' to ignore all warnings in a file.'
|
||||
];
|
||||
|
||||
function displayError(error) {
|
||||
return [error.message, '']
|
||||
}
|
||||
|
||||
function format(errors, type) {
|
||||
const lintErrors = errors.filter(e => e.type === 'lint-error');
|
||||
if (lintErrors.length > 0) {
|
||||
const flatten = (accum, curr) => accum.concat(curr);
|
||||
return concat(
|
||||
lintErrors
|
||||
.map(error => displayError(error))
|
||||
.reduce(flatten, []),
|
||||
infos
|
||||
)
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
module.exports = format;
|
92
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/formatters/moduleNotFound.js
generated
vendored
Normal file
92
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/formatters/moduleNotFound.js
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
'use strict';
|
||||
const concat = require('../utils').concat;
|
||||
|
||||
function isRelative (module) {
|
||||
return module.startsWith('./') || module.startsWith('../');
|
||||
}
|
||||
|
||||
function formatFileList (files) {
|
||||
const length = files.length;
|
||||
if (!length) return '';
|
||||
return ` in ${files[0]}${files[1] ? `, ${files[1]}` : ''}${length > 2 ? ` and ${length - 2} other${length === 3 ? '' : 's'}` : ''}`;
|
||||
}
|
||||
|
||||
function formatGroup (group) {
|
||||
const files = group.errors.map(e => e.file).filter(Boolean);
|
||||
return `* ${group.module}${formatFileList(files)}`;
|
||||
}
|
||||
|
||||
|
||||
function forgetToInstall (missingDependencies) {
|
||||
const moduleNames = missingDependencies.map(missingDependency => missingDependency.module);
|
||||
|
||||
if (missingDependencies.length === 1) {
|
||||
return `To install it, you can run: npm install --save ${moduleNames.join(' ')}`;
|
||||
}
|
||||
|
||||
return `To install them, you can run: npm install --save ${moduleNames.join(' ')}`;
|
||||
}
|
||||
|
||||
function dependenciesNotFound (dependencies) {
|
||||
if (dependencies.length === 0) return;
|
||||
|
||||
return concat(
|
||||
dependencies.length === 1 ? 'This dependency was not found:' : 'These dependencies were not found:',
|
||||
'',
|
||||
dependencies.map(formatGroup),
|
||||
'',
|
||||
forgetToInstall(dependencies)
|
||||
);
|
||||
}
|
||||
|
||||
function relativeModulesNotFound (modules) {
|
||||
if (modules.length === 0) return;
|
||||
|
||||
return concat(
|
||||
modules.length === 1 ? 'This relative module was not found:' : 'These relative modules were not found:',
|
||||
'',
|
||||
modules.map(formatGroup)
|
||||
);
|
||||
}
|
||||
|
||||
function groupModules (errors) {
|
||||
const missingModule = new Map();
|
||||
|
||||
errors.forEach((error) => {
|
||||
if (!missingModule.has(error.module)) {
|
||||
missingModule.set(error.module, [])
|
||||
}
|
||||
missingModule.get(error.module).push(error);
|
||||
});
|
||||
|
||||
return Array.from(missingModule.keys()).map(module => ({
|
||||
module: module,
|
||||
relative: isRelative(module),
|
||||
errors: missingModule.get(module),
|
||||
}));
|
||||
}
|
||||
|
||||
function formatErrors (errors) {
|
||||
if (errors.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const groups = groupModules(errors);
|
||||
|
||||
const dependencies = groups.filter(group => !group.relative);
|
||||
const relativeModules = groups.filter(group => group.relative);
|
||||
|
||||
return concat(
|
||||
dependenciesNotFound(dependencies),
|
||||
dependencies.length && relativeModules.length ? ['', ''] : null,
|
||||
relativeModulesNotFound(relativeModules)
|
||||
);
|
||||
}
|
||||
|
||||
function format (errors) {
|
||||
return formatErrors(errors.filter((e) => (
|
||||
e.type === 'module-not-found'
|
||||
)));
|
||||
}
|
||||
|
||||
module.exports = format;
|
175
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/friendly-errors-plugin.js
generated
vendored
Normal file
175
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/friendly-errors-plugin.js
generated
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const chalk = require('chalk');
|
||||
const os = require('os');
|
||||
const transformErrors = require('./core/transformErrors');
|
||||
const formatErrors = require('./core/formatErrors');
|
||||
const output = require('./output');
|
||||
const utils = require('./utils');
|
||||
|
||||
const concat = utils.concat;
|
||||
const uniqueBy = utils.uniqueBy;
|
||||
|
||||
const defaultTransformers = [
|
||||
require('./transformers/babelSyntax'),
|
||||
require('./transformers/moduleNotFound'),
|
||||
require('./transformers/esLintError'),
|
||||
];
|
||||
|
||||
const defaultFormatters = [
|
||||
require('./formatters/moduleNotFound'),
|
||||
require('./formatters/eslintError'),
|
||||
require('./formatters/defaultError'),
|
||||
];
|
||||
|
||||
class FriendlyErrorsWebpackPlugin {
|
||||
|
||||
constructor(options) {
|
||||
options = options || {};
|
||||
this.compilationSuccessInfo = options.compilationSuccessInfo || {};
|
||||
this.onErrors = options.onErrors;
|
||||
this.shouldClearConsole = options.clearConsole == null ? true : Boolean(options.clearConsole);
|
||||
this.formatters = concat(defaultFormatters, options.additionalFormatters);
|
||||
this.transformers = concat(defaultTransformers, options.additionalTransformers);
|
||||
this.previousEndTimes = {};
|
||||
}
|
||||
|
||||
apply(compiler) {
|
||||
|
||||
const doneFn = stats => {
|
||||
this.clearConsole();
|
||||
|
||||
const hasErrors = stats.hasErrors();
|
||||
const hasWarnings = stats.hasWarnings();
|
||||
|
||||
if (!hasErrors && !hasWarnings) {
|
||||
this.displaySuccess(stats);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasErrors) {
|
||||
this.displayErrors(extractErrorsFromStats(stats, 'errors'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasWarnings) {
|
||||
this.displayErrors(extractErrorsFromStats(stats, 'warnings'), 'warning');
|
||||
}
|
||||
};
|
||||
|
||||
const invalidFn = () => {
|
||||
this.clearConsole();
|
||||
output.title('info', 'WAIT', 'Compiling...');
|
||||
};
|
||||
|
||||
if (compiler.hooks) {
|
||||
const plugin = { name: 'FriendlyErrorsWebpackPlugin' };
|
||||
|
||||
compiler.hooks.done.tap(plugin, doneFn);
|
||||
compiler.hooks.invalid.tap(plugin, invalidFn);
|
||||
} else {
|
||||
compiler.plugin('done', doneFn);
|
||||
compiler.plugin('invalid', invalidFn);
|
||||
}
|
||||
}
|
||||
|
||||
clearConsole() {
|
||||
if (this.shouldClearConsole) {
|
||||
output.clearConsole();
|
||||
}
|
||||
}
|
||||
|
||||
displaySuccess(stats) {
|
||||
const time = isMultiStats(stats) ? this.getMultiStatsCompileTime(stats) : this.getStatsCompileTime(stats);
|
||||
output.title('success', 'DONE', 'Compiled successfully in ' + time + 'ms');
|
||||
|
||||
if (this.compilationSuccessInfo.messages) {
|
||||
this.compilationSuccessInfo.messages.forEach(message => output.info(message));
|
||||
}
|
||||
if (this.compilationSuccessInfo.notes) {
|
||||
output.log();
|
||||
this.compilationSuccessInfo.notes.forEach(note => output.note(note));
|
||||
}
|
||||
}
|
||||
|
||||
displayErrors(errors, severity) {
|
||||
const processedErrors = transformErrors(errors, this.transformers);
|
||||
|
||||
const topErrors = getMaxSeverityErrors(processedErrors);
|
||||
const nbErrors = topErrors.length;
|
||||
|
||||
const subtitle = severity === 'error' ?
|
||||
`Failed to compile with ${nbErrors} ${severity}${nbErrors === 1 ? '' : 's'}` :
|
||||
`Compiled with ${nbErrors} ${severity}${nbErrors === 1 ? '' : 's'}`;
|
||||
output.title(severity, severity.toUpperCase(), subtitle);
|
||||
|
||||
if (this.onErrors) {
|
||||
this.onErrors(severity, topErrors);
|
||||
}
|
||||
|
||||
formatErrors(topErrors, this.formatters, severity)
|
||||
.forEach(chunk => output.log(chunk));
|
||||
}
|
||||
|
||||
getStatsCompileTime(stats, statsIndex) {
|
||||
// When we have multi compilations but only one of them is rebuilt, we need to skip the
|
||||
// unchanged compilers to report the true rebuild time.
|
||||
if (statsIndex !== undefined) {
|
||||
if (this.previousEndTimes[statsIndex] === stats.endTime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
this.previousEndTimes[statsIndex] = stats.endTime;
|
||||
}
|
||||
|
||||
return stats.endTime - stats.startTime;
|
||||
}
|
||||
|
||||
getMultiStatsCompileTime(stats) {
|
||||
// Webpack multi compilations run in parallel so using the longest duration.
|
||||
// https://webpack.github.io/docs/configuration.html#multiple-configurations
|
||||
return stats.stats
|
||||
.reduce((time, stats, index) => Math.max(time, this.getStatsCompileTime(stats, index)), 0);
|
||||
}
|
||||
}
|
||||
|
||||
function extractErrorsFromStats(stats, type) {
|
||||
if (isMultiStats(stats)) {
|
||||
const errors = stats.stats
|
||||
.reduce((errors, stats) => errors.concat(extractErrorsFromStats(stats, type)), []);
|
||||
// Dedupe to avoid showing the same error many times when multiple
|
||||
// compilers depend on the same module.
|
||||
return uniqueBy(errors, error => error.message);
|
||||
}
|
||||
|
||||
const findErrorsRecursive = (compilation) => {
|
||||
const errors = compilation[type];
|
||||
if (errors.length === 0 && compilation.children) {
|
||||
for (const child of compilation.children) {
|
||||
errors.push(...findErrorsRecursive(child));
|
||||
}
|
||||
}
|
||||
|
||||
return uniqueBy(errors, error => error.message);
|
||||
};
|
||||
|
||||
return findErrorsRecursive(stats.compilation);
|
||||
}
|
||||
|
||||
function isMultiStats(stats) {
|
||||
return stats.stats;
|
||||
}
|
||||
|
||||
function getMaxSeverityErrors(errors) {
|
||||
const maxSeverity = getMaxInt(errors, 'severity');
|
||||
return errors.filter(e => e.severity === maxSeverity);
|
||||
}
|
||||
|
||||
function getMaxInt(collection, propertyName) {
|
||||
return collection.reduce((res, curr) => {
|
||||
return curr[propertyName] > res ? curr[propertyName] : res;
|
||||
}, 0)
|
||||
}
|
||||
|
||||
module.exports = FriendlyErrorsWebpackPlugin;
|
111
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/output.js
generated
vendored
Normal file
111
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/output.js
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
'use strict';
|
||||
|
||||
const colors = require('./utils/colors');
|
||||
const chalk = require('chalk');
|
||||
const stringWidth = require('string-width');
|
||||
const readline = require('readline');
|
||||
const stripAnsi = require('strip-ansi');
|
||||
|
||||
class Debugger {
|
||||
|
||||
constructor () {
|
||||
this.enabled = true;
|
||||
this.capturing = false;
|
||||
this.capturedMessages = [];
|
||||
}
|
||||
|
||||
enable () {
|
||||
this.enabled = true;
|
||||
}
|
||||
|
||||
capture () {
|
||||
this.enabled = true;
|
||||
this.capturing = true;
|
||||
}
|
||||
|
||||
endCapture () {
|
||||
this.enabled = false;
|
||||
this.capturing = false;
|
||||
this.capturedMessages = [];
|
||||
}
|
||||
|
||||
log () {
|
||||
if (this.enabled) {
|
||||
this.captureConsole(Array.from(arguments), console.log);
|
||||
}
|
||||
}
|
||||
|
||||
info (message) {
|
||||
if (this.enabled) {
|
||||
const titleFormatted = colors.formatTitle('info', 'I');
|
||||
this.log(titleFormatted, message);
|
||||
}
|
||||
}
|
||||
|
||||
note (message) {
|
||||
if (this.enabled) {
|
||||
const titleFormatted = colors.formatTitle('note', 'N');
|
||||
this.log(titleFormatted, message);
|
||||
}
|
||||
}
|
||||
|
||||
title (severity, title, subtitle) {
|
||||
if (this.enabled) {
|
||||
const date = new Date();
|
||||
const dateString = chalk.grey(date.toLocaleTimeString());
|
||||
const titleFormatted = colors.formatTitle(severity, title);
|
||||
const subTitleFormatted = colors.formatText(severity, subtitle);
|
||||
const message = `${titleFormatted} ${subTitleFormatted}`
|
||||
|
||||
// In test environment we don't include timestamp
|
||||
if(process.env.NODE_ENV === 'test') {
|
||||
this.log(message);
|
||||
this.log();
|
||||
return;
|
||||
}
|
||||
|
||||
// Make timestamp appear at the end of the line
|
||||
let logSpace = process.stdout.columns - stringWidth(message) - stringWidth(dateString)
|
||||
if (logSpace <= 0) {
|
||||
logSpace = 10
|
||||
}
|
||||
|
||||
this.log(`${message}${' '.repeat(logSpace)}${dateString}`);
|
||||
this.log();
|
||||
}
|
||||
}
|
||||
|
||||
clearConsole () {
|
||||
if (!process.env.CI && !this.capturing && this.enabled && process.stdout.isTTY) {
|
||||
// Fill screen with blank lines. Then move to 0 (beginning of visible part) and clear it
|
||||
const blank = '\n'.repeat(process.stdout.rows)
|
||||
console.log(blank)
|
||||
readline.cursorTo(process.stdout, 0, 0)
|
||||
readline.clearScreenDown(process.stdout)
|
||||
}
|
||||
}
|
||||
|
||||
captureLogs (fun) {
|
||||
try {
|
||||
this.capture();
|
||||
fun.call();
|
||||
return this.capturedMessages;
|
||||
} finally {
|
||||
this.endCapture();
|
||||
}
|
||||
}
|
||||
|
||||
captureConsole (args, method) {
|
||||
if (this.capturing) {
|
||||
this.capturedMessages.push(stripAnsi(args.join(' ')).trim());
|
||||
} else {
|
||||
method.apply(console, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function capitalizeFirstLetter (string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
module.exports = new Debugger();
|
42
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/transformers/babelSyntax.js
generated
vendored
Normal file
42
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/transformers/babelSyntax.js
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* This will be removed in next versions as it is not handled in the babel-loader
|
||||
* See: https://github.com/geowarin/friendly-errors-webpack-plugin/issues/2
|
||||
*/
|
||||
function cleanStackTrace(message) {
|
||||
return message
|
||||
.replace(/^\s*at\s.*:\d+:\d+[\s)]*\n/gm, ''); // at ... ...:x:y
|
||||
}
|
||||
|
||||
function cleanMessage(message) {
|
||||
return message
|
||||
// match until the last semicolon followed by a space
|
||||
// this should match
|
||||
// linux => "(SyntaxError: )Unexpected token (5:11)"
|
||||
// windows => "(SyntaxError: C:/projects/index.js: )Unexpected token (5:11)"
|
||||
.replace(/^Module build failed.*:\s/, 'Syntax Error: ')
|
||||
// remove mini-css-extract-plugin loader tracing errors
|
||||
.replace(/^Syntax Error: ModuleBuildError:.*:\s/, '')
|
||||
// remove babel extra wording and path
|
||||
.replace(/^Syntax Error: SyntaxError: (([A-Z]:)?\/.*:\s)?/, 'Syntax Error: ');
|
||||
}
|
||||
|
||||
function isBabelSyntaxError(e) {
|
||||
return e.name === 'ModuleBuildError' || e.name === 'ModuleBuildError' &&
|
||||
e.message.indexOf('SyntaxError') >= 0;
|
||||
}
|
||||
|
||||
function transform(error) {
|
||||
if (isBabelSyntaxError(error)) {
|
||||
return Object.assign({}, error, {
|
||||
message: cleanStackTrace(cleanMessage(error.message) + '\n'),
|
||||
severity: 1000,
|
||||
name: 'Syntax Error',
|
||||
});
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
module.exports = transform;
|
20
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/transformers/esLintError.js
generated
vendored
Normal file
20
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/transformers/esLintError.js
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
function isEslintError (e) {
|
||||
return e.originalStack
|
||||
.some(stackframe => stackframe.fileName && stackframe.fileName.indexOf('eslint-loader') > 0) ||
|
||||
e.name === 'ESLintError';
|
||||
}
|
||||
|
||||
function transform(error) {
|
||||
if (isEslintError(error)) {
|
||||
return Object.assign({}, error, {
|
||||
name: 'Lint error',
|
||||
type: 'lint-error',
|
||||
});
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
module.exports = transform;
|
30
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/transformers/moduleNotFound.js
generated
vendored
Normal file
30
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/transformers/moduleNotFound.js
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const TYPE = 'module-not-found';
|
||||
|
||||
function isModuleNotFoundError (e) {
|
||||
const webpackError = e.webpackError || {};
|
||||
return webpackError.dependencies
|
||||
&& webpackError.dependencies.length > 0
|
||||
&& e.name === 'ModuleNotFoundError'
|
||||
&& e.message.indexOf('Module not found') === 0;
|
||||
}
|
||||
|
||||
function transform(error) {
|
||||
const webpackError = error.webpackError;
|
||||
if (isModuleNotFoundError(error)) {
|
||||
const dependency = webpackError.dependencies[0];
|
||||
const module = dependency.request || dependency.options.request;
|
||||
return Object.assign({}, error, {
|
||||
message: `Module not found ${module}`,
|
||||
type: TYPE,
|
||||
severity: 900,
|
||||
module,
|
||||
name: 'Module not found'
|
||||
});
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
module.exports = transform;
|
38
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/utils/colors.js
generated
vendored
Normal file
38
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/utils/colors.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
const chalk = require('chalk');
|
||||
|
||||
function formatTitle(severity, message) {
|
||||
return chalk[bgColor(severity)].black('', message, '');
|
||||
}
|
||||
|
||||
function formatText(severity, message) {
|
||||
return chalk[textColor(severity)](message);
|
||||
}
|
||||
|
||||
function bgColor(severity) {
|
||||
const color = textColor(severity);
|
||||
return 'bg'+ capitalizeFirstLetter(color)
|
||||
}
|
||||
|
||||
function textColor(severity) {
|
||||
switch (severity.toLowerCase()) {
|
||||
case 'success': return 'green';
|
||||
case 'info': return 'blue';
|
||||
case 'note': return 'white';
|
||||
case 'warning': return 'yellow';
|
||||
case 'error': return 'red';
|
||||
default: return 'red';
|
||||
}
|
||||
}
|
||||
|
||||
function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
bgColor: bgColor,
|
||||
textColor: textColor,
|
||||
formatTitle: formatTitle,
|
||||
formatText: formatText
|
||||
};
|
31
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/utils/index.js
generated
vendored
Normal file
31
app_vue/node_modules/@soda/friendly-errors-webpack-plugin/src/utils/index.js
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Concat and flattens non-null values.
|
||||
* Ex: concat(1, undefined, 2, [3, 4]) = [1, 2, 3, 4]
|
||||
*/
|
||||
function concat() {
|
||||
const args = Array.from(arguments).filter(e => e != null);
|
||||
const baseArray = Array.isArray(args[0]) ? args[0] : [args[0]];
|
||||
return Array.prototype.concat.apply(baseArray, args.slice(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dedupes array based on criterion returned from iteratee function.
|
||||
* Ex: uniqueBy(
|
||||
* [{ id: 1 }, { id: 1 }, { id: 2 }],
|
||||
* val => val.id
|
||||
* ) = [{ id: 1 }, { id: 2 }]
|
||||
*/
|
||||
function uniqueBy(arr, fun) {
|
||||
const seen = {};
|
||||
return arr.filter(el => {
|
||||
const e = fun(el);
|
||||
return !(e in seen) && (seen[e] = 1);
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
concat: concat,
|
||||
uniqueBy: uniqueBy
|
||||
};
|
Reference in New Issue
Block a user