Versioning combined CSS files in Laravel 5.4 with Laravel Mix - laravel

I am using Laravel Mix in Laravel 5.4 and I would like to combine to plain files and add versioning.
Reading the documentation it says
The version method will automatically append a unique hash to the
filenames of all compiled files, allowing for more convenient cache
busting
And it efectively does what it says. But is there any workaround to obtain a final combined file with versioning?
Actually I would like to join some compiled files together with other plain files and combine everything in a single versioned file.
Edit:
The code I am using is like the following
mix.sass('resources/assets/sass/app.scss', 'public/css')
.combine(['public/css/app.css', 'other/component/file.css'], 'public/css/all.css')
.version();
And I would like to obtain a versioned all.css file. i.e. something like all.d41d8cd98f00b204e9800998ecf8427e.css.
However what I get is a versioned version of the app.css and a non-versioned version of the all.css.

Versioning/Cache-Busting for CSS and JS files
Webpack.Mix
After combining my css (using mix.styles) and js (using mix.scripts) files into two files, I had all.css and all.js.
To add versioning, I did the following:
var timestamp = Date.now();
mix.copy('public/css/all.css', 'public/css/all/all.'+ timestamp + '.css');
mix.copy('public/js/all.js', 'public/js/all/all.'+ timestamp + '.js');
OR
Write it directly when you combine your css and js files, for example:
mix.styles([
'public/css/app.css',
'public/css/custom.css'], 'public/css/all/all.'+ Date.now() + '.css').
mix.scripts([
'public/js/app.js',
'public/js/custom.js'], 'public/js/all/all.'+ Date.now() + '.js').
Blade layout file:
I created /css/all/ and /js/all/ directories. I used the scandir() php function with ordering to get all of the files in the respective directories. Then I got the first filename from the array, which in this instance was 'all.1574160664960.css'.
#php($css_files = scandir('css/all/', 1))
<link href="/css/all/{{ $css_files[0] }}" rel="stylesheet">
#php($js_files = scandir('js/all/', 1))
<script src="/js/all/{{ $js_files[0] }}"></script>

https://laravel-mix.com/docs/5.0/versioning
In webpack.mix.js:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.sass', 'public/css')
.version();

Related

How can I compile JS without merging on Laravel mix?

How can I compile JS without merging on Laravel mix?
const mix = require('laravel-mix');
mix.js('resources/js/*', 'public/js');
The code above results in all the js files in the js directory being merged into one file.
But, I want to get a result like below code.
const mix = require('laravel-mix');
mix.js('resources/js/a.js', 'public/js/a.js');
mix.js('resources/js/b.js', 'public/js/b.js');
...
mix.js('resources/js/z.js', 'public/js/z.js');
You can use copy.
const mix = require('laravel-mix');
mix.copy('resources/js', 'public/js');
Above will copy entire files inside resources/js into public/js directory.

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 use external scripts in vue js and laravel

is the first time I use vue js and laravel mix and I'm a bit confused, I previously loaded the scripts manually, without compiling, however now that I want to use vue js, when I add the app.js script to the end of my blade template the others scripts stop working, I tried to compile all the scripts and add them together with the app.js file but even so it does not work, this is my webpack code
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
//project files
mix.styles([
'public/css/materialize.css',
'public/plugins/datatablesMaterialize.css',
'public/css/main.css',
'public/css/ionicons.min.css',
'public/css/nouislider.css',
'public/plugins/fullcalendar/fullcalendar.css',
'public/plugins/responsive.dataTables.min.css',
'public/css/jquery.fancybox.min.css',
'public/css/style.css',
'public/css/sweetalert2.min.css',
'public/css/jquery.steps.css'
], 'public/css/allPets.css');
mix.scripts([
'public/plugins/datatablesMaterialize.js',
'public/plugins/moment.min.js',
'public/plugins/dataTables.responsive.min.js',
'public/plugins/moment.min.js',
'public/plugins/fullcalendar/fullcalendar.js',
'public/plugins/fullcalendar/lang/es.js',
'public/plugins/jquery.validate.js',
'public/plugins/validation-additional-methods.min.js',
'public/js/materialize.js',
'public/js/sweetalert2.min.js',
'public/js/jquery.steps.js',
'public/plugins/jquery.validate.js',
'public/plugins/slick/slick.min.js',
'public/js/jquery.fancybox.min.js',
'public/js/spinner.js',
'public/js/jquery.spin.js',
'public/js/funciones.js'
], 'public/js/allPets.js');
when I use the files allPets.css and allPets.js without the script app.js everything works, however when I add everything it stops working again(
the sidebars of materialize stop working etc).
var plugin = 'resources/assets/plugins/';
mix.js('resources/assets/js/app.js', 'public/js/app.js')
.combine([
plugin + 'jquery/jquery.min.js',
plugin + 'popper/popper.min.js',
plugin + 'bootstrap/bootstrap.min.js',
plugin + 'moment/moment.min.js',
plugin + 'toastr/toastr.min.js',
plugin + 'slimscroll/jquery.slimscroll.js',
plugin + 'waves/waves.js',
plugin + 'sticky-kit/sticky-kit.min.js',
plugin + 'fancybox/jquery.fancybox.pack.js',
plugin + 'fancybox/jquery.fancybox.js',
plugin + 'fancybox/jquery.mousewheel.pack.js',
'public/js/app.js',
],'public/js/bundle.min.js')
.sass('resources/assets/sass/style.scss', 'public/css')
.browserSync('laravue');

minify js and styles in laravel 5

How can I minify my JavaScript and css files all in one?
currently I have:
let mix = require('laravel-mix');
mix.styles([
'theme/admin/assets/css/bootstrap.css',
'theme/admin/assets/font-awesome/css/font-awesome.css',
'theme/admin/assets/css/zabuto_calendar.css',
'theme/admin/assets/lineicons/style.css',
'theme/admin/assets/css/style.css',
'theme/admin/assets/css/style-responsive.css',
'css/adminstyle.css'
], 'public/css/admin.css');
mix.scripts([
'theme/admin/assets/js/jquery.min.js',
'theme/admin/assets/js/bootstrap.min.js',
'theme/admin/assets/js/jquery.dcjqaccordion.2.7.js',
'theme/admin/assets/js/jquery.scrollTo.min.js',
'theme/admin/assets/js/jquery.nicescroll.js',
'theme/admin/assets/js/jquery.sparkline.js',
'theme/admin/assets/js/common-scripts.js',
'theme/admin/assets/js/zabuto_calendar.js'
], 'public/js/admin.js');
in my webpack.mix.js file but it creates empty files.
You have to use full path starting from the root directory of your Laravel application.
So instead of:
'theme/admin/assets/css/bootstrap.css'
As you've said that theme is under public, you should do this:
'public/theme/admin/assets/css/bootstrap.css'
Do this update on the rest of your URLs

Webpack mix verion files that use Copy or CopyDirectry

Laravel Mix Version: 1.4.5
Node Version: v6.10.2
NPM Version: 3.10.10
OS: windows 10 xampp
Description:
Undefined index when using copy/copyDirectory and {{ mix() }}
Steps To Reproduce:
Create 2 folders in resources
/css/afolder/afile.css
/css/another/anotherfile.css
Copy the folders with the following:
`mix.copy('resources/assets/css/', 'public/css', false);`
or
`mix.copyDirectory('resources/assets/css/', 'public/css');`
The files are copied fine, but when using
`{{ mix('css/afolder/afile.css') }}`
or
`{{ mix('css/anotherfolder/anotherfile.css') }}`
It returns back
Undefined index: css/afolder/afile.css
Undefined index: css/anotherfolder/anotherfile.css
The folders exists:
public/css/afolder/afile.css
public/css/anotherfolder/anotherfile.css
Mix manifest just shows the following
{
"/js/app.js": "/js/app.js?id=0eaf1649511b8f1c3fd9",
"/css/app.css": "/css/app.css?id=a86d86d0b7edd1152cc6"
}
Full webpackmix 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.js('resources/assets/js/app.js', 'public/js');
mix.copy('resources/assets/js/', 'public/js', false);
mix.copy('resources/assets/css/', 'public/css', false);
mix.sass('resources/assets/sass/app.scss', 'public/css');
mix.version();
Webpack does not apply version on files under copy() or copyDirectory() methods. Because they runs standalone, outside of webpack build.
If you just copy them, you should use this files like as simple file, that are not under version.
<link rel="stylesheet" href="{{ asset('css/afolder/afile.css') }}">
The mix.version() will automatically version any compiled JavaScript, Sass/Less, or combined files. However, if you'd also like to version extra files as part of your build, simply pass a path, or array of paths, to the method, like so: mix.version(['public/js/random.js']);
Webpack mix doesn't work with copyDirectory().
Below is a solution that adds all files from the copied directory to the manifest:
webpack.mix.js
let mix = require('laravel-mix');
mix.copyDirectory('resources/sourceDir/', 'public/destinationDir');
mix.version([
'destinationDir/**'
])

Resources