I am trying to copy files from one folder to another folder using Gulp:
gulp.task('move-css',function(){
return gulp.src([
'./source/css/one.css',
'./source/other/css/two.css'
]).pipe(gulp.dest('./public/assets/css/'));
});
The above code is copying one.css & two.css to the public/assets/css folder.
And if I use gulp.src('./source/css/*.css') it will copy all CSS files to the public/assets/css folder which is not what I want.
How do I select multiple files and keep the folder structure?
To achieve this please specify base.
¶ base - Specify the folder relative to the cwd. Default is where the glob begins. This is used to determine the file names when saving in .dest()
In your case it would be:
gulp.task('move-css',function(){
return gulp.src([
'./source/css/one.css',
'./source/other/css/two.css'
], {base: './source/'})
.pipe(gulp.dest('./public/assets/'));
});
Folder structure:
.
├── gulpfile.js
├── source
│ ├── css
│ └── other
│ └── css
└── public
└── assets
I use gulp-flatten and use this configuration:
var gulp = require('gulp'),
gulpFlatten = require('gulp-flatten');
var routeSources = {
dist: './public/',
app: './app/',
html_views: {
path: 'app/views/**/*.*',
dist: 'public/views/'
}
};
gulp.task('copy-html-views', task_Copy_html_views);
function task_Copy_html_views() {
return gulp.src([routeSources.html_views.path])
.pipe(gulpFlatten({ includeParents: 1 }))
.pipe(gulp.dest(routeSources.html_views.dist));
}
And there you can see the documentation about gulp-flatten: Link
gulp.task('move-css',function(){
return gulp
.src([ 'source/**'], { base: './' })
.pipe(gulp.dest('./public/assets/css/'));
});
Your own code didn't include the entire dir tree of source 'source/**' and the base {base:'./'} when calling to gulp.src which caused the function to fail.
The other parts where fine.
gulp.task('move-css',function(){
return gulp.src([
'./source/css/one.css',
'./source/other/css/two.css'
]).pipe(gulp.dest('./public/assets/css/'));
});
Related
Problem Context
I have webpack working for compiling my typescript into javascript. Automatic reloading works when I change my typescript code. However, webpack is not watching my static html file.
.
├── dist
│ ├── index.html
│ └── style.css
├── src
│ └── index.ts
└── webpack.config.js
The problem is I need to make several changes in my index.html and webpack does not automatically detect those changes. And, if I refresh the html page, it seems to break webpack's webpack-dev-server.
Expected Output
I want everything to be in the src folder and when I run webpack I have a fully working static site in my dist folder. That is:
. .
├── dist ├── dist
├── src │ ├── index.html
│ ├── index.html │ ├── bundle.js
│ ├── index.ts npx webpack -> │ └── style.css
│ └── style.css ├── src
└── webpack.config.js │ ├── index.html
│ ├── index.ts
│ └── style.css
└── webpack.config.js
The files in the dist folder might have hashed filenames. I'm not worrying about that step for now though. I expect that webpack will go through my files and make sure they link to the correct resources. So if webpack were to give style.css a hashed name, the href in index.html would be updated.
Current Output
My current solution outputs both index.html and bundle.js, but I cannot get it to copy style.css into the dist folder. My current webpack.config.js looks like the this:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: './src/index.ts',
devtool: 'inline-source-map',
mode: 'development',
devServer: {
contentBase: './dist'
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.html$/,
use: [
{ loader: 'file-loader?name=[name].[ext]' },
{ loader: 'extract-loader' },
{ loader: 'html-loader' }
]
}
]
},
plugins: [
new CleanWebpackPlugin()
],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
And my index.html looks like this:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>stuff</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="./bundle.js" charset="utf-8"></script>
</body>
</html>
My index.ts contains:
import './index.html';
What I Tried
At first I tried just adding an import for my css into my index.ts:
import './style.css';
But this did not work. Next I looked at the html-loader documentation, and it seemed to hint at what I'm looking for:
However, I've read that inlining loaders like that is deprecated, and looking through the source there doesn't seem to be any configuration option for interpolation. I tried to do it as described in the documentation anyways, but it either simply does not work, or gives me some error message about require not found (I can't seem to reproduce that error though). My index.html contained:
<link rel="stylesheet" href="${require(`style.css`)">
and index.ts contained:
require("html-loader?interpolate=require!./index.html");
How do I get webpack to move my style.css to the dist folder?
I have the hunch I'm misunderstanding how webpack is supposed to be used. When I have something working can I post my webpack config on the code review stack exchange to get help creating a more idiomatic webpack config?
When creating a CSS file, try using MiniCssExtractPlugin to write CSS to a new file
import './style.css'; - this should work, but write CSS inline in the head of html.
{ use: [MiniCssExtractPlugin.loader, 'css-loader'] }
For file name pattern: [name].[contenthash].bundle.js
Use HtmlWebpackPlugin for auto updating [contenthash]
const plugins = () => {
const result = [
new HtmlWebpackPlugin({
template: "./index.html", // this file will be used as html and all css/js will be automaticly included
})
]}
My directories structure is similar to this:
app/
directory1/
assets/
images/
js/
directory2/
assets/
images/
dist/
assets/
images/
js/
What I try to achieve using Gulp is to "gather" assets from directories 1, 2, ... and place them into the dist/assets/ so I wrote this:
gulp.task('gather-assets', function() {
gulp.src('app/*/assets/**').pipe(gulp.dest('dist/assets/'));
});
The problem is that after running this function it will create a path like this:
dist/assets/directory1/assets/images
Following the recommendations from this question I tried to use gulp-rename, but my case is different, and if I use gulp-rename like this:
gulp.task('gather-assets', function() {
gulp.src('app/*/assets/**').pipe(rename({dirname: ''})).pipe(gulp.dest('dist/assets/'));
});
it will surely remove unnecessary path at the place of * asterisk, but it will remove the ** path as well. So files from both images/ and js/ will be copied to assets/ without subdirectories. What solution is available for me for this scenario?
Gulp-flatten will work for you.
var flatten = require('gulp-flatten');
gulp.task('gather-assets', function() {
return gulp.src('app/*/assets/**')
// .pipe(rename({ dirname: '' }))
// -2 will keep the last two parents : assets/images or assets/js
.pipe(flatten({ includeParents: -2 }))
.pipe(gulp.dest('dist'));
});
And if you wanted to use gulp-rename: [both gulp-flatten and gulp-rename are just doing string manipulations of each file's directory structure]
// .pipe(flatten({ includeParents: -2 }))
.pipe(rename(function (file) {
let tempArray = file.dirname.split(path.sep);
// remove the first array item : directory1 or directory2
// rejoin the remaining array items into a directory string
let temp = tempArray.slice(1).join(path.sep);
file.dirname = temp;
}))
I want to approach my deploy folder from my gulpfile, I placed the gulpfile in the source folder so that it stays tidy. My current folder structure:
deploy
├── js
├── css
├── img
└── index.php
source
├── node_modules
├── base
├── structure
└── gulpfile.js
Structure above is only a part of the full tree
Part of gulpfile.js:
var path = {
js: {
src: [
'./source/_base/**/js/*.js',
'./source/_structure/**/js/*.js'
],
deploy: [
'../deploy/js/'
]
},
// more below this line
The gulp task:
gulp.task('process-js', function(){
gulp.src(path.js.src)
.pipe(plumber())
.pipe(jshint())
.pipe(jshint.reporter(stylish))
.pipe(concat('main.min.js'))
.pipe(uglify())
.pipe(plumber.stop())
.pipe(gulp.dest(path.js.deploy));
});
When I execute my gulp task (which uses this deploy path) I get an error:
:Error: Invalid output folder at Gulp.dest
Question:
How can I use the gulpfile relative path to place files in the parent of the root folder.
I've found the solution, it is - of course - not possible to parse an array as a destination.
I'm using gulp-watch to watch for changes
and right now I have it ignore layout files. The problem is that whenever I update a layout file, I have to change some other file for it to compile. Is there any way using gulp-watch to watch everything and then compile a part of it? I saw this relevant link but it did not use gulp-watch.
I misread this question. I've left my original answer at the bottom for reference anyway.
You could use gulp-if.
gulp.task('stream', function () {
return gulp.src('dir/**/*.*')
.pipe(watch('dir/**/*.*'))
.pipe(gulpif(function (file) {
return file.ext != ".layout"//your excluded extension
}, processIfTrue()))
.pipe(gulp.dest('build'));
});
That link does use gulp-watch. In fact, as I understand, that link explains exactly what you want to do.
The gulp-watch and whatever task you run on change take separate gulp.src instances.
You can, for example, use gulp.src('**/*.*') for your gulp.watch, and then gulp.src('**/*.less') for your compilation task.
You can set 2 separate watchers to run, and modifying each respective file listed below in src would trigger the respective task for that filename:
$ tree -I node_modules
.
├── gulpfile.js
├── package.json
└── src
├── layout-file-1.html
├── layout-file-2.html
├── other-file-1.html
└── other-file-2.html
1 directory, 6 files
gulpfile.js - gulp.watch() function
var gulp = require('gulp')
// files with the word "layout" in them
var layoutFiles = 'src/**/*layout*';
// files without the word "layout" in them
var otherFiles = ['src/**/*', '!'+layoutFiles];
// these tasks will show as completed in console output
gulp.task('build-layout-files');
gulp.task('build-other-files');
gulp.task('watch', function(cb) {
// watch only layoutFiles
gulp.watch(layoutFiles, ['build-layout-files'])
// watch only otherFiles
gulp.watch(otherFiles, ['build-other-files'])
})
gulp.task('default', ['watch'])
gulpfile.js - gulp-watch module
var gulp = require('gulp')
var watch = require('gulp-watch')
// use print to debug watch processes
var print = require('gulp-print')
// files with the word "layout" in them
var layoutFiles = 'src/**/*layout*';
// files without the word "layout" in them
var otherFiles = ['src/**/*', '!'+layoutFiles];
gulp.task('watch:layout-files', function(cb) {
watch(layoutFiles, function () {
gulp.src(layoutFiles)
.pipe(print(function(fileName) {
return "Compiling Layout File: "+fileName;
}))
.pipe(gulp.dest('build/layout-files'))
});
})
gulp.task('watch:other-files', function(cb) {
watch(otherFiles, function () {
gulp.src(otherFiles)
.pipe(print(function(fileName) {
return "Compiling Other File: "+fileName;
}))
.pipe(gulp.dest('build/other-files'))
});
})
gulp.task('default', ['watch:layout-files', 'watch:other-files'])
If I use :
gulp.src(['app/client/**/*.html'])
.pipe(gulp.dest('dist'));
The folder structure in which my .html files were in, is maintained in the dist folder, but I would like to remove the folder structure completely and just a flat hierarchy in my dist folder.
You could use gulp-rename to accomplish this:
var rename = require('gulp-rename');
gulp.src('app/client/**/*.html')
.pipe(rename({dirname: ''}))
.pipe(gulp.dest('dist'));
You can use gulp-flatten
https://www.npmjs.com/package/gulp-flatten
app
├── logo
│ └── logo.styl
└── sidebar
└── sidebar.styl
var flatten = require('gulp-flatten');
gulp.src('app/**/*.styl')
.pipe(flatten())
.pipe(gulp.dest('dist/'));
dist
├── logo.styl
└── sidebar.styl