Skip to content
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

[feature] configuration validation #240

Merged

Conversation

jbottigliero
Copy link
Member

  • uses JSON schema to validate configuration types.
    • validated via webpack/lib/validateSchema
  • adds tests for various configuration types
    • adds negative tests for an invalid type and array.

What kind of change does this PR introduce?
Feature

Did you add tests for your changes?
Yes – I'll probably add more based on actual desired implementation.

If relevant, did you update the documentation?
N/A – for now.

Summary

This is an port of webpack/webpack#6255 which is intended to resolve webpack/webpack#4977.

Does this PR introduce a breaking change?

No, it's not expected to... However, it may cause previously invalid configuration objects to throw errors not seen before.

Other information

Some outstanding questions (from webpack/webpack#6255):

  • Is using JSON schema validation too much for this?
    • It does seem like it might be better to combine this validation with the configuration options validation. This would be a much larger change and is worthy of a discussion.
  • Should it be using the WebpackOptionsValidationError class? The updated output still leaves a bit to be desired. This could be accomplished using the same class or it's own.

With the code now being in separate repositories/modules, I could see how the proposed solution is less than ideal. I'm up for discussing how to move forward!

@jbottigliero
Copy link
Member Author

I believe the failing tests here are addressed in #238

@ematipico
Copy link
Contributor

Yeah exactly, these are tests due to the new version of webpack and how it outputs the entry points.

@evenstensberg
Copy link
Member

Let's wait for the fix on that to land and then do a review/rebase

@@ -3,6 +3,10 @@ var fs = require("fs");
fs.existsSync = fs.existsSync || path.existsSync;
var interpret = require("interpret");
var prepareOptions = require("./prepareOptions");
var webpackConfigurationSchema = require("../schemas/webpackConfigurationSchema.json");
var validateSchema = require("webpack/lib/validateSchema");
var WebpackOptionsValidationError = require("webpack/lib/WebpackOptionsValidationError");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use webpack.WebpackOptionsValidationError instead

@@ -3,6 +3,10 @@ var fs = require("fs");
fs.existsSync = fs.existsSync || path.existsSync;
var interpret = require("interpret");
var prepareOptions = require("./prepareOptions");
var webpackConfigurationSchema = require("../schemas/webpackConfigurationSchema.json");
var validateSchema = require("webpack/lib/validateSchema");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use webpack.validateSchema instead

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you switch this over @jbottigliero?

@evenstensberg
Copy link
Member

@jbottigliero mind rebasing against the master branch?

@jbottigliero
Copy link
Member Author

@ev1stensberg – rebased and updated. I wasn't able to reproduce the test failure in node@6 locally, should I just re-trigger the build? Any insight here would be helpful!

@ooflorent – for the usage of webpack.*... I was basing my implementation/usage of webpack lib files off of lib/commands/migration.js. I'm not super familiar with the build process and this package's association between webpack core, yet. Is it safe to require webpack core here? I'll dig through the code myself, but any advice in direction would be helpful!

@evenstensberg
Copy link
Member

@jbottigliero sure, happens sometimes, let's do another try

@jbottigliero jbottigliero reopened this Jan 8, 2018
@evenstensberg
Copy link
Member

Re-started your build, let's cross fingers 🤞

@webpack-bot
Copy link

Thank you for your pull request! The most important CI builds succeeded, we’ll review the pull request soon.

@jbottigliero
Copy link
Member Author

@ooflorent – for the usage of webpack.*... I was basing my implementation/usage of webpack lib files off of lib/commands/migration.js. I'm not super familiar with the build process and this package's association between webpack core, yet. Is it safe to require webpack core here? I'll dig through the code myself, but any advice in direction would be helpful!

Updated based on #229.

cc. @TheLarkInn

Copy link
Member

@evenstensberg evenstensberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, passing to @TheLarkInn or @fokusferit to 2nd review

Copy link
Contributor

@fokusferit fokusferit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, as far as I can see (read also the source code of validateSchema and WebpackOptionsValidationError, it looks fine.

I'm currently thinking of more test cases, I'd like to to throw in some more , maybe complex configurations to see if everything is still fine. @ev1stensberg any thoughts on that ? Otherwise I would approve it.

@jbottigliero
Copy link
Member Author

Thanks for taking a look @ev1stensberg and @fokusferit.

After taking another look at the code in bin/convert-argv.js, maybe the validation could be more strict?

When processConfiguredOptions is called, it looks like the configuration can only ever be a Promise, object or array of objects.

When you're using a function for a configuration, it's actually handled by prepareOptions.

Seems like I could/should also add a case for the Promise configuration.

@fokusferit
Copy link
Contributor

Hey @jbottigliero what do you think regarding about adding a test case for Promiseconfiguration? Just wanted to follow up :)

@webpack-bot
Copy link

@jbottigliero Thanks for your update.

I labeled the Pull Request so reviewers will review it again.

@ev1stensberg Please review the new changes.

@jbottigliero
Copy link
Member Author

jbottigliero commented Jan 31, 2018

@fokusferit, @ev1stensberg, just took a look at this...

Unless I'm mistaking there are few things that need to happen in order to make this work (at least to validate the Promise instance).

It appears the ajv-keywords package doesn't actually support "instanceof": "Promise". I plan to open a ticket there to discuss whether or not it could/should be added – I'll follow-up on this.

An alternative would be to add a custom validator similar towebpack's addition of absolutePath
... because we're sharing the validator, I'll need to open a PR against webpack core.
EDIT: A better alternative would just be adding Promise as custom constructor... but would still need to happen in webpack core.

I think ideally we get Promise added to the ajv-keywords package.

For now, I've added two new tests and resolved merge conflicts.

@jbottigliero
Copy link
Member Author

(tests are passing now because it's still just "instanceof": "Function")

@jbottigliero
Copy link
Member Author

jbottigliero commented Jan 31, 2018

Support for "instanceof": "Promise" was just merged – ajv-validator/ajv-keywords#51 (closed ajv-validator/ajv-keywords#52).

Once released, I'll open a PR bumping webpack core's dependency version and update here.

jbottigliero pushed a commit to jbottigliero/webpack that referenced this pull request Jan 31, 2018
- updates to `ajv@6.1.0`
- updates to `ajv-keywords@3.1.0` (required for _better_ validation in webpack/webpack-cli#240)
@evenstensberg
Copy link
Member

Maybe we can keep it like this an open an issue up for discussion? Instead of rushing it

@jbottigliero
Copy link
Member Author

@ev1stensberg works for me. I did just open webpack/webpack#6430...

The dependency version bump in core does feel pretty heavy-handed based on the original intent of this PR.

I'll be watching for feedback, thanks again.

@evenstensberg
Copy link
Member

Can you make an issue at webpack-cli with what we've just discussed and link to the 6430 and this pr? Thanks!

Copy link
Member

@evenstensberg evenstensberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any specific error message here except that you're throwing the validationSchema. Could you add an extra log on top of the validation schema that's something like: You passed X into webpack, we expect Y?

@jbottigliero
Copy link
Member Author

The console.error will log:

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration should be one of these:
   object | [object] | function
   Details:
    * configuration should be an object.
      -> A webpack configuration object.
    * configuration should be an array:
      [object]
      -> An array of webpack configuration objects.
    * configuration should be an instance of function
      -> A promise that resolves with a configuration object, or an array of configuration objects.

I can certainly add something along the lines of Received: ${typeof options} (${options}) to this.

@evenstensberg
Copy link
Member

Previous looked fine, but some extra indication would be nice, like the schema, but:


Webpack has been initialised using a configuration object that does not match the API schema. Recieved: $type 
...

@evenstensberg
Copy link
Member

But that might be a schema thing, so LGTM :shipit:

console.error(
"Config did not export an object or a function returning an object."
error.message,
`\nReceived: ${typeof options} : ${JSON.stringify(options, null, 2)}`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the json stringify callback to b correct @fokusferit @ematipico

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a newline \n straight after :. But the rest looks good to me

@ematipico
Copy link
Contributor

I really like the correct indentation of the configuration error, it makes more cleaner and easier to read!

@evenstensberg evenstensberg merged commit a15807b into webpack:master Feb 2, 2018
@evenstensberg
Copy link
Member

Thanks ☝️💙💙

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Show more accurate validation information for initial configuration
7 participants