When I have a loader configuration with multiple tests matching a file, I would expect only the first matching loader to be used but that doesn\'t seem to be the case.
Official documentation explains it really well. Unfortunately all the necessary info are spread in different sections of documentation. Let me wrap up all that you need to know.
1.
Make sure they are in correct order (bottom to top).
2.
They are functions that take the source of a resource file as the parameter and return the new source.
3.
Loaders can be chained. They are applied in a pipeline to the resource. The final loader is expected to return JavaScript; each other loader can return source in arbitrary format, which is passed to the next loader.
So...
If you have somefile.css and you are passing it through loaderOne, loaderTwo, loaderThree is behaves like a regular chained function.
{
test: /\.css$/,
loaders: ['loaderOne', 'loaderTwo', 'loaderThree']
}
means exactlly the same as...
loaderOne(loaderTwo(loaderThree(somefile.css)))
If you are coming from grunt || gulp world it is confusing. Just read loaders order from right to left.