vuetifyjs / vuetify-loader

📦 Webpack and Vite plugins for treeshaking Vuetify components and more
https://vuetifyjs.com/customization/a-la-carte#vuetify-loader
MIT License
517 stars 91 forks source link

'installComponents' has already been declared #20

Closed JeremyWalters closed 6 years ago

JeremyWalters commented 6 years ago

Hi, I am running a Vue/typescript/vuetify(a la carte) project. Upgraded to version 1.3.1. Added the vuetify-loader plugin to vue.config.js

"vue": "^2.5.17" "vuetify-loader": "^1.0.5" "vue-cli-plugin-vuetify": "^0.3.0" "vuetify": "^1.3.1"

Error:

Module parse failed: Identifier 'installComponents' has already been declared (53:7)
You may need an appropriate loader to handle this file type.
|
| /* vuetify-loader */
> import installComponents from "!../../../node_modules/vuetify-loader/lib/runtime/installComponents.js"
| import { VBtn } from 'vuetify/lib'
| import { VCard } from 'vuetify/lib'
KaelWD commented 6 years ago

If you're using vue-cli-plugin-vuetify you don't need to modify the webpack config manually. That error means the loader is being run twice.

amritk commented 6 years ago

@KaelWD how do you then set the options for it? Like a custom match function?

KaelWD commented 6 years ago

@johnleider

amritk commented 6 years ago

I tried something like this, but options is undefined:

module.exports = {
    chainWebpack: config => {
        config.module
            .rule('vue')
            .use('vuetify-loader')
            .loader('vuetify-loader')
            .tap(options => {
                console.log(options); // undefined
                return options
            })
    }
}
johnleider commented 6 years ago

Should be

chainWebpack: config => {
    config
      .plugin('vuetify-loader')
      .tap(args => {

      })
  }
amritk commented 6 years ago

@johnleider it seems the args are an empty array and it gives me an error.

module.exports = {
    chainWebpack: config => {
        config
            .plugin('vuetify-loader')
            .tap(args => {
                console.log(args); // []
                return args
            })
    }
}

produces:

➜  league-admin git:(master) ✗ yarn serve
yarn run v1.10.1
$ vue-cli-service serve
 INFO  Starting development server...
[]
 ERROR  TypeError: Cannot read property '__expression' of undefined
TypeError: Cannot read property '__expression' of undefined
    at Object.toConfig (/home/amritk/apps/league-admin/node_modules/webpack-chain/src/Plugin.js:55:38)
    at clean.Object.assign.plugins.plugins.values.map.plugin (/home/amritk/apps/league-admin/node_modules/webpack-chain/src/Config.js:129:61)
    at Array.map (<anonymous>)
    at module.exports.toConfig (/home/amritk/apps/league-admin/node_modules/webpack-chain/src/Config.js:129:40)
    at Service.resolveWebpackConfig (/home/amritk/apps/league-admin/node_modules/@vue/cli-service/lib/Service.js:218:34)
    at PluginAPI.resolveWebpackConfig (/home/amritk/apps/league-admin/node_modules/@vue/cli-service/lib/PluginAPI.js:115:25)
    at serve (/home/amritk/apps/league-admin/node_modules/@vue/cli-service/lib/commands/serve.js:47:31)
    at Service.run (/home/amritk/apps/league-admin/node_modules/@vue/cli-service/lib/Service.js:203:12)
    at Object.<anonymous> (/home/amritk/apps/league-admin/node_modules/@vue/cli-service/bin/vue-cli-service.js:36:9)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at startup (internal/bootstrap/node.js:266:19)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
johnleider commented 6 years ago

Here is the relevant documentation: https://cli.vuejs.org/guide/webpack.html#modifying-options-of-a-plugin

We do not define any args so the empty array seems correct: https://github.com/vuetifyjs/vue-cli-plugin-vuetify/blob/dev/index.js#L18

amritk commented 6 years ago

This is still blowing up with that same error:

module.exports = {
    chainWebpack: config => {
        config
            .plugin('vuetify-loader')
            .tap(args => {
                return [{
                    match (originalTag, { kebabTag, camelTag, path, component }) {
                        if (components.indexOf(kebabTag) > -1) {
                            return [camelTag, `import ${camelTag} from '@/components/${kebabTag}.vue'`]
                        }
                    }
                }]
            })
    }
}

I will play around with it some more tomorrow in case I am missing something.

KaelWD commented 6 years ago

@johnleider I think we need to use chainWebpack instead of configureWebpack, so it can have an identfier.

amritk commented 6 years ago

still was unable to get this working, it seems it keeps trying to call __expression' of undefined

johnleider commented 6 years ago

I'm going to update this tonight and ensure it is easily extensible. Thank you for your patience.

amritk commented 6 years ago

Looks like it works correctly with this pull request https://github.com/vuetifyjs/vue-cli-plugin-vuetify/pull/51 and the following code:

module.exports = {
    chainWebpack: config => {
        config
            .plugin('VuetifyLoaderPlugin')
            .tap(args => {
                return [{
                    match (originalTag, { kebabTag, camelTag, path, component }) {
                        if (components.indexOf(kebabTag) > -1) {
                            return [camelTag, `import ${camelTag} from '@/components/${kebabTag}.vue'`]
                        }
                    }
                }]
            })
    }
}

The plugin needs to be called by VuetifyLoaderPlugin

chriscdn commented 6 years ago

If you're using vue-cli-plugin-vuetify you don't need to modify the webpack config manually. That error means the loader is being run twice.

Thanks, this helped. It might be worth adding it to the documentation at https://vuetifyjs.com/en/guides/a-la-carte.

KaelWD commented 6 years ago

Yeah I still need to add config to the plugin.

John released it right after I updated the loader.

chriscdn commented 6 years ago

A follow up to this: When using vue-cli-plugin-vuetify do we still use import Vuetify from 'vuetify' or import Vuetify from 'vuetify/lib' ? I'm trying to understand if vue-cli-plugin-vuetify supersedes everything in the configuration on that page.

KaelWD commented 6 years ago

Still lib, vue-cli-plugin-vuetify just adds new VuetifyLoaderPlugin() if you have vuetify-loader installed.

chriscdn commented 6 years ago

Still lib, vue-cli-plugin-vuetify just adds new VuetifyLoaderPlugin() if you have vuetify-loader installed.

Thanks - much appreciated.

NevenD commented 5 years ago

I have rather odd situation regarding vuetify and vuetify loader plugin.

I posted problem on stackoverflow and Vue forum but without any luck so far. I've created simple SPA with implemented Vue and Vuetify and while in dev mode everything works fine I'm having problem in production mode. I'm getting rather strange error regarding my components

Uncaught TypeError: T(...)(...) is not a function
at Module.56d7 (VectorFeatures.vue:37)
at r (bootstrap:78)
at Object.0 (bootstrap:151)
at r (bootstrap:78)
at i (bootstrap:45)
at bootstrap:151
at bootstrap:151

Further inspecting error I'm getting this :

InkedScreenshot_1_LI

My vue.config.js is this:

module.exports = {
    publicPath: process.env.NODE_ENV === 'production'
        ? '/hr-map/'
        : '/vue-map/',
    chainWebpack: config => {
        config.module
            .rule('vue')
            .use('vue-loader')
            .loader('vue-loader')
            .tap(options => {
                // modify the options...
                return options
            })
    }
}

And my router is this:

import Vue from 'vue'
import Router from 'vue-router'
import Dashboard from '@/views/Dashboard.vue'
import Croatia from '@/views/CroatiaMap.vue'
import Poland from '@/views/PolandMap.vue'

Vue.use(Router)

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'dashboard',
      component: Dashboard
    },
    {
      path: '/croatia',
      name: 'croatia',
      component: Croatia,
      meta: { keepAlive: true }
    },
    {
      path: '/poland',
      name: 'poland',
      component: Poland,
      meta: { keepAlive: true }
    }
  ]
})

Also worth mentioning is when I comment out lets say poland or croatia everything works fine on production

ClayShentrup commented 5 years ago

Looks like it works correctly with this pull request vuetifyjs/vue-cli-plugin-vuetify#51 and the following code:

So this was awesome and worked for me. But any idea how to incorporate this in my Jest specs? E.g.

    config
      .plugin('VuetifyLoaderPlugin')
      .tap(args => [{
        match(originalTag, {
          kebabTag, camelTag, path, component,
        }) {
          if (!camelTag.startsWith('Strata')) { return []; }
          return [camelTag, `import ${camelTag} from '@/components/${camelTag}.vue'`];
        },
      }]);
Ruchirr commented 4 years ago

Please remove buildModules inside nuxt.config.js, this is for those who are using Nuxt.js

{
  buildModules: [
    // Simple usage
    '@nuxtjs/vuetify',

    // With options
    ['@nuxtjs/vuetify', { /* module options */ }]
  ]
}

Add modules this one is for latest version

modules: [
    '@nuxtjs/vuetify',
  ],
vuetify: {
//what ever options you may like
  },
jeanpaul1304 commented 4 years ago

Thank you @Ruchirr, it works, don't forget remove theses lines if you was trying another solutions...


build:  {
    parallel: true,
    plugins: [
      new VuetifyLoaderPlugin(), // remove this
    ],
    transpile: [/^vuetify/] // remove this
  }