Webpack, Mix and Vuetify loader : SassError: Expected newline - laravel

I use Vuetify loader in my Laravel project but compilation doesn't work.
Laravel : 8.46
Vue : 2.6.14
Vuetify : 2.5.3
This is my package.json
{
"private": true,
"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"
},
"devDependencies": {
"axios": "^0.21",
"deepmerge": "^4.2.2",
"laravel-mix": "^6.0.6",
"path": "^0.12.7",
"postcss": "^8.1.14",
"sass": "^1.34.1",
"sass-loader": "^12.1.0",
"vue": "^2.6.14",
"vue-loader": "^15.9.5",
"vue-template-compiler": "^2.6.14",
"vuetify": "^2.5.3",
"vuetify-loader": "^1.7.2"
}
}
My webpack.mix.js
const mix = require('laravel-mix');
const path = require('path');
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')
mix.webpackConfig({
resolve: {
alias: {
'#': path.resolve(__dirname, 'resources/js/')
}
},
module: {
rules: [
{
test: /\.s(c|a)ss$/,
use: [
"sass-loader",
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sassOptions: {
indentedSyntax: true
},
},
},
],
},
],
},
plugins: [
new VuetifyLoaderPlugin()
],
});
mix.js('resources/js/app.js', 'public/js')
.vue()
//.extract(['vue'])
.postCss('resources/css/app.css', 'public/css', [
//
]);
if (mix.inProduction()) {
mix.version();
}
My entry :
require('./bootstrap');
import Vue from 'vue'
import vuetify from '#/plugins/vuetify'
new Vue({
vuetify,
}).$mount('#app')
And my vuetify plugin :
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
const opts = {}
export default new Vuetify(opts)
But when I run yarn dev, I have an error :
...
ERROR in ./node_modules/vuetify/src/styles/main.sass (./node_modules/css-loader/dist/cjs.js??clonedRuleSet-15[0].rules[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-15[0].rules[0].use[2]!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-15[0].rules[0].use[3]!./node_modules/sass-loader/dist/cjs.js!./node_modules/vue-style-loader/index.js!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??clonedRuleSet-22[0].rules[0].use[3]!./node_modules/vuetify/src/styles/main.sass)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Expected newline.
╷
4 │ var content = require("!!../../../css-loader/dist/cjs.js!../../../sass-loader/dist/cjs.js??clonedRuleSet-22[0].rules[0].use[3]!./main.sass");
│ ^
╵
node_modules/vuetify/src/styles/main.sass 4:141 root stylesheet
webpack compiled with 95 errors
I follow Vuetify documentation and Mix documentation.

Related

Why does my App JS file increase after each run of NPM run dev?

For some strange reason, whenever I run npm run dev, each time, my /public/js/app.js file seems to gain a few MB, regardless of not changing any code.
webpack.mix.js
mix.js('resources/js/app.js', 'public/js')
.vue()
.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
])
.webpackConfig(require('./webpack.config'));
if (mix.inProduction()) {
mix.version();
}
if (!mix.inProduction()) {
mix.bundleAnalyzer({
analyzerMode: 'static'
});
}
webpack.config.js
const path = require('path');
module.exports = {
resolve: {
alias: {
'#': path.resolve('resources/js'),
},
},
};
app.js
require('./bootstrap');
import { createApp, h } from 'vue';
import { createInertiaApp } from '#inertiajs/inertia-vue3';
import { InertiaProgress } from '#inertiajs/progress';
const appName = window.document.getElementsByTagName('title')[0]?.innerText
|| 'Laravel';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.mixin({ methods: { route } })
.mount(el);
},
});
InertiaProgress.init({ color: '#4B5563' });
The problem seems to be the .vue() in the webpack file, which, when run without, reduces the app.js size down to 700kb. But, of course, without it, I get:
ERROR in ./resources/js/Pages/Dashboard.vue 1:0 Module parse failed:
Unexpected token (1:0) You may need an appropriate loader to handle
this file type. Currently, no loaders are configured to process this
file. See https://webpack.js.org/concepts#loaders
package.json
{
"private": true,
"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"
},
"devDependencies": {
"#inertiajs/inertia": "^0.10.0",
"#inertiajs/inertia-vue3": "^0.5.1",
"#inertiajs/progress": "^0.2.6",
"#tailwindcss/forms": "^0.2.1",
"#vue/compiler-sfc": "^3.0.5",
"autoprefixer": "^10.2.4",
"axios": "^0.21",
"laravel-mix": "^6.0.6",
"laravel-mix-bundle-analyzer": "^1.0.5",
"lodash": "^4.17.19",
"postcss": "^8.2.13",
"postcss-import": "^14.0.1",
"tailwindcss": "^2.2.7",
"vue": "^3.0.5",
"vue-loader": "^16.1.2"
},
"dependencies": {
"#headlessui/vue": "^1.4.0",
"#heroicons/vue": "^1.0.4"
}
}
Please can someone point me in the right direction?

FullCalendar is not defined. Laravel 8 Fullcalendar-scheduler version 5.6 es6

Uncaught ReferenceError: FullCalendar is not defined when
npm install. If I use the cdn source inside my calendar blade. Calendar will display correctly. However, I change to npm install and I am stuck
composer install
npm i
npm run dev
webpack.mix.js
let mix = require("laravel-mix");
let productionSourceMaps = false;
mix.js('resources/js/app.js', 'public/js')
mix.sass('resources/sass/app.scss', 'public/css')
.sourceMaps()
if (mix.inProduction()) {
mix.version();
}
app.js
import 'jquery';
require('./bootstrap');
import 'moment';
import 'fullcalendar-scheduler';
app.scss
#import "~bootstrap/dist/css/bootstrap.css";
#import "~fullcalendar-scheduler/main.css";
#import "~bootstrap-select/dist/css/bootstrap-select.min.css";
#import "~shop-item/dist/bootstrap/css/bootstrap.css";
#import "~font-awesome/css/font-awesome.css";
#import "variables";
package.json
{
"private": true,
"scripts": {
"dev": "mix",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"axios": "^0.21.1",
"css-loader": "^5.2.1",
"laravel-mix": "^6.0.16",
"lodash": "^4.17.21",
"postcss": "^8.2.10",
"resolve-url-loader": "^3.1.2",
"sass": "^1.32.10",
"sass-loader": "^11.0.1"
},
"dependencies": {
"autoprefixer": "^10.2.5",
"bootstrap": "^4.5.3",
"bootstrap-datetimepicker": "0.0.7",
"bootstrap-select": "^1.13.18",
"chartjs": "^0.3.24",
"datatables.net": "^1.10.24",
"font-awesome": "^4.7.0",
"fullcalendar-scheduler": "5.6.0",
"jquery": "^3.6.0",
"moment": "^2.29.1",
"popper.js": "^1.16.1",
"style-loader": "^2.0.0",
"waypoints": "^4.0.1",
"webpack": "^5.35.0",
"webpack-cli": "^4.6.0"
}
}
With Webpack, it's always better to use "require" instead of "import" in app.js
So try this:
var moment = require ('moment');
require ('fullcalendar-scheduler');
I finally got... I just had not learned enough yet.. But, hope this helps others.
I needed both a webpack.config.js and a webpack.mix.js and a little work on the package.json. Here are the changes that worked for me. Also, I could never get npm i fullcalendar-scheduler to work in the build.. I had to use #fullcalendar
webpack.config.js
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: './resources/fullcalendar/main.js',
resolve: {
extensions: [ '.js' ]
},
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{ loader: 'css-loader', options: { importLoaders: 1 } }
]
}
]
},
output: {
filename: 'main.js',
path: path.join(__dirname, 'public/dist')
},
plugins: [
new MiniCssExtractPlugin({
filename: 'main.css'
})
]
}
webpack.mix.js
let mix = require("laravel-mix");
mix
.js("resources/js/app.js", "public/js")
.sass("resources/sass/app.scss", "public/css");
package.json
{
"private": true,
"scripts": {
"dev": "mix && npm run build",
"development": "mix",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production",
"build": "webpack",
"watch": "webpack --watch",
"clean": "rm -rf dist"
},
"devDependencies": {
"css-loader": "^4.3.0",
"laravel-mix": "^6.0.18",
"mini-css-extract-plugin": "^1.2.0",
"resolve-url-loader": "^3.1.2",
"sass": "^1.32.11",
"sass-loader": "^11.0.1",
"webpack": "^5.3.0",
"webpack-cli": "^4.1.0"
},
"dependencies": {
"#fullcalendar/adaptive": "^5.6.0",
"#fullcalendar/core": "^5.6.0",
"#fullcalendar/daygrid": "^5.6.0",
"#fullcalendar/interaction": "^5.6.0",
"#fullcalendar/list": "^5.6.0",
"#fullcalendar/resource-timeline": "^5.6.0",
"#fullcalendar/timegrid": "^5.6.0",
"autoprefixer": "^10.2.5",
"bootstrap": "^4.6.0",
"jquery": "^3.6.0",
"webpack": "^5.35.0",
"webpack-cli": "^4.6.0"
}

Module not found: Error: Can't resolve 'timers'

i'm trying to install this package https://github.com/shwilliam/vue-scrollin to my laravel + vue project. after compiling with laravel mix, the following error appeared:
Module not found: Error: Can't resolve 'timers' in
'\node_modules\vue-scrollin\dist'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules
by default. This is no longer the case. Verify if you need this module
and configure a polyfill for it. If you want to include a polyfill,
you need to:
- add a fallback 'resolve.fallback: { "timers": require.resolve("timers-browserify") }'
- install 'timers-browserify' If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "timers": false }
I followed the given instructions but it gives me the same errors.
webpack.mix.js
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js').vue()
.sass('resources/css/app.scss', 'public/css/app.css')
.postCss('resources/css/app.css', 'public/css', [
//
])
.webpackConfig(require('./webpack.config'));
webpack.config.js
module.exports = {
resolve: {
fallback: { "timers": require.resolve("timers") }
},
};
package.json
{
"private": true,
"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"
},
"devDependencies": {
"#fortawesome/fontawesome-free": "^5.15.3",
"#fortawesome/fontawesome-svg-core": "^1.2.35",
"#fortawesome/free-regular-svg-icons": "^5.15.3",
"#fortawesome/free-solid-svg-icons": "^5.15.3",
"#fortawesome/vue-fontawesome": "^3.0.0-3",
"#vue/compiler-sfc": "^3.0.7",
"axios": "^0.21",
"bulma": "^0.9.2",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"particles.vue3": "^1.3.1",
"postcss": "^8.1.14",
"resolve-url-loader": "^3.1.2",
"sass": "^1.32.8",
"sass-loader": "^10.1.1",
"vue": "^3.0.5",
"vue-loader": "^16.1.2",
"vue-router": "^4.0.5",
"vue-scrollin": "^0.1.2",
"timers-browserify": "^2.0.12"
}
}
You almost got it. webpack.config.js should be:
module.exports = {
resolve: {
fallback: { "timers": require.resolve('timers-browserify') }
},
};
Just change the package in the require.resolve() to what the warning suggests.
For anyone who comes here with a polyfills-problem or about to migrate from webpack 4 to 5, here's the PR with a list of removed polyfills

CKEditor 5 - Why h2 tags look like p tags?

I Have a problem when use CKEditor 5 for my project ( VILT stack )
I can describe the problem as follows :
Here is my vue file:
<template>
<app-layout>
<ckeditor :editor="editor" #blur="onEditorInput" v-model="editorData" :config="editorConfig"></ckeditor>
</app-layout>
</template>
<script>
import AppLayout from '#/Layouts/AppLayout'
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
export default {
components: {
AppLayout,
},
data() {
return {
editor: ClassicEditor,
editorData: '',
editorConfig: {
// The configuration of the editor.
}
}
},
methods: {
onEditorInput() {
console.log(this.editorData);
}
}
}
</script>
and here's the app.js :
require('./bootstrap');
// Import modules...
import Vue from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '#inertiajs/inertia-vue';
import PortalVue from 'portal-vue';
import CKEditor from '#ckeditor/ckeditor5-vue2';
Vue.mixin({ methods: { route } });
Vue.use(InertiaPlugin);
Vue.use(PortalVue);
Vue.use( CKEditor );
const app = document.getElementById('app');
new Vue({
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => require(`./Pages/${name}`).default,
},
}),
}).$mount(app);
and here are the contents of the package.json file :
{
"private": true,
"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"
},
"devDependencies": {
"#inertiajs/inertia": "^0.8.2",
"#inertiajs/inertia-vue": "^0.5.4",
"#tailwindcss/forms": "^0.2.1",
"#tailwindcss/typography": "^0.3.0",
"autoprefixer": "^10.0.2",
"axios": "^0.21",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"portal-vue": "^2.1.7",
"postcss": "^8.1.14",
"postcss-import": "^12.0.1",
"tailwindcss": "^2.0.1",
"vue": "^2.5.17",
"vue-loader": "^15.9.6",
"vue-template-compiler": "^2.6.10"
},
"dependencies": {
"#ckeditor/ckeditor5-build-classic": "^25.0.0",
"#ckeditor/ckeditor5-vue2": "^1.0.5"
}
}
So you can see in the console it says h2 but it looks like a p tag and I don't like it, how do I make the text look like h2 when I select the h2 option?
i have tried reading the documentation ( Quick start ) but still haven't found the right solution
that's because you are using tailwindcss and it escapes H tags. You can add
#layer
base {
h1 {
#apply text-2xl;
}
h2 {
#apply text-xl;
}
}
to your resources->css->app.css file and you will make it work as normal.

How to use Typescript in Laravel Project with Vue as frontend?

I want to use typescript in Vue in Laravel project.
I already checked all tutorials for that but none of them works for me give below
teej.
Titas Gailius.
sebastiandedeyne.
when ever i run 'npm run dev' i get this error
ERROR in ./resources/js/app.ts
Module build failed: Error: You may be using an old version of webpack; please check you're using at least version 4
at successfulTypeScriptInstance (E:\PersonalProjects\web_dev\blog\node_modules\ts-loader\dist\instances.js:144:15)
at Object.getTypeScriptInstance (E:\PersonalProjects\web_dev\blog\node_modules\ts-loader\dist\instances.js:34:12)
at Object.loader (E:\PersonalProjects\web_dev\blog\node_modules\ts-loader\dist\index.js:17:41)
# multi ./resources/js/app.ts ./resources/sass/app.scss
Im facing this problem from quite some days but i was finally be able to find the solution for that so im Sharing my exp to folks who want to use typescript instead of javascript in vue in laravel. so here is the instruction
here the intruction
Laravel 5.7 uses Laravel-mix which down the line uses webpack 3 . Which is not what we want for typescript to work in laravel project.
Initialize your project
Let's create a new Project. You can also do this on Existing project just make sure to convert js code to ts.
First make sure you have composer and laravel installed
sh
laravel new Laravel-Vue-Typecript
Open the project in your any favraite code editor.
Open the package.json and add these packages to devdependencies
{
"devDependencies": {
"auto-loader": "^0.2.0",
"autoprefixer": "^9.4.1",
"axios": "^0.18",
"bootstrap": "^4.0.0",
"lodash": "^4.17.5",
"popper.js": "^1.12",
"jquery": "^3.2",
"cross-env": "^5.1",
"css-loader": "^1.0.1",
"mini-css-extract-plugin": "^0.4.5",
"node-sass": "^4.10.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"ts-loader": "^5.3.1",
"typescript": "^3.2.1",
"uglifyjs-webpack-plugin": "^2.0.1",
"vue": "^2.5.17",
"vue-class-component": "^6.3.2",
"vue-property-decorator": "^7.2.0",
"webpack": "^4.26.1",
"webpack-cli": "^3.1.2",
"vue-loader": "^15.4.2",
"vue-template-compiler": "^2.5.17"
}
}
Now install these npm packages with
npm install
Add Typescript Support
Then rename these files
Laravel-Vue-Typecript/
├─ resources/js/app.js => resources/js/app.ts
└─ resources/js/bootstrap.js => resources/js/bootstrap.ts
Now Change the Code in app.ts, bootstrap.ts and
resources/js/components/ExampleComponent.vue
// app.ts
import "./bootstrap"
import Vue from "vue"
import ExampleComponent from "./components/ExampleComponent.vue"
Vue.component('example', ExampleComponent)
new Vue({
el: '#app'
})
// bootstrap.ts
import axios from 'axios';
import * as _ from 'lodash';
import jQuery from 'jquery';
import * as Popper from 'popper.js';
import 'bootstrap';
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token : HTMLMetaElement | null = document.head!.querySelector('meta[name="csrf-token"]');
if (token) {
axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
// resources/js/components/ExampleComponent.vue
<template>
<h1>This is an example component</h1>
</template>
<script lang="ts">
import Vue from 'vue'
import Component from "vue-class-component"
#Component
export default class ExampleComponent extends Vue {
mounted() : void {
console.log("hello");
}
}
</script>
```
Create typings.d.ts file inside resources/js and add these lines.
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
declare module 'jquery';
declare module 'lodash';
Now Create tsconfig.json, webpack.config.js and postcss.config.js in the root of your project and these lines of code to them respectivly
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"strict": true,
"module": "es2015",
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true
},
"include": [
"resources/js/**/*"
],
"exclude": [
"node_modules",
"vendor"
]
}
webpack.config.json
const path = require('path')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const autoprefixer = require('autoprefixer');
const webpack = require('webpack');
let env = process.env.NODE_ENV
let isDev = env === 'development'
const WEBPACK_CONFIG = {
mode: env,
entry: {
app: ['./resources/js/app.ts', './resources/sass/app.scss'],
},
output: {
publicPath: './public',
path: path.resolve(__dirname, 'public'),
filename: 'js/[name].js',
chunkFilename: 'js/chunks/app.js'
},
module: {
rules: [{
test: /\.tsx?$/,
loader: 'ts-loader',
options: { appendTsSuffixTo: [/\.vue$/] },
exclude: /node_modules/,
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader'
],
exclude: /node_modules/,
}
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
}),
new VueLoaderPlugin(),
new webpack.LoaderOptionsPlugin({
options: {
postcss: [
autoprefixer()
]
}
})
],
resolve: {
extensions: ['.js', '.jsx', '.vue', '.ts', '.tsx'],
alias: {
vue$: 'vue/dist/vue.esm.js',
},
},
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
}
if (!isDev) {
WEBPACK_CONFIG.optimization = {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true
}),
new OptimizeCSSAssetsPlugin({})
]
}
WEBPACK_CONFIG.plugins.push(
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: 'production'
}
})
)
}
module.exports = WEBPACK_CONFIG
postcss.config.js
module.exports = {
plugins: {
'autoprefixer': {}
} }
Now finally change the "scripts" in package.json
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=webpack.config.js"
},
Finally build the project
and run the npm scripts by
npm run dev // To build the Project
npm run watch // To build and watch for files changes and build automagically
npm run prod // for production

Resources