New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fixes #133: Add Support for Webpack-Standard Errors #136
Conversation
add travis
npm: update dependencies
inherited from sass-webpack-plugin
npm: clean not used dependencies
npm: add version script
* Update stylelint dependency * Fix renamed rules in stylelint v7 * Add editorconfig * Simplify linter * Use chai array length assertion * Restructure with linting and coverage * Add some documentation for runCompilation and add missing use strict * Keep stylelint v7 in peerDependencies
Add some jsdoc comments to the "public API"
- consistent tense in test suite - corrected editorconfig for markdown files - use `.have.length` assertion - add gitter badge
* Fixed warnings not being logged to console Warnings were not being logged unless there was an error in the css linting. * Corrected number of warnings returned
* It should work without configuration, just use default one * It should warn user if .stylelintrc file does not exit * Add warnings check
* Add micromatch * Use micromatch to check changes * Remove matchbase in micromatch
* style: correct td.verify calls to match documentation * style: use const/lets in lint-dirty-modules.test.js
Fixes downstream vulnerability: https://snyk.io/vuln/npm:braces:20180219
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is great! Thank you @shellscape for taking your time to do this and updating the docs & tests.
I have some questions and freshly picked nits. Let me know what you think.
README.md
Outdated
```js | ||
plugins: [ | ||
new StyleLintPlugin({ | ||
formatter: 'webpack' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer explicitly require
ing the function, i.e. formatter: require('stylelint-webpack-plugin/lib/webpack-formatter')
to keep the signature consistent and remove an (IMO) unnecessary branch in index.js
. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Experience on the core team points to that being another unnecessary step for users (that's been a very big public gripe recently)
index.js
Outdated
@@ -10,6 +10,7 @@ var formatter = require('stylelint').formatters.string; | |||
var runCompilation = require('./lib/run-compilation'); | |||
var LintDirtyModulesPlugin = require('./lib/lint-dirty-modules-plugin'); | |||
var defaultFilesGlob = require('./lib/constants').defaultFilesGlob; | |||
var webpackFormatter = require('./lib/formatter-webpack'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nit, the filename should be kebab-cased version of the export, i.e. webpack-formatter
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we put the context after the subject, then lint-dirty-modules-plugin
should be named dirty-modules-plugin-lint
as well ;) that seems inconsistent with the rest of the codebase
lib/formatter-webpack.js
Outdated
@@ -0,0 +1,27 @@ | |||
'use strict'; | |||
|
|||
const StylelintPluginError = require('./StylelintPluginError'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another minor nit, the filename should be kebab-cased version of the export, i.e. stylelint-plugin-error
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah you're requesting that change in the classes file. that's pretty unusual for a file that exports a class :)
lib/StylelintPluginError.js
Outdated
|
||
module.exports = class StylelintPluginError extends Base { | ||
constructor(message) { | ||
super(message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL that ES2015 will automatically do these kinds of constructors, so this export could just be:
module.exports = class StylelintPluginError extends Base {};
and can become more complicated later on as necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer being verbose here. It's especially relevant when the RFC changes are implemented, as it'll likely need to do some things with the constructor.
lib/formatter-webpack.js
Outdated
module.exports = function webpack (items) { | ||
const result = []; | ||
|
||
for (const item of items) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is your opinion on doing this with a .reduce
and .map
s? I understand this imperative version is probably simpler to read, and for now is all we need, but I like the "pure" versions because they are easier to test the individual units should they need to be extracted at some point. I took the liberty of writing this all out, just for my own understanding:
module.exports = function webpackFormatter (items) {
return items.reduce(function (result, item) {
const file = item.source;
const warnings = item.warnings.map(function (warning) {
const line = warning.line;
const column = warning.column;
const text = warning.text;
return new StylelintPluginError(file + '\n' + line + ':' + column + ' stylelint: ' + text);
});
const invalidOptionWarnings = item.invalidOptionWarnings.map(function (warning) {
return new StylelintPluginError('stylelint\n0:0 ' + warning.text);
});
return result.concat(warnings, invalidOptionWarnings);
}, []);
};
When the codebase is eventually upgraded to use things like destructuring and arrow functions this method will become much shorter :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah it's six of one, half dozen of another. There's no performance gain so it's all personal preference. If you'd prefer to see this format instead, please do edit the code in the PR (github will allow you to do that here on the site)
README.md
Outdated
|
||
When using this plugin with a webpack reporter, such as | ||
[webpack-stylish](https://github.com/webpack-contrib/webpack-stylish), you must | ||
set the `formatter` option to `'webpack'` for proper error and warning output. eg: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extreme nit: s/eg/e.g.
(I'm sorry)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do edit the PR in the Github UX for this :)
README.md
Outdated
formatter: 'webpack' | ||
}) | ||
] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another extreme nit, please remove extra whitespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do edit the PR in the Github UX for this :)
package.json
Outdated
@@ -76,6 +76,9 @@ | |||
"globals": [ | |||
"getPath", | |||
"expect" | |||
], | |||
"ignore": [ | |||
"/lib/StylelintPluginError.js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with the automatic constructor, I think this is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
semistandard complains about the class not being used, in the same file the class is being declared. unfortunately it's necessary for CI to pass
test/helpers/base-config.js
Outdated
var configFilePath = getPath('./.stylelintrc'); | ||
module.exports = function (options) { | ||
var configFilePath = getPath('./.stylelintrc'); | ||
const pluginOptions = Object.assign({ configFile: configFilePath }, options || {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great change! Thank you!
However, could you:
- use the
object-assign
polyfill, to remain consistent with the rest of the codebase - update
baseConfig()
s usages in the tests to remove the unnecessaryconfig
objects everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one doesn't ring as necessary. You're only testing your code on Node 4+, which don't require a polyfill.
lib/run-compilation.js
Outdated
} | ||
|
||
format('warnings'); | ||
format('errors'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome, thank you. 💯 👍
Thanks for reviewing. I honestly appreciate the thorough look. I say this with all positive intent: the codebase for the plugin could definitely use that level of scrutiny as well. I think we disagree some of the responses for the PR, but I would be completely cool if you edited the PR with those changes. This PR will set the plugin up for success and a minimal transition when the Error Alignment RFC (which I'm starting implementing of tonight) lands in webpack@3 and 4. 🍺 |
Transfering ownership to webpack-contrib
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shellscape What about sing snapshot, it will be better and easy to reading 👍
I think there's a translation problem there my friend 😆 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's tests better later. 👍
@shellscape - This will require a rebase against current master & can / should be reopened. |
This PR addresses #133 by pushing errors to
compilation.warnings
andcompilations.errors
that follow the standard (and by standard we mean presently most frequently used) webpack error message format. This format is parsed bywebpack-stylish
and future reporters until the RFC for revamping webpack errors is implemented.This PR:
StylelintPluginError
in anticipation of future work. It inherits fromWebpackError
if the class exists (v2.5.0+).formatter-webpack.js
which utilizesStylelintPluginError
and returns an array of error objects.run-compilation.js
by consolidating the code for pushing warnings and errors to thecompilation
and handling the case in which a formatter returns an array instead of a string, while still accounting for a string (in the case of the default formatter).options.formatter = 'webpack'
in the options for the plugin in the webpack config. (This will be noted in webpack-stylish as well). The README for this project was updated with that info.And as an added bonus you now have tests touching the
options.formatter
property.It's worth noting that once webpack/webpack#6534 is implemented in it's final form, this plugin will start to throw warnings in the console for webpack@3, and errors for webpack@4, and will have to be updated again to follow that new standard.