As part of my build script using Laravel Mix, I'm needing to make a modification to one of the files inside the resources/assets/sass directory. The problem is that running npm run watch will then modify this file and the watcher re-runs the build process, causing an infinite recursive loop.
Is there any way to exclude an individual file from being watched for changes?
For example:
webpack.mix.js
// Do something with `resources/assets/sass/_modules.scss` first, then continue
mix.sass('resources/assets/sass/app.scss');
app.scss
#include "_modules.scss";
If you're ok with webpack not automatically updating your relative stylesheet URL's, try this:
In webpack.mix.js, add the following option:
processCssUrls: false
Source: https://github.com/JeffreyWay/laravel-mix/blob/master/docs/options.md
Related
I have a folder of SCSS files. The main SCSS file is /css/app.scss. It imports all the other SCSS files, like /css/variables.scss and /css/component_a.scss.
How can I have sass watch my /css/ folder for any changes, then recompile starting from /css/app.scss?
Right now it errors since /css/component_a.scss uses variables defined in a different file. But in app.scss they are imported in the correct order.
My answer may be limited because I don't have all the information about how you are compiling sass and what settings you are using.
However I can see that your file names aren't prefixed with an underscore, basically sass will compile every file individually that doesn't have the '_' prefix.
Basically what you want to do is set up your task manager (grunt, gulp, etc) to watch all files ending with '.scss' then tell it to run the sass compile task and have this pointed at your app.scss file.
With the limited information I have from your question I hope that my answer points you in the right direction to solve your problem.
I am using a css file that I import through npm. Respectively it is saved in my "/node_modules" directory.
I want to compile this file with my other scss files with elixir and am searching for a way, how to include it properly.
The options I could do is:
Rename the file from file.css to file.scss and import it in my app.scss
Copy the file.css file to my "resources/assets/" directory, rename it to scss and include it in my sass compilation like this:
Now I want to know, if there is a way to reference the file from the "node_modules" directory, without touching the file, because I want other people who download the project and use "composer install" and "npm install" to be up and running.
Or is the most common way to handle this, just to copy every required file from my "node_modules" directory to my resources/assets folder? Seems odd, since the included bootstrap file of the laravel framework is added just through an scss import in the app.scss file.
Now I want the same, but scss files can't import css files, which I have in my case, which would require for me to just rename it, which would not work out of the box on any other environment, since the "node_modules" directory is not included in version control.
Any recommendations, on what the best way is to compile css files in my "node_modules" directory?
If you look at the Elixir documentation you will notice there are many handy functions you can use. One of them is the mix.copy() function (you can copy single file or whole directory, for example whole jquery folder).
elixir(function(mix) {
mix.copy('node_modules/blabla/file.scss', 'resources/assets/sass/file.scss');
mix.sass(['file.scss', 'app.scss']);
});
This way each time you call gulp it will first copy the scss file from node_modules dir and then will compile sass.
Just add a dot before file path.
mix.scripts([
'./node_modules/autosize/src/autosize.js',
'./bower_components/jquery-tokenize/jquery.tokenize.js'
], 'public/js/app.js');
var elixir = require('laravel-elixir');
var path = require('path');
/*
|--------------------------------------------------------------------------
| Elixir Asset Management
|--------------------------------------------------------------------------
|
| Elixir provides a clean, fluent API for defining some basic Gulp tasks
| for your Laravel application. By default, we are compiling the Less
| file for our application, as well as publishing vendor resources.
|
*/
function node_modules(filename) {
return path.join('../../../node_modules/', filename);
}
elixir(function (mix) {
var base = [
node_modules('bootstrap-sass/assets/javascripts/bootstrap/tooltip.js'),
node_modules('bootstrap-sass/assets/javascripts/bootstrap/collapse.js')
];
});
I want to use Laravel Elixir to minify my css/files files. But I don't want to use the mix-methode and merge them. All I want is to generate a "custom.min.js" file from my original "custom.js". Is there a way to do this with Elexir?
EDIT:
To make it a bit clearer: My biggest issue is that I have two folders in "resources/assets": js and css. So I basically want to minify all files in there and have them minified in "public/js" and "public/css".
Quote from the Laravel documentation:
Note: All tasks will assume a development environment, and will exclude minification. For production, use gulp --production.
This means if you want the files to be minified run gulp --production instead of just gulp. It's a better practise than enabling compression directly in the gulp file and makes sure you can debug your compiled files while developing the application.
If you want them to be placed in public/assets/css use the path as a second parameter:
mix.less('app.less', 'public/assets/css');
gulp --production.
Jeffrey way replied on the issue here: https://laracasts.com/discuss/channels/elixir/elixir-doesnt-minify
Or you can find it on the documentation. Enjoy coding!
If you just want to copy .css files, without using LESS or SASS, and don't want to combine files (i.e. you want something like a copy() method with minification ability) you can use method for combining, styles(), by calling it for every .css file and passing filename string without array, for example:
mix.styles('some.css');
mix.styles('node_modules/bootstrap/dist/css/bootstrap.css', null, './');
Same can be done for .js files using scripts() method:
mix.scripts('some.js');
mix.scripts('node_modules/bootstrap/dist/js/bootstrap.js', null, './');
And then you can use gulp (doesn't minify, creates .map files) or gulp --production (creates minified files) as mentioned in above posts.
Straight from the Laravel/Elixir docs:
Elixir is built on top of Gulp, so to run your Elixir tasks you only need to run the gulp command in your terminal. Adding the --production flag to the command will instruct Elixir to minify your CSS and JavaScript files:
Run all tasks... gulp
Run all tasks and minify all CSS and JavaScript... gulp --production
docs: https://laravel.com/docs/5.3/elixir#running-elixir
There seem to be a few plugins...and I'm using webstorm file watcher which also precompiles individual files.
I think this may not be the best way to setup a watcher.
I'm running this command now:
sass --no-cache --update --stop-on-error --trace ./app/sass:./app/css
It seems to conflict with the webstorm file watch, which appears to be appending everything to base.css. Can someone tell me what exactly this command is doing vs. a sass filewatcher in webstorm?
What's the best way to work with sass:
precompile my sass to css using a grunt build task
and have file watchers while developing?
My base.sass looks like this:
#charset "UTF-8";
/* DO NOT EDIT FILES IN ./css. See ./sass instead */
#import "page";
#import "modal";
#import "nav";
#import "tables";
#import "forms";
#import "message";
Your command just compiles all files in diretory ./app/sass to CSS and put the resultant files to ./app/css. Default file watcher runs the following command:
sass --no-cache --update $FileName$:$FileNameWithoutExtension$.css
i.e. it takes the current file (the one that has been changed) as input and creates a .css in the same directory. But, as you have 'track only root files' option on (default settings), the watcher creates css for the root file only - the one that reference other files via imports. You can turn this option off to change the current behavior ans get css generated for other files as well.
I have a simple Rake Pipeline setup that does nothing more than run "stylus" on my .styl files, using the rake-pipeline-web-filters gem. (The original pipeline does much more, but I've trimmed it down to the essentials for this question.
=== Assetfile ===
require "rake-pipeline-web-filters"
output "build"
input "app/style" do
# Compile Stylus to CSS
match "*.styl" do
stylus
end
end
This works fine for converting individual .styl files to individual .css files.
However, I am not able to use the Stylus #import command to import one file in another (necessary for mixins, among other things. Instead I get the error
ExecJS::ProgramError: Error: stylus:1
> 1| #import "appmixins"
2|
failed to locate #import file appmixins.styl
All the styl files are in the same folder, and when I execute stylus on the commandline using the npm version, the import works fine, so there's no syntax error.
Is this just something that's missing from the Stylus Filter in rake-pipeline-web-filters, or is there something I can do to make it work?
Ok, it looks like when I run the in Rake Pipeline in assumes all paths are starting from the directory I'm running the pipeline in, and so all the #imports have to be relative to that. Changing my imports to #import "app/style/appmixins" worked. This is different from what the NPM version of Stylus does, since it expects (and the docs specify) that all the paths are relative to the individual stylesheets. Not sure if I could have specified the block differently in the Assetfile to make this work as expected, but no matter, it all works for me now.