Compile error [VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf

10,257

Solution 1

I ran into the same issue today, and although I can't tell why it happens or what's the proper way to solve it, I notice that the error is only thrown in the latest version of vuetify-loader, so basically try with an older version (1.4.3 worked fine for me). npm i [email protected]

Solution 2

As per this post: Newer versions of vuetify-loader in Laravel. Instead of putting it in the plugins of the webpack.mix.js you should:

mix.extend('vuetify', new class {
    webpackConfig (config) {
        config.plugins.push(new VuetifyLoaderPlugin())
    }
})
mix.vuetify()

Apparently this has to do with laravel-mix. It uses it's own vue-loader conflicting with the one from vuetify-loader. In this way you use the vuetify-loader after laravel-mix has done it's magic.

In this way you can use newer versions of the vuetify-loader. (Am using 1.7.2 and it works)

Share:
10,257
Alaa
Author by

Alaa

Updated on July 21, 2022

Comments

  • Alaa
    Alaa almost 2 years

    I have project (Laravel with vue.js)downloaded from Gitlab and after i installed the dependencies (npm install & composer install), i can not compile it,as when i try typing: npm run watch, i got below error:

    Note:i deleted package-lock.json because without deleted it i got error in:

    npm install
    
    K:\pharma\node_modules\webpack-cli\bin\cli.js:281
                                    throw err;
                                    ^
    
    Error: [VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf.
        at VueLoaderPlugin.apply (K:\pharma\node_modules\vue-loader\lib\plugin-webpack4.js:46:13)
        at webpack (K:\pharma\node_modules\webpack\lib\webpack.js:51:13)
        at processOptions (K:\pharma\node_modules\webpack-cli\bin\cli.js:272:16)
        at K:\pharma\node_modules\webpack-cli\bin\cli.js:364:3
        at Object.parse (K:\pharma\node_modules\webpack-cli\node_modules\yargs\yargs.js:576:18)
        at K:\pharma\node_modules\webpack-cli\bin\cli.js:49:8
        at Object.<anonymous> (K:\pharma\node_modules\webpack-cli\bin\cli.js:366:3)
        at Module._compile (internal/modules/cjs/loader.js:1137:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
        at Module.load (internal/modules/cjs/loader.js:985:32)
        at Function.Module._load (internal/modules/cjs/loader.js:878:14)
        at Module.require (internal/modules/cjs/loader.js:1025:19)
        at require (internal/modules/cjs/helpers.js:72:18)
        at Object.<anonymous> (K:\pharma\node_modules\webpack\bin\webpack.js:156:2)
        at Module._compile (internal/modules/cjs/loader.js:1137:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
        at Module.load (internal/modules/cjs/loader.js:985:32)
        at Function.Module._load (internal/modules/cjs/loader.js:878:14)
        at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
        at internal/main/run_main_module.js:17:47
    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! @ development: `cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js`
    npm ERR! Exit status 1
    npm ERR! 
    npm ERR! Failed at the @ development script.
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     C:\Users\Alaa\AppData\Roaming\npm-cache\_logs\2020-07-29T08_00_19_753Z-debug.log
    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! @ dev: `npm run development`
    npm ERR! Exit status 1
    npm ERR!
    npm ERR! Failed at the @ dev script.
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     C:\Users\Alaa\AppData\Roaming\npm-cache\_logs\2020-07-29T08_00_20_214Z-debug.log
    

    the webpacj.mix.js:

    const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')    
        mix.js('resources/js/app.js', 'public/js')
           .sass('resources/sass/app.scss', 'public/css')
           .disableNotifications()
           .webpackConfig({
              plugins: [new VuetifyLoaderPlugin()]
           })
           ;
    

    if i comment below codes,the npm run watch can compile the project.

     .webpackConfig({
          plugins: [new VuetifyLoaderPlugin()]
       })
    

    package.json:

    {
        "private": true,
        "scripts": {
            "dev": "npm run development",
            "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
            "watch": "npm run development -- --watch",
            "watch-poll": "npm run watch -- --watch-poll",
            "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
            "prod": "npm run production",
            "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
        },
        "devDependencies": {
            "axios": "^0.19",
            "cross-env": "^7.0.2",
            "laravel-mix": "^5.0.1",
            "lodash": "^4.17.13",
            "resolve-url-loader": "^2.3.1",
            "sass": "^1.20.1",
            "sass-loader": "^8.0.0",
            "vue": "^2.5.17",
            "vue-template-compiler": "^2.6.10",
            "vuetify-loader": "^1.6.0",
            "webpack-dev-server": "^3.11.0"
        },
        "dependencies": {
            "@mdi/font": "^5.0.45",
            "@mdi/js": "^5.0.45",
            "ckeditor4-vue": "^1.0.0",
            "laravel-mix-bundle-analyzer": "^1.0.5",
            "moment": "^2.26.0",
            "promise": "^8.1.0",
            "qs": "^6.9.4",
            "vue-i18n": "^8.18.1",
            "vue-mq": "^1.0.1",
            "vue-notification": "^1.3.20",
            "vue-router": "^3.1.6",
            "vuelidate": "^0.7.5",
            "vuetify": "^2.3.6",
            "vuex": "^3.3.0",
            "xlsx": "^0.16.0"
        }
    }
    

    log file:

    0 info it worked if it ends with ok
    1 verbose cli [
    1 verbose cli   'C:\\Program Files\\nodejs\\node.exe',
    1 verbose cli   'C:\\Users\\Alaa\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js',
    1 verbose cli   'run',
    1 verbose cli   'dev'
    1 verbose cli ]
    2 info using [email protected]
    3 info using [email protected]
    4 verbose run-script [ 'predev', 'dev', 'postdev' ]
    5 info lifecycle @~predev: @
    6 info lifecycle @~dev: @
    7 verbose lifecycle @~dev: unsafe-perm in lifecycle true
    8 verbose lifecycle @~dev: PATH: C:\Users\Alaa\AppData\Roaming\npm\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin;K:\pharma\node_modules\.bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\xampp\php;C:\composer;C:\Program Files\dotnet\;C:\Program Files\Microsoft DNX\Dnvm\;C:\Program Files\Git\cmd;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\ProgramData\chocolatey\bin;C:\Program Files (x86)\Yarn\bin\;C:\Program Files\nodejs\;C:\xampp\php;C:\Users\Alaa\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\Alaa\AppData\Roaming\Composer\vendor\bin;C:\xampp\php;C:\Program Files\nodejs;C:\Users\Alaa\.dotnet\tools;C:\Users\Alaa\AppData\Local\Yarn\bin;C:\Users\Alaa\AppData\Roaming\npm
    9 verbose lifecycle @~dev: CWD: K:\pharma
    10 silly lifecycle @~dev: Args: [ '/d /s /c', 'npm run development' ]
    11 silly lifecycle @~dev: Returned: code: 1  signal: null
    12 info lifecycle @~dev: Failed to exec dev script
    13 verbose stack Error: @ dev: `npm run development`
    13 verbose stack Exit status 1
    13 verbose stack     at EventEmitter.<anonymous> (C:\Users\Alaa\AppData\Roaming\npm\node_modules\npm\node_modules\npm-lifecycle\index.js:332:16)
    13 verbose stack     at EventEmitter.emit (events.js:315:20)
    13 verbose stack     at ChildProcess.<anonymous> (C:\Users\Alaa\AppData\Roaming\npm\node_modules\npm\node_modules\npm-lifecycle\lib\spawn.js:55:14)
    13 verbose stack     at ChildProcess.emit (events.js:315:20)
    13 verbose stack     at maybeClose (internal/child_process.js:1021:16)
    13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
    14 verbose pkgid @
    15 verbose cwd K:\pharma
    16 verbose Windows_NT 10.0.18362
    17 verbose argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\Alaa\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "run" "dev"
    18 verbose node v12.18.3
    19 verbose npm  v6.14.7
    20 error code ELIFECYCLE
    21 error errno 1
    22 error @ dev: `npm run development`
    22 error Exit status 1
    23 error Failed at the @ dev script.
    23 error This is probably not a problem with npm. There is likely additional logging output above.
    24 verbose exit [ 1, true ]
    

    vuetify-loader/lib/plugin.js:

    const RuleSet = require('webpack/lib/RuleSet')
    const progressiveLoaderModule = require('../progressive-loader/module')
    let vueLoaderPath
    try {
      vueLoaderPath = require.resolve('vue-loader')
    } catch (err) {}
    
    function isVueLoader (use) {
      return use.ident === 'vue-loader-options' ||
        use.loader === 'vue-loader' ||
        (vueLoaderPath && use.loader === vueLoaderPath)
    }
    
    class VuetifyLoaderPlugin {
      constructor (options) {
        this.options = options || {}
      }
    
      apply (compiler) {
        // use webpack's RuleSet utility to normalize user rules
        const rawRules = compiler.options.module.rules
        const { rules } = new RuleSet(rawRules)
        this.rules = rules
    
        // find the rules that apply to vue files
        const vueRules = rules.filter(rule => rule.use && rule.use.find(isVueLoader))
    
        if (!vueRules.length) {
          throw new Error(
            `[VuetifyLoaderPlugin Error] No matching rule for vue-loader found.\n` +
            `Make sure there is at least one root-level rule that uses vue-loader.`
          )
        }
    
        vueRules.forEach(this.updateRule.bind(this))
    
        compiler.options.module.rules = rules
      }
    
      updateRule (rule) {
        if (this.options.progressiveImages) {
          const vueLoaderOptions = rule.use.find(isVueLoader).options
          vueLoaderOptions.compilerOptions = vueLoaderOptions.compilerOptions || {}
          vueLoaderOptions.compilerOptions.modules = vueLoaderOptions.compilerOptions.modules || []
          vueLoaderOptions.compilerOptions.modules.push(progressiveLoaderModule)
    
          const imageRuleIndex = this.rules.findIndex(rule => {
            return rule.resource &&
              !rule.resourceQuery &&
              ['.png', '.jpg', '.jpeg', '.gif'].some(ext => rule.resource(ext))
          })
          let imageRule = this.rules[imageRuleIndex]
    
          const options = typeof this.options.progressiveImages === 'boolean'
            ? undefined
            : this.options.progressiveImages
    
          if (!imageRule) {
            imageRule = {
              test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)(\?.*)?$/,
              oneOf: [
                {
                  test: /\.(png|jpe?g|gif)$/,
                  resourceQuery: options ? options.resourceQuery : /vuetify-preload/,
                  use: [
                    {
                      loader: 'vuetify-loader/progressive-loader',
                      options
                    },
                    {
                      loader: 'url-loader',
                      options: { limit: 8000 }
                    }
                  ]
                },
                {
                  loader: 'url-loader',
                  options: { limit: 8000 }
                }
              ]
            }
            rules.push(imageRule)
          } else {
            if (Array.isArray(imageRule.use)) {
              imageRule.oneOf = [
                {
                  test: /\.(png|jpe?g|gif)$/,
                  resourceQuery: options ? options.resourceQuery : /vuetify-preload/,
                  use: [
                    {
                      loader: 'vuetify-loader/progressive-loader',
                      options
                    },
                    ...imageRule.use
                  ]
                },
                ...imageRule.use
              ]
            } else if (imageRule.loader) {
              imageRule.oneOf = [
                {
                  test: /\.(png|jpe?g|gif)$/,
                  resourceQuery: options ? options.resourceQuery : /vuetify-preload/,
                  use: [
                    {
                      loader: 'vuetify-loader/progressive-loader',
                      options
                    },
                    {
                      loader: imageRule.loader,
                      options: imageRule.options
                    }
                  ]
                },
                {
                  loader: imageRule.loader,
                  options: imageRule.options
                }
              ]
            }
            delete imageRule.use
            delete imageRule.loader
            delete imageRule.options
          }
        }
    
        rule.oneOf = [
          {
            resourceQuery: '?',
            use: rule.use
          },
          {
            use: [
              {
                loader: require.resolve('./loader'),
                options: {
                  match: this.options.match || [],
                  attrsMatch: this.options.attrsMatch || []
                }
              },
              ...rule.use
            ]
          },
        ]
        delete rule.use
      }
    }
    
    module.exports = VuetifyLoaderPlugin
    

    running npm install was successfully, also i update the composer by composer update.

    plugin-webpack4.js:

    const qs = require('querystring')
    const RuleSet = require('webpack/lib/RuleSet')
    
    const id = 'vue-loader-plugin'
    const NS = 'vue-loader'
    
    class VueLoaderPlugin {
      apply (compiler) {
        // add NS marker so that the loader can detect and report missing plugin
        if (compiler.hooks) {
          // webpack 4
          compiler.hooks.compilation.tap(id, compilation => {
            const normalModuleLoader = compilation.hooks.normalModuleLoader
            normalModuleLoader.tap(id, loaderContext => {
              loaderContext[NS] = true
            })
          })
        } else {
          // webpack < 4
          compiler.plugin('compilation', compilation => {
            compilation.plugin('normal-module-loader', loaderContext => {
              loaderContext[NS] = true
            })
          })
        }
    
        // use webpack's RuleSet utility to normalize user rules
        const rawRules = compiler.options.module.rules
        const { rules } = new RuleSet(rawRules)
    
        // find the rule that applies to vue files
        let vueRuleIndex = rawRules.findIndex(createMatcher(`foo.vue`))
        if (vueRuleIndex < 0) {
          vueRuleIndex = rawRules.findIndex(createMatcher(`foo.vue.html`))
        }
        const vueRule = rules[vueRuleIndex]
    
        if (!vueRule) {
          throw new Error(
            `[VueLoaderPlugin Error] No matching rule for .vue files found.\n` +
            `Make sure there is at least one root-level rule that matches .vue or .vue.html files.`
          )
        }
    
        if (vueRule.oneOf) {
          throw new Error(
            `[VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf.`
          )
        }
    
        // get the normlized "use" for vue files
        const vueUse = vueRule.use
        // get vue-loader options
        const vueLoaderUseIndex = vueUse.findIndex(u => {
          return /^vue-loader|(\/|\\|@)vue-loader/.test(u.loader)
        })
    
        if (vueLoaderUseIndex < 0) {
          throw new Error(
            `[VueLoaderPlugin Error] No matching use for vue-loader is found.\n` +
            `Make sure the rule matching .vue files include vue-loader in its use.`
          )
        }
    
        // make sure vue-loader options has a known ident so that we can share
        // options by reference in the template-loader by using a ref query like
        // template-loader??vue-loader-options
        const vueLoaderUse = vueUse[vueLoaderUseIndex]
        vueLoaderUse.ident = 'vue-loader-options'
        vueLoaderUse.options = vueLoaderUse.options || {}
    
        // for each user rule (expect the vue rule), create a cloned rule
        // that targets the corresponding language blocks in *.vue files.
        const clonedRules = rules
          .filter(r => r !== vueRule)
          .map(cloneRule)
    
        // global pitcher (responsible for injecting template compiler loader & CSS
        // post loader)
        const pitcher = {
          loader: require.resolve('./loaders/pitcher'),
          resourceQuery: query => {
            const parsed = qs.parse(query.slice(1))
            return parsed.vue != null
          },
          options: {
            cacheDirectory: vueLoaderUse.options.cacheDirectory,
            cacheIdentifier: vueLoaderUse.options.cacheIdentifier
          }
        }
    
        // replace original rules
        compiler.options.module.rules = [
          pitcher,
          ...clonedRules,
          ...rules
        ]
      }
    }
    
    function createMatcher (fakeFile) {
      return (rule, i) => {
        // #1201 we need to skip the `include` check when locating the vue rule
        const clone = Object.assign({}, rule)
        delete clone.include
        const normalized = RuleSet.normalizeRule(clone, {}, '')
        return (
          !rule.enforce &&
          normalized.resource &&
          normalized.resource(fakeFile)
        )
      }
    }
    
    function cloneRule (rule) {
      const { resource, resourceQuery } = rule
      // Assuming `test` and `resourceQuery` tests are executed in series and
      // synchronously (which is true based on RuleSet's implementation), we can
      // save the current resource being matched from `test` so that we can access
      // it in `resourceQuery`. This ensures when we use the normalized rule's
      // resource check, include/exclude are matched correctly.
      let currentResource
      const res = Object.assign({}, rule, {
        resource: {
          test: resource => {
            currentResource = resource
            return true
          }
        },
        resourceQuery: query => {
          const parsed = qs.parse(query.slice(1))
          if (parsed.vue == null) {
            return false
          }
          if (resource && parsed.lang == null) {
            return false
          }
          const fakeResourcePath = `${currentResource}.${parsed.lang}`
          if (resource && !resource(fakeResourcePath)) {
            return false
          }
          if (resourceQuery && !resourceQuery(query)) {
            return false
          }
          return true
        }
      })
    
      if (rule.rules) {
        res.rules = rule.rules.map(cloneRule)
      }
    
      if (rule.oneOf) {
        res.oneOf = rule.oneOf.map(cloneRule)
      }
    
      return res
    }
    
    VueLoaderPlugin.NS = NS
    module.exports = VueLoaderPlugin
    
     npm -v
    6.14.7
    node -v
    v12.18.3
    

    Please help me..

  • Charlie
    Charlie over 3 years
    I came across this issue after running npm audit fix --force to get rid of some vulnerability warnings. Whilst this fix means my site will build, it does not get rid of those warnings...