laravel / nova-issues

557 stars 34 forks source link

Use Laravel-Mix v6 in tools? #3184

Closed marktopper closed 3 years ago

marktopper commented 3 years ago

Description:

Is it possible to use laravel-mix v6 in tools?

Whenever I try to upgrade a tool to use laravel-mix v6, it fails upon build with the Can't resolve error. Seems to be unable to load the .vue file extension after upgrade to v6.

If anyone has succeeded in this, please share your setup for this.

crynobone commented 3 years ago

This issue board is for tracking bugs and feature requests. Please direct general questions to #nova on Laravel's Discord or other support channel listed at https://nova.laravel.com/docs/3.0/support.html#support-questions

crynobone commented 3 years ago

In term of Laravel Nova itself, this will be considered when we worked on next series with updated Tailwind and Vue.js (planned this year).

AlbinoDrought commented 3 years ago

This is one of the first results when I google laravel nova laravel-mix. My templated tools were created with laravel-mix@^1.0 which uses a version of node-sass that doesn't work with Node 16+. Later versions of laravel-mix default to dart-sass instead, which works great. Here's what I did to get my tool building on Node 16 + laravel-mix:^6


Install it: npm install --save-dev laravel-mix@^6.0

Loosely following the upgrade guide at https://laravel-mix.com/docs/6.0/upgrade#update-your-npm-scripts , update your scripts in package.json to:

    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },

Still loosely following the upgrade guide at https://laravel-mix.com/docs/6.0/upgrade#before-1 , let laravel-mix know you're building Vue by adding .vue() to the end of the .js() line in webpack.mix.js:

.js('resources/js/tool.js', 'js').vue()

Update your resources/js/tool.js to import your components instead of using require. If you don't do this, your project will appear to build successfully but you will see a blank space where it should be on the Nova dashboard. If running Vue in devtools mode, you will see a Failed to mount component: template or render function not defined. message when this happens. https://laravel-mix.com/docs/4.0/upgrade#importing-es-modules

import Tool from './components/Tool.vue';

Nova.booting((Vue, router, store) => {
  Vue.component('your-tool', Tool)
})

Let laravel-mix install the rest of the required dependencies by running npm run dev. You should see something like this:

    Additional dependencies must be installed. This will only take a moment.

    Running: npm install sass-loader@^11.0.1 resolve-url-loader@^3.1.2 vue-template-compiler vue-loader@^15.9.5 --save-dev --legacy-peer-deps

This failed for me, no idea why, and I had to run the printed command manually:

npm install sass-loader@^11.0.1 resolve-url-loader@^3.1.2 vue-template-compiler vue-loader@^15.9.5 --save-dev --legacy-peer-deps

That's all I needed to do. npm run dev, npm run watch, and npm run prod all work as expected now :+1:


I ended up with this monster of an update script:

#!/bin/sh

set -e
set -x

# Install Deps
echo "If this step fails, you may need to manually run the 'npm install' string printed by laravel-mix"
npm install laravel-mix@^6 --save-dev --legacy-peer-deps

# Upgrade package.json scripts
## npm run development
sed -i 's/cross-env NODE_ENV=development node_modules\/webpack\/bin\/webpack.js --progress --hide-modules --config=node_modules\/laravel-mix\/setup\/webpack.config.js/mix/' package.json
## npm run watch
sed -i 's/cross-env NODE_ENV=development node_modules\/webpack\/bin\/webpack.js --watch --progress --hide-modules --config=node_modules\/laravel-mix\/setup\/webpack.config.js/mix watch/' package.json
## npm run watch-poll
sed -i 's/npm run watch -- --watch-poll/mix watch -- --watch-options-poll=1000/' package.json
## npm run hot
sed -i 's/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/mix watch --hot/' package.json
## npm run production
sed -i 's/cross-env NODE_ENV=production node_modules\/webpack\/bin\/webpack.js --progress --hide-modules --config=node_modules\/laravel-mix\/setup\/webpack.config.js/mix --production/' package.json

# Add .vue() to end of .js() line in webpack.mix.js
sed -i -E 's/\.js(.+)/.js\1.vue()/' webpack.mix.js

# Please manually replace all uses of `Vue.component('your-component', require(/* ... */))` with top-of-file `import` statements
(grep -r Vue.component resources | grep require && echo "Please manually replace inline require() with import statements in ./resources") || true

echo "If this step fails, your import statements could be wrong, or you may need to update vue to match your vue-template-compiler (installed by laravel-mix) version"
npm run prod
lucacri commented 3 years ago

@AlbinoDrought Thank you so much for that snippet. I was just going through the same problem, and your solution worked perfectly

FrazeColder commented 3 years ago

Hi @AlbinoDrought, first of all, thank you for your answer! I have already switched to laravel mix v6 and done all of this steps. However, I did not do them for my custom written nova components. I know have done that as well but I am ending up with a weird problem. This is the problem I get.

ERROR in ./resources/js/components/FormField.vue?vue&type=script&lang=js& (../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5[0].rules[0].use[0]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./resources/js/components/FormField.vue?vue&type=script&lang=js&) 20:0-66
Module not found: Error: Can't resolve 'laravel-nova' in '/Myproject/nova-components/PricePercentage/resources/js/components'

Do you have any idea on how to solve this?

gekkota commented 2 years ago

When we do this for multiple tools the vue() causes it to be included every time.

Can anyone advise how I should get it to only happen once?

whitespacecode commented 2 years ago

Hi @AlbinoDrought, first of all, thank you for your answer! I have already switched to laravel mix v6 and done all of this steps. However, I did not do them for my custom written nova components. I know have done that as well but I am ending up with a weird problem. This is the problem I get.

ERROR in ./resources/js/components/FormField.vue?vue&type=script&lang=js& (../../node_modules/babel-loader/lib/index.js??clonedRuleSet-5[0].rules[0].use[0]!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./resources/js/components/FormField.vue?vue&type=script&lang=js&) 20:0-66
Module not found: Error: Can't resolve 'laravel-nova' in '/Myproject/nova-components/PricePercentage/resources/js/components'

Do you have any idea on how to solve this?

Any update on this? Having the same issue

<script>
import {Paginatable, PerPageable} from 'laravel-nova';
`Error: Could not find a declaration file for module 'laravel-nova'.