Adding a loader results in Webpack "Invalid configuration object" error in some cases
ajani2001 opened this issue · comments
I want to add html-loader and I do it according to the recipe:
import {CracoConfig} from "@craco/types";
import {addBeforeLoader, loaderByName} from "@craco/craco";
const config: CracoConfig = {
webpack: {
configure: (webpackConfig) => {
webpackConfig.resolve!.extensions!.push('.html');
const htmlLoader = {
loader: require.resolve('html-loader'),
test: /\.html$/,
exclude: /node_modules/,
};
addBeforeLoader(webpackConfig, loaderByName('file-loader'), htmlLoader);
return webpackConfig;
},
}
};
export default config;
But my application even doesn`t starts:
Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.module.rules[1] should be one of these:
["..." | object { assert?, compiler?, dependency?, descriptionData?, enforce?, exclude?, generator?, include?, issuer?, issuerLayer?, layer?, loader?, mimetype?, oneOf?, options?, parser?, realResource?, resolve?, resource?, resourceFragment?, resourceQuery?, rules?, scheme?, sideEffects?, test?, type?, use? }, ...]
-> A rule.
Details:
* configuration.module.rules[1].oneOf[2].use[1] has an unknown property 'test'. These properties are valid:
object { ident?, loader?, options? }
* configuration.module.rules[1].oneOf[2].use[1] has an unknown property 'exclude'. These properties are valid:
object { ident?, loader?, options? }
It can be reproduced on a blank app just created by create-react-app (with typescript in my case).
"@craco/craco": "^7.0.0",
"@craco/types": "^7.0.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.4"
I suppose, this is a rare bug, that emerge, when a target loader for addBeforeLoader`s matcher becomes a RuleSetUseItem located in the 'use' array. New loader argument for addBeforeLoader has the type of RuleSetRule, thus, a RuleSetRule is inserted in the 'use' array and breaks the consistency.
The root of problem might me in this cast:
craco/packages/craco/src/lib/loaders.ts
Line 49 in 47fb53b
did you ever find a fix for this? I was a little suprised that copying and pasting the provided code doesn't work.
I was able to work around this issue by using a diffrent loader as the starting point, doing this seems to place the loader in the correct place of the webpack config.
const txtLoader = {
test: /\.txt$/i,
use: 'raw-loader',
};
addAfterLoader(webpackConfig, loaderByName('source-map-loader'), txtLoader);
Have anyone found a fix for this? I have same issue just with ejs-loader instead of html-loader.
Have anyone found a fix for this? I have same issue just with ejs-loader instead of html-loader.
I just inspected the stricture of my existing loader rules via console.dir and inserted the new loader manually in the right place. This is a temporary fix and it might be broken if you change the version of create-react-app or other packages.
This is the corresponding fragment of my config:
(ofc you shouldn't remove resolve-url-loader, this is for my project)
configure: (webpackConfig) => {
const htmlLoader = {
test: /\.html$/,
loader: require.resolve('html-loader'),
exclude: [/node_modules/, /public/],
options: { minimize: true, sources: false },
};
// FIXME AFTER THE ISSUE IS FIXED
// https://github.com/dilanx/craco/issues/486
(webpackConfig.module.rules[0] as any).oneOf.splice(0, 0, htmlLoader);
removeLoaders(webpackConfig, loaderByName('resolve-url-loader'));
return webpackConfig;
}
I could fix this issue by adding the loader before another loader instead of file-loader|raw-loader
like babel-loader
. It seems that issue is adding before or after file-loader
and raw-loader
but adding before/after babel-loader
working well.
configure: (webpackConfig) => {
webpackConfig.resolve.extensions.push('.graphql', '.gql');
const graphqlLoader = {
test: /\.(graphql|gql)$/,
exclude: /node_modules/,
loader: require.resolve('graphql-tag/loader'),
}
addBeforeLoader(webpackConfig, loaderByName('babel-loader'), graphqlLoader);
return webpackConfig;
}
@dotamir your solution works for men thank you!
@dotamir Thank you! It works!