Laravel-mix custom rules not working? - laravel

I am trying to use this package to use my scss as javascript objects in my React part of my Laravel project.
Now when I try do add the rule to my webpack.mix.js folder I always get the following error for all my .scss files
ERROR in ./node_modules/css-loader??ref--5-2!./node_modules/postcss-loader/lib??postcss!./node_modules/resolve-url-loader??ref--5-4!./node_modules/sass-loader/lib/loader.js??ref--5-5!./node_modules/css-loader??ref--9-0!./resources/assets/sass/app.scss
Module build failed:
^
Invalid CSS after "e": expected 1 selector or at-rule, was "exports = module.ex"
in /Users/user/Desktop/project/resources/assets/sass/app.scss (line 1, column 1)
# ./resources/assets/sass/app.scss 2:14-318
# multi ./resources/assets/js/app.js ./resources/assets/sass/app.scss
my webpack.mix.js file:
let mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| 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.react('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
mix.webpackConfig({
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: "css-loader",
options: {
modules: true
}
}
]
}
]
}
});
EDIT
I've updated my webpack.mix.js and added the sass-loader but same error
mix.webpackConfig({
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: "css-loader",
options: {
modules: true
}
},
{
loader: "sass-loader",
options: {
modules: true
}
}
]
}
]
}
});

I have found a very nice npm package that fixed all my issues:
https://github.com/leinelissen/laravel-mix-react-css-modules

There is no modules option to sass-loader. Also install style-loader
Try:
module: {
rules: [
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: "css-loader",
options: {
modules: true
}
},
'sass-loader'
]
}
]
}

Related

Getting 95% emitting unnamed compat pluginError: UNKNOWN: unknown error, open

Whenever I do npm run watch, the first compilation works fine - but then after few compilations I'll eventually get this error:
95% emitting unnamed compat pluginError: UNKNOWN: unknown error, open 'D:\Laragon\www\erproj\public\js\app.js'
const mix = require('laravel-mix')
require('laravel-vue-lang/mix')
/*
|--------------------------------------------------------------------------
| 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.js('resources/js/app.js', 'public/js')
mix.webpackConfig(
{
module:
{
rules:
[
{
enforce: 'pre',
exclude: /node_modules/,
loader: 'eslint-loader',
test: /\.(js|vue)?$/
},
]
}
})
mix.webpackConfig(
{
module:
{
rules:
[
{
test: /\.scss$/,
use:
[
{
loader: 'sass-loader'
},
{
loader: 'sass-resources-loader',
options:
{
resources: './resources/sass/_*.scss'
}
}
]
}
]
}
})
mix.webpackConfig(
{
resolve:
{
alias:
{
'#': path.resolve('./resources/js'),
'~': path.resolve('./resources/')
}
}
})
mix.webpackConfig(
{
resolve:
{
alias:
{
'vue$': 'vue/dist/vue.js'
}
}
})
mix.webpackConfig(
{
resolve:
{
alias:
{
'#lang': path.resolve('./resources/lang'),
},
},
module:
{
rules:
[
{
test: /resources[\\/]lang.+\.(php|json)$/,
loader: 'laravel-localization-loader',
},
],
},
})
I've searched back and forth through google and found no solution that would work.
I appreciate any help.
Try manually setting the path where all the assets are going to be compiled. You can do this by adding mix.setPublicPath('public').
Reference: https://laravel-mix.com/docs/6.0/api#setpublicpathpath

Module build failed when trying to globally import variables on Laravel Vue project

I'm trying to globally import my variables file withing my webpack.mix.js file but have not been able to successfully do it. My alias is confirmed working by importing directly on the component but when I try to use vue-style-loader to include it on every vue style tag, it gives me a large error in my terminal.
ERROR in ./resources/sass/app.scss
Module build failed (from ./node_modules/css-loader/dist/cjs.js):
ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
#import "base/normalize";
^
Invalid CSS after "...load the styles": expected 1 selector or at-rule, was "var content = requi"
in /Users/jscotto/app/app.app.com/resources/sass/app.scss (line 1, column 1)
at runLoaders (/Users/jscotto/app/app.app.com/node_modules/webpack/lib/NormalModule.js:316:20)
at /Users/jscotto/app/app.app.com/node_modules/loader-runner/lib/LoaderRunner.js:367:11
at /Users/jscotto/app/app.app.com/node_modules/loader-runner/lib/LoaderRunner.js:233:18
at context.callback (/Users/jscotto/app/app.app.com/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
at Object.render [as callback] (/Users/jscotto/app/app.app.com/node_modules/sass-loader/dist/index.js:89:7)
at Object.done [as callback] (/Users/jscotto/app/app.app.com/node_modules/neo-async/async.js:8067:18)
at options.error (/Users/jscotto/app/app.app.com/node_modules/node-sass/lib/index.js:294:32)
# ./resources/sass/app.scss
ERROR in ./resources/sass/app.scss (./node_modules/css-loader/dist/cjs.js??ref--6-2!./node_modules/postcss-loader/src??postcss0!./node_
modules/resolve-url-loader??ref--6-4!./node_modules/sass-loader/dist/cjs.js??ref--6-5!./node_modules/vue-style-loader!./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/dist/cjs.js??ref--12-2!./resources/sass/app.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
#import "base/normalize";
^
Invalid CSS after "...load the styles": expected 1 selector or at-rule, was "var content = requi"
in /Users/jscotto/app/app.app.com/resources/sass/app.scss (line 1, column 1)
# ./resources/sass/app.scss 2:14-397
I believe this could have something to do with the way I'm compiling normal scss files so I will include my entire mix file below:
mix.sourceMaps(true, "source-map")
.ts("resources/js/app.ts", "public/js")
.sass("resources/sass/app.scss", "public/css")
.webpackConfig({
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
options: {
appendTsSuffixTo: [/\.vue$/]
},
exclude: /node_modules/
},
{
test: /\.scss$/,
use: [
"vue-style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
data: `#import "#/_var.scss`
}
}
]
}
]
},
resolve: {
extensions: ["*", ".js", ".jsx", ".vue", ".ts", ".tsx"],
alias: {
"#": path.resolve("resources/sass")
}
}
})
.extract(["vue"])
.version()
.scripts("resources/js/modules/*.js", "public/js/modules.js")
.options({
postCss: [
require("lost"),
require("autoprefixer")({
grid: true
})
]
})
.browserSync({
proxy: process.env.BROWSERSYNC_PROXY,
host: process.env.BROWSERSYNC_HOST,
browser: "google chrome"
});
The rule that is causing the issue is:
{
test: /\.scss$/,
use: [
"vue-style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
data: `#import "#/_var.scss`
}
}
]
}
Just hit the same issue, turned out I was omitting the semicolon in my global definitions.
Try giving this a go:
{
test: /\.scss$/,
use: [
"vue-style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
data: `#import "#/_var.scss;` //<- Semicolon here.
}
}
]
}

Vuejs Laravel blankpage on IE and Safari

My webapp work correctly on Chrome and Firefox but not with IE8-11 and Safari.
I use Laravel 5.6 and the last version of VueJS (with laravelmix webpack).
I supposed that the const variable type is not readable by IE and Safari (
I think it would be necessary to compile es6 in es5).
I've tried import babel in app.js file but also many library but with no result:
- npm install es6-promise
- npm i --save #babel/polyfill
- npm i babel-polyfill
- npm i bufferutil --save -optional
- .babelrc file in root
- npm i --save-dev babel-preset-stage-2
- npm i --save-dev babel-cli babel-preset-es2015
- npm i --save-dev babel-preset-env
- npm i joi-browser
- npm i --save-dev babel-preset-es2015-node6
- npm i --save-dev babel-preset-stage-0
Or laravelmix file (webpack.mix.js) should be able to with the right config?
I've tried also this:
- in webpack.mix.js file
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
mix.webpackConfig({
node: {
fs: 'empty'
}
});
// mix.webpackConfig({
// module: {
// rules: [
// {
// test: /\.js?$/,
// use: {
// loader: 'babel-loader',
// options: {
// presets: ['es2015'] // default == env
// }
// }
// }
// ]
// }
// });
// OR
// mix.webpackConfig({
// module: {
// rules: [{
// test: /\.js?$/,
// exclude: /(bower_components)/,
// use: [{
// loader: 'babel-loader',
// options: mix.config.babel()
// }]
// }]
// }
// });
.babelrc file:
{
"presets": ["es2015"]
}
and
{
"presets": [
[
"env",
{
"modules": false,
"browsers": ["IE >= 9", "> 1%"]
}
],
"stage-2"
],
"plugins": ["transform-runtime"],
"comments": false
}
If you have solutions or had a similar case, do not hesitate.
I've already searched on the web and by myself but nothing work.
If you need more information, tell me in comment.
EDIT:
ERROR MSG : SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode. (safari)

errors when creating webpack config file

I am trying to setup the simplest possible typescript+react-project in visual studio 2017.
I have this webpack.config.js that was changed to work with webpack 2+
The change was from using "loaders" and "preloaders" to "rules".
With the content below I get the error
Module build failed: error TS5014: Failed to parse file 'C:\Users\my project\tsconfig.json': Unexpected token } in JSON at position 4521.
This is the file
module.exports = {
entry: "./Scripts/hello-stackoverflow/index.tsx",
output: { filename: "./dist/bundle.js" },
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.tsx?$/, loader: "ts-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
]
},
externals: {
"react": "React",
"react-dom": "ReactDOM"
}
};

Laravel + VueJs + Webpack + Karma = world of pain

Is it possible to write unit tests for VueJs if you are using Laravel's Elixir for your webpack configuration?
VueJs 2x has a very simple example for a component test: Vue Guide Unit testing
<template>
<span>{{ message }}</span>
</template>
<script>
export default {
data () {
return {
message: 'hello!'
}
},
created () {
this.message = 'bye!'
}
}
</script>
and then...
// Import Vue and the component being tested
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'
describe('MyComponent', () => {
it('has a created hook', () => {
expect(typeof MyComponent.created).toBe('function')
})
it ...etc
})
and gives an example of a karma conf file here: https://github.com/vuejs-templates
But the Karma configuration file requires a webpack configuration file
webpack: webpackConfig,
The only problem is the Laravel's Elixir is creating the webpack configuration so it can't be included.
I have tried creating another webpack configuration file based on the example from https://github.com/vuejs-templates/webpack.
Something like this:
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the "scss" and "sass" values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
and included it like...
// Karma configuration
// Generated on Wed Mar 15 2017 09:47:48 GMT-0500 (CDT)
var webpackConf = require('./karma.webpack.config.js');
delete webpackConf.entry;
module.exports = function(config) {
config.set({
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
But I am getting errors that seem to indicate that webpack isn't doing anything.
ERROR in ./resources/assets/js/components/test.vue
Module parse failed: /var/www/test/resources/assets/js/components/test.vue Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <template>
| <span >{{test}}</span>
| </template>
Ok, I got this to work. Couple of things that might help.
I was originally running gulp, and trying to run tests in my vagrant box, to try to match the server configuration. I think that makes it much harder to find examples and answers on the internet.
Ok, so the main problem I was having is that webpack wasn't processing my components included in my test files. I copied the webpack config out of the laravel-elixir-vue-2/index.js node module directly into the Karma configuration file and it started working.
The key is that karma-webpack plugin needs both the resolve and module loader configuration settings (resolve with alias and extensions) for it to work.
Hope this helps someone.
karma.conf.js:
module.exports = function (config) {
config.set({
// to run in additional browsers:
// 1. install corresponding karma launcher
// http://karma-runner.github.io/0.13/config/browsers.html
// 2. add it to the `browsers` array below.
browsers: ['Chrome'],
frameworks: ['jasmine'],
files: ['./index.js'],
preprocessors: {
'./index.js': ['webpack']
},
webpack: {
resolve: {
alias: {
vue: 'vue/dist/vue.common.js'
},
extensions: ['.js', '.vue']
},
vue: {
buble: {
objectAssign: 'Object.assign'
}
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
},
webpackMiddleware: {
noInfo: true,
},
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' },
]
},
});
};
I ran into the exact same problem. The accepted answer did not fully work for me. The following solved my issue:
Install relevant loaders for webpack:
npm install --save-dev vue-loader file-loader url-loader
Create webpack config file (note the format). The accepted answer produced errors citing invalid format of the webpack.config.js file. At least with me it did.
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: [
{ loader: 'vue-loader' }
]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'file-loader',
query: {
limit: 10000,
name: '../img/[name].[hash:7].[ext]'
}
}
]
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: [
{
loader: 'url-loader',
query: {
limit: 10000,
name: '../fonts/[name].[hash:7].[ext]'
}
}
]
}
]
}
}
karma.conf.js
// Karma configuration
var webpackConf = require('./webpack.config.js');
delete webpackConf.entry
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
port: 9876, // web server port
colors: true,
logLevel: config.LOG_INFO,
reporters: ['progress'], // dots, progress
autoWatch: true, // enable / disable watching files & then run tests
browsers: ['Chrome'], //'PhantomJS', 'Firefox',
singleRun: true, // if true, Karma captures browsers, runs the tests and exits
concurrency: Infinity, // how many browser should be started simultaneous
webpack: webpackConf, // Pass your webpack.config.js file's content
webpackMiddleware: {
noInfo: true,
stats: 'errors-only'
},
/**
* base path that will be used to resolve all patterns (eg. files, exclude)
* This should be your JS Folder where all source javascript
* files are located.
*/
basePath: './resources/assets/js/',
/**
* list of files / patterns to load in the browser
* The pattern just says load all files within a
* tests directory including subdirectories
**/
files: [
{pattern: 'tests/*.js', watched: false},
{pattern: 'tests/**/*.js', watched: false}
],
// list of files to exclude
exclude: [
],
/**
* pre-process matching files before serving them to the browser
* Add your App entry point as well as your Tests files which should be
* stored under the tests directory in your basePath also this expects
* you to save your tests with a .spec.js file extension. This assumes we
* are writing in ES6 and would run our file through babel before webpack.
*/
preprocessors: {
'app.js': ['webpack', 'babel'],
'tests/**/*.spec.js': ['babel', 'webpack']
},
})
}
Then run karma start and everything should work.

Resources