编译报错 [VueLoaderPlugin Error] vue-loader 15 目前不支持带有oneOf的vue规则

Posted

技术标签:

【中文标题】编译报错 [VueLoaderPlugin Error] vue-loader 15 目前不支持带有oneOf的vue规则【英文标题】:Compile error [VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf 【发布时间】:2020-11-18 19:00:57 【问题描述】:

我从 Gitlab 下载了项目(Laravel 和 vue.js),在我安装了依赖项(npm install & composer install)之后, 我无法编译它,当我尝试输入:npm run watch 时,出现以下错误:

注意:我删除了 package-lock.json 因为没有删除它我得到了错误:

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

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()]
       )
       ;

如果我在下面的代码注释,npm run watch 可以编译项目。

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

日志文件:

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 npm@6.14.7
3 info using node@v12.18.3
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

运行 npm install 成功,我也通过 composer update 更新作曲家。

插件-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

请帮帮我..

【问题讨论】:

我尝试编辑您的问题以更正您的代码格式,但我做不到,因为您几乎没有写任何关于您的问题的内容,而且问题几乎完全是代码。您能否详细说明问题所在并正确格式化您的代码? 对不起亲爱的,请立即查看@Paze 【参考方案1】:

我今天遇到了同样的问题,虽然我不知道为什么会发生或者解决它的正确方法是什么,但我注意到这个错误只在最新版本的 vuetify-loader 中抛出,所以基本上试试使用旧版本(1.4.3 对我来说很好)。 npm i vuetify-loader@1.4.3

【讨论】:

我在运行npm audit fix --force 以消除一些漏洞警告后遇到了这个问题。虽然此修复意味着我的网站将建立,但它并没有摆脱那些警告......【参考方案2】:

使用 Laravel 8 进行 VUETIFY 并解决了这个问题。

// 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));

// webpack.config.js
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin');
module.exports = 
    plugins: [
        new VuetifyLoaderPlugin(),
    ]
;

【讨论】:

【参考方案3】:

根据这篇文章:Newer versions of vuetify-loader in Laravel。 不要把它放在 webpack.mix.js 的插件中 你应该:

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

显然这与laravel-mix 有关。它使用它自己的vue-loader 与来自vuetify-loader 的那个冲突。通过这种方式,您可以在 laravel-mix 完成之后使用 vuetify-loader,这很神奇。

通过这种方式,您可以使用较新版本的vuetify-loader。 (我正在使用 1.7.2 并且可以正常工作)

【讨论】:

以上是关于编译报错 [VueLoaderPlugin Error] vue-loader 15 目前不支持带有oneOf的vue规则的主要内容,如果未能解决你的问题,请参考以下文章

nvm下cnpm报错,npm ERR! code ENOTEMPTY npm ERR! syscall rmdir,npm ERR! npm ERR! errno -4051 npm ERR!

vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your w

mysql编译安装完启动时候报错

redis编译3.0.5报错,哪位哥们见过看一下

安装@vue/cli报错,npm ERR! gyp ERR! not ok

npm install 报错:ERR! code EINTEGRITY 解决方案