Correct way to include image via relative path - sass

I've updated laravel-mix to version 4.0.12 and faced with broken build on the line in *.scss where I used a relative path to include background image
I got a next files structure
resources/
|-assets/
||-img/
|||-background.png
||-sass/
|||-footer.scss
my code in footer.scss is next
.footer {
background-image: url(../img/background.png)
}
My webpack.mix.js is next
const mix = require('laravel-mix');
const resourcesAssets = 'resources/assets/';
const dest = 'public/assets/';
mix
.copy(`${resourcesAssets}images`, `${dest}images`, false)
.sass(`${resourcesAssets}scss/footer.scss`, `${dest}css`);
During compling npm run prod I got
Module build failed (from ./node_modules/css-loader/index.js):
ModuleBuildError: Module build failed (from ./node_modules/resolve-url-loader/index.js):
Error: resolve-url-loader: CSS error
predicate must return an absolute path or the result of calling next()
at file://C:\xampp\htdocs\laravel-project\resources\assets\sass\footer.scss:2:3
at encodeError (C:\xampp\htdocs\laravel-project\node_modules\resolve-url-loader\index.js:218:12)
at onFailure (C:\xampp\htdocs\laravel-project\node_modules\resolve-url-loader\index.js:175:14)
at <anonymous>
at runMicrotasksCallback (internal/process/next_tick.js:122:5)
at _combinedTickCallback (internal/process/next_tick.js:132:7)
at process._tickCallback (internal/process/next_tick.js:181:9)
at runLoaders (C:\xampp\htdocs\laravel-project\node_modules\webpack\lib\NormalModule.js:301:20)
at C:\xampp\htdocs\laravel-project\node_modules\loader-runner\lib\LoaderRunner.js:364:11
at C:\xampp\htdocs\laravel-project\node_modules\loader-runner\lib\LoaderRunner.js:230:18
at context.callback (C:\xampp\htdocs\laravel-project\node_modules\loader-runner\lib\LoaderRunner.js:111:13)
at onFailure (C:\xampp\htdocs\laravel-project\node_modules\resolve-url-loader\index.js:175:5)
at <anonymous>
at runMicrotasksCallback (internal/process/next_tick.js:122:5)
at _combinedTickCallback (internal/process/next_tick.js:132:7)
at process._tickCallback (internal/process/next_tick.js:181:9)
error in ./resources/assets/sass/footer.scss
How can I fix this problem?

It's an URL rewriting thing in Webpack as Laravel Mix is built on top of Webpack. For CSS compilation, Webpack rewrites and optimizes any url() calls within your stylesheets.
However, according to the Laravel Docs:
Absolute paths for any given url() will be excluded from URL-rewriting. For example, url('/images/thing.png') or url('http://example.com/images/thing.png') won't be modified.
So, Mix tries to rewrite your CSS to sth. like:
.footer {
background-image: url(/img/background.png?<some-hash-identifier>)
}
In that case, you can disable url() like so and Mix will not touch url(../img/background.png) in your footer.scss:
mix.sass(`${resourcesAssets}scss/footer.scss`, `${dest}css`);
.options({
processCssUrls: false
});

The problem was in too new "resolve-url-loader": "^3.0.0".
After installing an intermediate version "laravel-mix": "~3" some time ago it was added to package.json.
Removing it and rerun build helps me to resolve the problem. laravel-mix added "resolve-url-loader": "2.3.1" after running npm run prod.

Related

mix.js() is missing required parameter

I use Vue with Laravel. But I get this error "mix.js() is missing required parameter" when I run
npm run watch.
Here is my code:
const mix = require("laravel-mix");
mix.js("resources/js/app.js", "public/js").vue();
mix.sass("public/assets/scss/style.scss", "public/assets/css");
mix.browserSync("127.0.0.1:8000");
Please share with me how to handle this error.
Change in version works well with laravel 7.3.* see link below
The solution was to change to version ^6.0.6 in package.json and run npm install, as the .vue() call is a new feature in Laravel Mix 6.
"devDependencies": {
// ...
"laravel-mix": "^6.0.6",
// ...
},
Then on webpack.mix.js.
mix.js('resources/js/app.js', 'public/js').vue();
https://nono.ma/assertionerror-mix-js-is-missing-required-parameter-1-entry

How to remove #charset in the CSS file when running npm?

I'm using Laravel 5.7 and i'm applying AMP to our website. (https://amp.dev/).
I'm folowing these steps to convert HTML to AMP: https://amp.dev/documentation/guides-and-tutorials/start/converting/?format=websites
One of the requirements is to replace external stylesheets to internal stylesheets (https://amp.dev/documentation/guides-and-tutorials/start/converting/resolving-errors?format=websites#replace-external-stylesheets). I've done this by doing the following code below:
<style amp-custom>
{!! file_get_contents(public_path('css/app.css')) !!}
</style>
I'm using Sass and I'm using Laravel mix to compile my assets.
This is my webpack.mix.js
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.sourceMaps()
.version();
But upon doing this I've encountered an error in the AMP:
CSS syntax error in tag 'style amp-custom' - saw invalid at rule '#charset'.
To solve this problem, I must remove the #charset "UTF-8"; in the compiled css css/app.css. And it seems that running npm run dev, its automatically adding #charset "UTF-8"; at the top of the file. How do I remove this?
I'm thinking that I have to add some code in the webpack.mix.js to remove that. But I don't have an idea how to do this.
Yep! SASS adds this directive if your SASS contains any extended (e.g., not standard ASCII) characters. There's an open issue in the SASS project to provide an option to not do this... but they've said they won't provide that option.
For now, it's pretty easy to fix... simply add a step that your build process that hunts for #charset "UTF-8"; and removes it. You can see how I did it here:
https://github.com/ampproject/samples/blob/master/amp-camp/gulpfile.js#L63
gulp.task('styles', function buildStyles() {
const cssEncodingDirective = '#charset "UTF-8";';
return gulp.src(paths.css.src)
... (stuff removed)
.pipe(options.env === 'dev' ? replace(cssEncodingDirective, '') : noop())
... (more stuff removed)
});
If you run 'npm run production', that line will be deleted automatically and you will not get an error in AMP validation.

how to compile js to es5 with laravel mix?

I have laravel Vue app and it works perfectly with chrome and firefox. but it doesn't work on Edge or IE11 and the console shows error on arrow function!?
How to compile or transpile to es5 with laravel mix and webpack?
could you show the correct configuration for webpack.mix.js?
tnx alot
UPDATE February 2020
If anyone still need help with this, mix already provide a babel compilation to es5:
A slight variation of mix.scripts() is mix.babel(). Its method
signature is identical to scripts; however, the concatenated file will
receive Babel compilation, which translates any ES2015 code to vanilla
JavaScript that all browsers will understand.
You can use it like this:
mix.babel(['public/js/es6file.js'], 'public/js/app.es5.js')
DOCS
In order to compile your es6 code to es5 follow the following steps:
1) install the babel-env preset
npm install #babel/preset-env --save
And then declare it in your .babelrc in the root directory:
{
"presets": ["#babel/preset-env"]
}
2) compile your code using
npm run dev //for dev environment
or
npm run prod // for production environment
after a lot of search, I've found out that this Vuecomponent causes the error "https://github.com/godbasin/vue-select2" how can I compile it to es5.
the edge console error:
Expected identifier, string or number
and the corresponding line that it shows is this:
setOption(val = []) {
this.select2.empty();
this.select2.select2({
-----> ...this.settings,
data: val
});
this.setValue(this.value);
},
sorry for taking your time

Setup Laravel Mix with SASS and PostCSS critical CSS splitting

I want to setup Laravel Mix with mix.sass AND PostCss Critical CSS splitting. In the end I want two files: app.css and app-critical.css.
Unfortunately I can get this to work. One of the setups (webpack.mix.js) I did try:
mix
.js('templates/src/js/app.js', 'web/assets/dist/')
.js('templates/src/js/home.js', 'web/assets/dist/')
.extract(['vue','axios','lazysizes','svgxuse', 'fontfaceobserver'], 'web/assets/dist/vendor.js')
.sass('templates/src/scss/app.scss', 'web/assets/dist/')
.sourceMaps()
.options({
postCss: [
require('postcss-critical-css')({
preserve: false,
minify: false
})
]
})
.browserSync({
proxy: '127.0.0.1:8080',
files: [
'templates/**/*.twig',
'templates/src/js/**/*',
'templates/src/scss/**/*'
]
});
if (mix.inProduction()) {
console.log("In production");
mix.version();
}
When I run the script via 'npm run watch' I get an error:
10% building modules 0/1 modules 1 active ...ign-tools/templates/src/scss/app.scssWithout `from` option PostCSS could generate wrong source map and will not find Browserslist config. Set it to CSS file path or to `undefined` to prevent this warning.
Also, my file is just copying over all the critical styling. The file grows bigger and bigger, expanding the duplicate code everytime the input SCSS/CSS-file changes.
I did try to set up Laravel Mix + mix.sass + one of the following plugins:
https://github.com/zgreen/postcss-critical-css
https://www.npmjs.com/package/postcss-critical-split
Without success :(
Anybody with a working setup or link to an example repository?
Thanks,
Teun

Laravel 5.4 Mix ignore img in SCSS

I try to use Laravel 5.4 mix with SCSS, but it gives me and error
error in ./mysite/assets/sass/landing/landing.scss
Module build failed: ModuleNotFoundError: Module not found: Error
Can't resolve '../img/somepic.png' in
'/var/www/html/mysite/resources/assets/sass/landing'`
in
mix.sass('resources/assets/sass/landing/landing.scss', 'public/css/landing.css');
However, I don't want to resolve pics at all, I just want them to stay as they were.
Fixed the problem with
mix.options({
processCssUrls: false
});
in webpack.mix.js

Resources