Copy folder structure from src/ to dist/ using grunt-contrib-copy - node.js

I have a folder structure that looks like this
I want to copy the folder img/ from src/ to the dist/ folder.
I use the following grunt command, using grunt-contrib-copy:
copy:{
main : {
files : [
{
flatten : true,
expand: true,
src: ['src/img/*'],
dest: 'dist/img'
}
]
}
}
But my folder structure ends up like this. Missing the images in the icons folder:
Basically, I want to do the linux command (when I'm located in the root of my project):
cp -r src/img dist/img
How can I do this?

Set flatten to false flatten : false and change src to ['src/img/**'] to include subdirectories (source: https://github.com/gruntjs/grunt-contrib-copy)
copy:{
main : {
files : [
{
flatten : false,
expand: true,
src: ['src/img/**'],
dest: 'dist/img'
}
]
}
}

Solved it by doing the following:
copy:{
main : {
files : [
{
cwd: 'src/',
expand: true,
src: ['img/**'],
dest: 'dist/'
}
]
}
}
Setting the cwd was aparently needed for this to work.

Related

Webpack file-loader with sass-loader

I am new to nodejs and get a problem when trying to use sass with it.
The following information is just fictional, but it represents the
actual condition.
THE SCENARIO:
I have the following folder structure:
frontend/
- scss/
- style.scss
- main.js
webpack.config.js
Goal:
I want to compile the style.scss to style.css using webpack and put it inside dist/frontend/css/ directory, so it should be resulting this path: dist/frontend/css/style.css and create the following folder structure:
dist/
- frontend/
- scss/
- style.scs
- main.js
frontend/
- scss/
- style.scss
- main.js
webpack.config.js
THE CODES:
main.js
import `style from "./scss/style.scss";`
webpack.config.js
module.exports = {
mode: "development",
entry: {
main: "./frontend/main.js"
},
output: {
path: path.join(__dirname, "/dist/frontend"),
publicPath: "/",
filename: "[name].js"
},
module: {
rules: [
{
test: /\.(s*)css$/,
use: [
{
loader: "file-loader",
options: {
name: "css/[name].[ext]"
}
},
"style-loader/url",
"css-loader?-url",
"sass-loader"
]
}
]
}
THE RESULT:
I get this message:
Module not found: Error: Can't resolve './scss/style.scss' in 'E:\project_name\frontend'
THE QUESTIONS
Why is that happening?
What is the correct codes to achieve the Goal?
As the message said, this path is not valid: './scss/style.scss'. There are typo when defining the path. The folder is supposed to be sass instead of scss.
The following configuration will work to achieve the Goal mentioned in the question:
module: {
rules: [
{
test: /\.(s*)css$/,
use: [
"style-loader/url",
{
loader: "file-loader",
options: {
name: "css/[name].css"
}
},
"sass-loader"
]
}
]
}
It works like Mini CSS Extract Plugin, but does not generating additional .js files for each .css file when used to convert multiple .scss files into different .css files.

Grunt Sass - Compile all Sass files into CSS with the same name

I used Compass and it compiles all Sass files into CSS with the same name. For example my-style.scss will become my-style.css.
All tutorials about grunt-sass that I found mapped the file name one by one, manually like:
sass: {
dist: {
options: { style: 'compressed' },
files: { 'css/my-style.css': 'sass/my-style.scss' }
}
}
Is there a way to make it more flexible? So I don't need to change the Gruntfile whenever I have new Sass file.
Thanks
Try this format for specifying your source and destination files:
sass: {
src: {
files: [{
expand: true,
cwd: 'source/styles/',
src: ['**/*.scss'],
dest: 'destination/styles/',
ext: '.css'
}]
}
}
This reads as "take all files matching *.scss in source/styles/ and its subfolders, process them and put them into destination/styles/, changing extension to .css. See also http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically
You should use the universal notation:
sass: {
dist: {
options: { style: 'compressed' },
files: { 'css/*/**.css': 'sass/my-style.scss' }
}
}
In this case, the Grunt will go for all *.css files inside the css folder (including subfolders) regardless of the file name, and compile to my-style.scss

Exclude subdirectory in Grunt-contrib-copy

I'm copying some folders with grunt-contrib-copy. I'm trying to exclude a subdirectory in the root. I can prevent the contents of the _sprites folder from being copied, but inevitably the sprites copy is always copied. How do I prevent the folder from being copied? Here is what I have:
...
copy: {
deploy: {
cwd: "src/",
expand: true,
src: [
"**/*",
"!**/_sprites/**/*"
],
dest: "deploy/"
}
},
...
I've attempted !_sprites, !_sprites/ and others, but none appear to yield the results I want.

Exclude already up-to-date files

I'm using grunt-contrib-imagemin to optimize my images on a project. However, the optimization takes a long time due to the amount of images I'm optimizing.
Therefore, I only want to optimize images which are not existing in the destination OR where the source file is newer then the destination file.
Here is my configuration:
imagemin: {
dist: {
files: [{
expand: true,
cwd: 'src',
src: ['**/*.{jpg,jpeg,png,gif}'],
dest: 'dist/',
filter: 'isFile'
}]
}
}
Is there any way to extend the expansion of files to exclude already existing or newer destination files from the preprocessing?
Use grunt-newer https://github.com/tschaub/grunt-newer
watch: {
imagemin: {
files: ['**/*.{jpg,jpeg,png,gif}'],
tasks: ['newer:imagemin']
}
}

Grunt watch: compile only one file not all

I have grunt setup to compile all of my coffee files into javascript and maintain all folder structures using dynamic_mappings which works great.
coffee: {
dynamic_mappings: {
files: [{
expand: true,
cwd: 'assets/scripts/src/',
src: '**/*.coffee',
dest: 'assets/scripts/dest/',
ext: '.js'
}]
}
}
What I would like to do is then use watch to compile any changed coffee file and still maintain folder structure. This works using the above task with this watch task:
watch: {
coffeescript: {
files: 'assets/scripts/src/**/*.coffee',
tasks: ['coffee:dynamic_mappings']
}
}
The problem is that when one file changes it compiles the entire directory of coffee into Javascript again, it would be great if it would only compile the single coffee file that was changed into Javascript. Is this naturally possible in Grunt or is this a custom feature. The key here is it must maintain the folder structure otherwise it would be easy.
We have custom watch scripts at work and I'm trying to sell them on Grunt but will need this feature to do it.
You can use something like the following Gruntfile. Whenever a CoffeeScript file changes, it updates the configuration for coffee:dynamic_mappings to only use the modified file as the src.
This example is a slightly modified version of the example in the grunt-contrib-watch readme.
Hope it helps!
var path = require("path");
var srcDir = 'assets/scripts/src/';
var destDir = 'assets/scripts/dest/';
module.exports = function( grunt ) {
grunt.initConfig( {
coffee: {
dynamic_mappings: {
files: [{
expand: true,
cwd: srcDir,
src: '**/*.coffee',
dest: destDir,
ext: '.js'
}]
}
},
watch : {
coffeescript : {
files: 'assets/scripts/src/**/*.coffee',
tasks: "coffee:dynamic_mappings",
options: {
spawn: false, //important so that the task runs in the same context
}
}
}
} );
grunt.event.on('watch', function(action, filepath, target) {
var coffeeConfig = grunt.config( "coffee" );
// Update the files.src to be the path to the modified file (relative to srcDir).
coffeeConfig.dynamic_mappings.files[0].src = path.relative(srcDir, filepath);
grunt.config("coffee", coffeeConfig);
} );
grunt.loadNpmTasks("grunt-contrib-coffee");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.registerTask("default", [ "coffee:dynamic_mappings", "watch:coffeescript"]);
};
found a solution from an answer to a similar question https://stackoverflow.com/a/19722900/1351350
short answer: try https://github.com/tschaub/grunt-newer

Resources