[VueLoaderPlugin Error] No matching rule for .vue files found - when files have different extension than .vue
roysanchez opened this issue ยท 17 comments
Version
15.0.0-rc.1
Reproduction link
N/A
Steps to reproduce
const path = require('path');
const webpack = require('webpack');
const { VueLoaderPlugin } = require('vue-loader')
module.exports = (env) => {
const isDevBuild = !(env && env.prod);
return [{
stats: { modules: false },
context: __dirname,
resolve: { extensions: [ '.js', '.ts' ] },
entry: { 'main': './ClientApp/boot.ts' },
module: {
rules: [
{ test: /\.vue\.html$/, loader: 'vue-loader' }, //Change this line to { test: /\.vue/, loader: 'vue-loader' } to make it work
{ test: /\.ts$/, use: 'ts-loader?silent=true' }
]
},
output: {
path: path.join(__dirname, './wwwroot/dist'),
filename: '[name].js',
publicPath: 'dist/'
},
plugins: [
new VueLoaderPlugin()
]
}];
};
What is expected?
The bundle is successful
What is actually happening?
Webpack throws the following error:
[VueLoaderPlugin Error] No matching rule for .vue files found.
Make sure there is at least one root-level rule that matches .vue files.
Why are you using .vue.html
extension instead of just .vue
?
Well, Vue SFCs are not technically HTML. The recommended approach is using the proper .vue
extension and VSCode (which has excellent SFC support via the Vetur extension) instead Visual Studio.
If you really want to stick with vue.html
, you can workaround this by having both rules:
rules: [
{ test: /\.vue$/, loader: 'vue-loader' },
{ test: /\.vue\.html$/, loader: 'vue-loader' }
]
Thanks that worked even thought it looks like a hack ๐
as I don't have any .vue
files in the project
@roysanchez I added a special case for .vue.html
. Will work without the extra rule in the next release.
@yyx990803 I have a similar issue. My .vue
files have become .pug
instead. Is there any chance we can have a configurable option instead of just handling special cases?
Why not just add an optional regex to the current instruction?
rules: [
{ test: /.vue(.html)?$/, loader: 'vue-loader' },
]
@Flamenco the loader was working only when there was a rule for .vue
specifically, hence the need to have multiple rules. I don't know if this is still the case.
Hi, I encountered the same error. The plugin is too restrictive in checking the rules. This is what I have:
// We need to fool the VueLoaderPlugin, as that checks if a rule is available
// for vue components, but it can't see our more restricted one....
// It even checks the name of the loader, so aliasing also doesn't work.
{
test: /\.vue$/,
include: path.resolve(__dirname),
loader: 'vue-loader',
},
{
test: /\.vue$/,
include: options.sourceDirectory,
issuer: /\.docs\.md$/,
use: [
{ loader: 'fb-inject-vue-loader' },
{ loader: 'fb-vue-loader' },
],
},
This comes from a package we make that is to be used with other packages, so we do aliasing to be sure that the others can use different versions of loaders etc...
้ฝๆฏๅคง็ฅ
I fund the cause of this issue in /node_modules/vue-loader/lib/plugin.js
there is this checking point vueLoaderUseIndex < 0
under const vueUse = vueRule.use
I make this following changes
let ListIndex = [];
const vueLoaderUseIndex = vueUse.findIndex(u => {
console.log(u)
let vueChecker = /^vue-loader|(\/|\\|@)vue-loader/.test(u.loader)
console.log({u:u.loader})
ListIndex[u.loader] = vueChecker
return vueChecker
})
console.log({ListIndex:ListIndex['vue-loader']})
in my terminal I have this
{ ListIndex: [ 'vue-loader': true ] }
{ ListIndex: [ 'html-loader': false ] }
this show to rules are been fire when I npm run dev
and this html-loader
is not defined in my web pack config file so vueLoaderUseIndex < 0
stop the processing since 'html-loader': false
am currently working on the solution or if there is fast fix for this please share
am able to bypass the error by doing this but I dont know if it right thing to do
const vueLoaderUseIndex = vueUse.findIndex(u => {
let vueChecker = /^vue-loader|(\/|\\|@)vue-loader/.test(u.loader)
|| /^babel-loader|(\/|\\|@)babel-loader/.test(u.loader)
|| /^html-loader|(\/|\\|@)html-loader/.test(u.loader)
|| /^file-loader|(\/|\\|@)file-loader/.test(u.loader)
|| /^img-loader|(\/|\\|@)img-loader/.test(u.loader)
return vueChecker
})
I do not believe this is fixed. I see the same behavior as @diadal in that the array of rules is processed as 1 item arrays one at a time, so always fails on the non-vue rules. So some guidance on usage is desired if that is expected as it implies no other rules can be used in presence of Vue Plugin.
I wonder though if this is only in the context of storybook loading of the webpack config incorrectly. Will investigate
I just encountered the same error on vue-loader 15.8.3
. While inspecting the source for my webpack version at plugin-webpack4.js
vue-loader/lib/plugin-webpack4.js
Line 32 in 21293bd
I came to the conclusion that the matcher created for
foo.vue
allows a rule for html-loader
to pass the test for some reasons I don't know. I was able to get it work by replace the line55 of the piece of code below with @diadal's comment #1238 (comment)vue-loader/lib/plugin-webpack4.js
Lines 54 to 56 in 21293bd
But I don't think this can be a decent solution to this issue.
actually to me npm update corrected the error
also to me just npm update
For me the fix was to move the rule in my config to the top of the array of rules. Can't tell you why, but it did the trick!
- Webpack v5.52.0
- webpack-dev-server 4.1.0
- yarn v11.22.11
In my webpack.common.js
:
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
entry: {
main : "./src/main.js",
vendor: "./src/vendor.js",
},
module: {
rules: [
// Moved this to the top of all rules
{
test : /\.vue$/,
loader: "vue-loader",
},
{
test: /\.html$/,
use : ["html-loader"],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
}
},
{
test: /\.(svg|png|jpe?g|gif)$/,
use : {
loader : "file-loader",
options: {
name : "[name].[contentHash:8].[ext]",
outputPath: "assets/img",
esModule : false,
},
},
},
],
},
plugins: [
new VueLoaderPlugin(),
],
}
And my webpack.dev.js
(just for reference since i'm using configs for different enviornments):
const autoprefixer = require("autoprefixer")
const common = require("./webpack.common")
const { merge } = require("webpack-merge")
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = merge(common, {
mode : "development",
devtool: "source-map",
output: {
filename: "[name].bundle.js",
path : path.resolve(__dirname, "dist", "index.html"),
},
module: {
rules: [
{
test: /\.scss$/,
use : [
"style-loader",
"css-loader",
{
loader: "postcss-loader",
options: {
plugins: () => [autoprefixer()],
},
},
"sass-loader",
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/template.html"
}),
],
})