js-dxtools / webpack-validator

Validates your webpack config with Joi
MIT License
295 stars 29 forks source link

Array of configurations gives vague validation error #117

Closed sadafie closed 8 years ago

sadafie commented 8 years ago

Using Webpack 2 and multi-configurations, I get the following output (shortened) and error:

[
  {
    "entry": {
      "client": [
        "/Users/sadaf/git_repo/mup-web/src/client.jsx"
      ]
    },
    "output": {
      "path": "/Users/sadaf/git_repo/mup-web/build/locale/fr-FR",
      "filename": "fr-FR.[name].js",
      "publicPath": "//0.0.0.0:8001/"
    },
    "devtool": "eval",
    "module": {
      "preLoaders": [
        {
          "test": {},
          "loader": "eslint-loader",
          "include": [
            "/Users/sadaf/git_repo/mup-web/src"
          ],
          "exclude": "/Users/sadaf/git_repo/mup-web/src/assets"
        }
      ],
      "loaders": [
        {
          "test": {},
          "include": [
            "/Users/sadaf/git_repo/mup-web/src"
          ],
          "loader": "babel-loader",
          "query": {
            "plugins": [
              [
                "react-transform",
                {
                  "transforms": [
                    {
                      "transform": "react-transform-hmr",
                      "imports": [
                        "react"
                      ],
                      "locals": [
                        "module"
                      ]
                    }
                  ]
                }
              ]
            ]
          }
        },
        {
          "test": {},
          "include": [
            "/Users/sadaf/git_repo/mup-web/src/assets/css"
          ],
          "loader": "style!css"
        },
        {
          "test": {},
          "include": [
            "/Users/sadaf/git_repo/mup-web/src"
          ],
          "loader": "json"
        }
      ]
    },
    "resolve": {
      "extensions": [
        ".js",
        ".jsx"
      ]
    },
    "plugins": [
      {
        "options": {
          "0": "/Users/sadaf/git_repo/mup-web/src/assets/svg/**/*.svg",
          "svg": {
            "xmlns": "http://www.w3.org/2000/svg",
            "style": "position:absolute; width: 0; height: 0"
          },
          "svgoOptions": {},
          "name": "sprite.[hash].svg",
          "prefix": "icon-",
          "template": "/Users/sadaf/git_repo/mup-web/node_modules/webpack-svgstore-plugin/src/templates/layout.pug"
        }
      }
    ]
  },
  ...
]

[1] "value" must be an object

Perhaps there is an error in my config (though it builds), but this error does not clearly point to the issue.

nyrosmith commented 8 years ago

I had the same error message. It seems you don't give the validator an object that contains the config. Can you show how you call webpack-validator and your complete config? Maybe you can share a gist?

kentcdodds commented 8 years ago

My thought is that we should just do a check before validating the config. If it's an array, then iterate through it and pass each item into the validator.

sadafie commented 8 years ago

Can you show how you call webpack-validator and your complete config? Maybe you can share a gist?

Sorry, I fixed a copy/paste error in my config. It's not an object, it's an array of objects. The following configs are nearly identical to the one I pasted.

If it's an array, then iterate through it and pass each item into the validator.

That's how I would expect it to work as well.

kentcdodds commented 8 years ago

@sadafie would you be interested to makeapullrequest.com? The relevant code is here

sadafie commented 8 years ago

Yep, I'll submit a PR

sadafie commented 8 years ago

@kentcdodds I finally got around to looking at this today. The notion of iterating over each array item (seemingly?) doesn't work because the validate method is used to validate each of the properties as well, and adding the Array check breaks some of the existing tests (i.e., entry.test.js).

An alternative that stood out to me was to update the base Joi schema type to be an array:

const schema = Joi.array().items(Joi.object({
    amd: Joi.object(),
    bail: Joi.boolean(),
    cache: Joi.boolean(),
    context: contextSchema,
    debug: Joi.boolean(),
    devServer: devServerSchema,
    devtool: devtoolSchema,
    entry: entrySchema,
    externals: externalsSchema,
    loader: Joi.any(), // ?
    module: moduleSchema,
    node: nodeSchema,
    output: outputSchema,
    plugins: pluginsSchema,
    profile: Joi.boolean(),
    progress: Joi.boolean(),
    recordsInputPath: looksLikeAbsolutePath,
    recordsOutputPath: looksLikeAbsolutePath,
    recordsPath: looksLikeAbsolutePath,
    resolve: resolveSchema,
    resolveLoader: resolveSchema.concat(Joi.object({
      moduleTemplates: Joi.array().items(Joi.string()),
    })),
    watch: Joi.boolean(),
    watchOptions: watchOptionsSchema,
    stats: Joi.any(), // TODO
    target: Joi.any(), // TODO

    // Plugins
    postcss: Joi.any(),
    eslint: Joi.any(),
    tslint: Joi.any(),
    metadata: Joi.any(),
  })).single()

But that breaks the schemaExtension case where two schema's are concat-ed together. Joi only concats schemas of the same type.

Not sure if there are any recommendations here, or if someone more familiar with this code wants to take a stab.

kentcdodds commented 8 years ago

the validate method is used to validate each of the properties as well,

Ah, yeah, that makes sense. Maybe instead we can create a validateRoot method which will be the new module.exports and that will call the validate method. That way we can separate the start of the validation at the root of the config from the property validation. Would that work?

sadafie commented 8 years ago

Maybe instead we can create a validateRoot

Let me play around with that. It seems like it would work, but I wasn't sure if it'd be a non-ideal solution.

jonathanglasmeyer commented 8 years ago

(Accidentally pressed the close button on mobile, doh. Sorry :))

sadafie commented 8 years ago

Ok, I think I have a working solution, but cant commit because it's failing code coverage. Is there a way to check exactly which code branch is the one not covered?

kentcdodds commented 8 years ago

Yeah, use --no-verify when committing and push up your branch so we can chat about it :-)

kentcdodds commented 8 years ago

Oh, sorry, I misread your message. You should be able to open the file: coverage/lcov-report/index.html and that'll show you the code coverage reports :+1:

ghost commented 8 years ago

I'm facing this issue in the latest version (v2.2.8) and webpack v1.13.2

My config is:

module.exports = validate([
  {},
  {}
]);
$ npm list | grep webpack-validator                                                        
└─┬ webpack-validator@2.2.8
$ node_modules/.bin/webpack                                                                
[
  {},
  {}
]

[1] "value" must be an object