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/**'
])
Related
Given the webpack.mix.js of a fresh Laravel project :
const 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/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
What is the equivalent using just webpack and a webpack.config.js? (Im looking to remove laravel mix as a dependency on an existing project.)
I did find this default file in the source but it did not help me. Is there a way I can see the "compiled/resulting" webpack configuration or a template/starting point that corresponds to laravel mix default settings?
You can, but the result is not very satisfactory.
Create a JS script with this:
console.log (JSON.stringify(
require('./node_modules/laravel-mix/setup/webpack.config.js'), null, 4)
);
and save it in the root folder of your laravel project. Run it with Node and the output will be the configuration object Laravel Mix receives and inputs to webpack.
However, this file is very long and covers a vast amount of settings, which you wouldn't need if you made your file from scratch. Yes, you could try and remove every extra setting you think you can remove without breaking your output, but in the end it's better to learn how Webpack works so you can write better, mode adjusted configs. At least you can use it to understand how it does certain things.
Just put into webpack.mix.js
Mix.listen('configReady', function (config) {
RegExp.prototype.toJSON = RegExp.prototype.toString;
console.log(JSON.stringify(config));
});
So you will get webpack config from your laravel.mix.
With recent laravel-mix you just need to invoke mix.dump() (in the webpack.mix.js script).
The file you referenced seems to point exactly to the default configuration. Why did this not help?
In order to migrate you could
Learn the basics
Extract the dependencies from Laravel mix aÇıd add them to your package.json
Hint: The dependencies there are your devDependencies
Start by installing npm install --save-dev everything "webpack", "babel" and prefixed with "-loader".
If you need Sass and extracted css - npm install --save-dev node-sass sass-loader mini-css-extract-plugin.
Minimal example of a webpack config for your mix example from above would be
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './resources/js/app.js',
output: {
filename: 'js/[name].js',
path: path.join(__dirname, 'public')
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
})
],
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader',
'sass-loader'
]
}
]
}
};
Learn the more advanced basics for your use case
I want to take all json files from path resources/json/ and do versioning so that when json files changed user can reload it, but I dont know which function I have to use
I changeed webpack.mix.js:
mix
.setPublicPath('public/build')
.setResourceRoot('build')
.js('resources/assets/js/app.js', 'js')
.sass('resources/assets/sass/app.scss', 'css')
//.json('resources/assets/json/*', 'json')
.version();
but I dont know how to copy from dir into another dir and in write mix-manifest file write all json files with hash
I have done this:
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
.setPublicPath('public/build')
.setResourceRoot('build')
.js('resources/assets/js/app.js', 'js')
.sass('resources/assets/sass/app.scss', 'css')
.copyDirectory('resources/assets/json', 'public/build/json')
.version(['public/build/json']);
and two times npm run dev, because mix is not waiting for copying files, .then() not helped, so two times npm run dev.
How do you include /node_modules in a laravel 5.5 application, i referenced this https://laravel.com/docs/5.5/mix
i can do this
npm install angular-moment moment --save
and it will make a /node_modules directory, however laravel ignores it
lets say i want to do this
<script src="node_modules/moment/moment.js"></script>
it will not work, it will show an error
i currently have this in my webpack, what will be the best way to integrate it ?
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')
.sass('resources/assets/sass/app.scss', 'public/css');
Just include it in your app.js so it is complied in...
var moment = require('moment');
Then access it as moment... like
moment().format();
I am attempting to use normal JavaScript with NPM and WebPack.
webpack.mix.js
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').version()
.sass('resources/assets/sass/app.scss', 'public/css').version();
In my app.js I added a simple test function:
var sayHi = function sayHi()
{
alert('hi');
};
And I included it in a HTML page, and called
<script>
sayHi();
</script>
However, I receive the error:
Uncaught ReferenceError: sayHi is not defined
I believe that WebPack etc. hides it all from the global namespace. I have ensured the compiled JavaScript with npm run watch has been included.
I am looking for insight on how to proceed.
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();