Laravel Mix Vue 3 - Can't compile "TypeError: Cannot read property 'resolve' of undefined"

Viewed 1922

I'm trying to upgrade my Laravel 8 with Vue 2 to Vue 3. I changed all the packages in my package.json to support the new Vue 3 dependencies. I can't even compile a simple test app with Vue 3. The error i'm getting when I try to build isn't giving me much information.

Any one know how to fix this error when I try to "yarn watch"?

λ yarn watch
yarn run v1.22.5
$ mix watch
[webpack-cli] TypeError: Cannot read property 'resolve' of undefined
    at Alias.register (c:\wamp\www\Stipender\node_modules\laravel-mix-alias\index.js:8:37)
    at Object.components.<computed> [as alias] (c:\wamp\www\Stipender\node_modules\laravel-mix\src\components\ComponentRegistrar.js:133:53)
    at Object.<anonymous> (c:\wamp\www\Stipender\webpack.mix.js:15:5)
    at Module._compile (c:\wamp\www\Stipender\node_modules\v8-compile-cache\v8-compile-cache.js:192:30)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Module.load (node:internal/modules/cjs/loader:973:32)
    at Function.Module._load (node:internal/modules/cjs/loader:813:14)
    at Module.require (node:internal/modules/cjs/loader:997:19)
    at require (c:\wamp\www\Stipender\node_modules\v8-compile-cache\v8-compile-cache.js:159:20)
    at module.exports (c:\wamp\www\Stipender\node_modules\laravel-mix\setup\webpack.config.js:4:5)
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

package.json

{
    "private": true,
    "scripts": {
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "production": "mix --production"
    },
    "devDependencies": {
        "@babel/core": "^7.12.10",
        "@babel/helper-validator-option": "^7.12.11",
        "@babel/plugin-proposal-optional-chaining": "^7.12.7",
        "@babel/plugin-transform-runtime": "^7.12.10",
        "@babel/polyfill": "^7.11.5",
        "@babel/preset-env": "^7.12.11",
        "@fortawesome/fontawesome-pro": "^5.15.1",
        "@vue/cli-plugin-babel": "^4.5.10",
        "@vue/compiler-sfc": "^3.0.2",
        "babel-loader": "^8.2.2",
        "cross-env": "^7.0.3",
        "jquery": "^3.5.1",
        "laravel-mix": "^6.0.9",
        "lodash": "^4.17.20",
        "node-sass": "^5.0.0",
        "resolve-url-loader": "^3.1.2",
        "sass": "^1.32.2",
        "sass-loader": "^10.0",
        "vue-loader": "^16.1.2"
    },
    "dependencies": {
        "@vee-validate/rules": "^4.0.4",
        "admin-lte": "^3.0.5",
        "axios": "^0.21.1",
        "bootstrap": "^4.5.3",
        "chart.js": "^2.9.3",
        "dayjs": "^1.10.2",
        "laravel-mix-alias": "^1.0.2",
        "mitt": "^2.1.0",
        "moment": "^2.29.1",
        "owl.carousel": "^2.3.4",
        "popper.js": "^1.16.1",
        "primevue": "3.1.1",
        "simple-line-icons": "^2.5.5",
        "style-loader": "^2.0.0",
        "sweetalert2": "^10.13.0",
        "v-calendar": "^2.1.6",
        "vee-validate": "^4.0",
        "vue": "^3.0.5",
        "vue-recaptcha-v3": "^2.0.0",
        "vue-router": "^4.0.0-beta.13",
        "vue-slider-component": "^3.2.11",
        "vuex": "^4.0.0-rc.2",
        "wowjs": "^1.1.3"
    }
}

webpack.mix.js

const mix = require('laravel-mix');
require('laravel-mix-alias');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.alias({
    '@': '/node_modules',
    '~': '/node_modules',
})
    .autoload({ 'jquery': ['window.$', 'window.jQuery', '$', 'jQuery'] })
    .js('resources/website/js/Vue3test.js', 'public/website/js').vue()
    .sass('resources/website/css/app.scss', 'public/website/css')
    .copyDirectory('resources/website/images','public/website/images')
    .copyDirectory('resources/website/images','public/images')
    .copyDirectory('resources/views/emails/images','public/images/email')


    .sourceMaps();
1 Answers

Instead of mix.alias({...}), use the mix.webpackConfig. However, for node_modules you don't need the aliases. For example, to import vue-property-decorator you just do:

import {Vue, Component} from 'vue-property-decorator';

For custom components located for example in /resources/js/, you can do the following:
(Note: I haven't verified with node_modules, but it should work if you replace resources/js with node_modules in the example below.)

mix.autoload({ 'jquery': ['window.$', 'window.jQuery', '$', 'jQuery'] })
    .js('resources/website/js/Vue3test.js', 'public/website/js').vue()
    .sass('resources/website/css/app.scss', 'public/website/css')
    .copyDirectory('resources/website/images','public/website/images')
    .copyDirectory('resources/website/images','public/images')
    .copyDirectory('resources/views/emails/images','public/images/email')
    
    .webpackConfig({
        resolve: {
            extensions: [".ts", ".tsx", ".js", ".jsx", ".vue", "*"],
            alias: {
                'vue$': 'vue/dist/vue.esm.js',
                '@': path.resolve(__dirname, 'resources/js/'),
                '~': path.resolve(__dirname, 'resources/sass/')
            },
        },
    })

    .sourceMaps();

Then in your tsconfig.json:

"compilerOptions": {
    "paths": {
      "@*": ["./*"]
    }
}

And you can then import components from /resources/js/components/ExampleComponent.vue like so:

import ExampleComponent from '@/components/ExampleComponent'
Related