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

3

7

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..

Riser answered 29/7, 2020 at 8:21 Comment(2)
I tried editing your question to correct formatting of your code, but I couldn't as you write almost nothing about your problem and the question is almost entirely code. Can you specify a bit more what the issue is and format your code correctly?Shu
sorry dear,please check now @ShuRiser
P
16

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]

Perennate answered 2/8, 2020 at 5:2 Comment(1)
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...Boschbok
A
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)

Accompanist answered 18/7, 2021 at 13:47 Comment(0)
B
0

VUETIFY with Laravel 8 & resolved this.

// pakage.json

"devDependencies": {
        "@babel/preset-env": "^7.11.0",
        "@mdi/font": "^5.9.55",
        "axios": "^0.21",
        "babel-plugin-transform-object-rest-spread": "^6.26.0",
        "babel-polyfill": "^6.26",
        "browser-sync": "^2.26.12",
        "browser-sync-webpack-plugin": "2.0.1",
        "cross-env": "^7.0.3",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "resolve-url-loader": "^3.1.2",
        "sass": "^1.32.8",
        "sass-loader": "^11.0.1",
        "vue": "^2.6.12",
        "vue-loader": "^15.9.5",
        "vue-router": "^3.5.1",
        "vue-template-compiler": "^2.6.12",
        "vuetify-loader": "^1.7.2",
        "vuex": "^3.6.2",
        "webpack-dev-server": "^3.11.2"
    },
    "dependencies": {
        "vuetify": "^2.4.5"
    }
// webpack.mix.js

const mix = require('laravel-mix');
const webpack = require('./webpack.config');
const path = require('path');
mix.js('resources/js/app.js', 'public/js')
    .vue()
    .sass('resources/styles/app.sass', 'public/css')
    .webpackConfig(Object.assign(webpack));

and

// webpack.config.js
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin');
module.exports = {
    plugins: [
        new VuetifyLoaderPlugin(),
    ]
};
Boot answered 5/3, 2021 at 21:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.