Gulpfile relative path to root - gulp

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.

Related

How do I import static assets in a static html page with webpack?

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
})
]}

How to export (dest) in multiple folder [duplicate]

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/'));
});

gulp if one file changes, compile the rest

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'])

Why does node.js app CSS load in my IDE but not on a localhost?

I am making a nodejs application using LightTable, and the css seems to be loading fine when I indicate a relative path to the file in my <link href=""> tag. When I run node index.js, however, the server starts up and the page loads fine, but I get a console error and my own 404 saying the CSS file could not be found at the path specified. I tried using Heroku's Foreman Start as well, but no dice. Here is the html:
<!DOCTYPE html>
<html>
<head>
<title>
Home
</title>
<link href="../../styles/master.css" rel="stylesheet" type="text/css" />
</head>
...
Here is my directory tree structure:
.
├── Procfile
├── README.md
├── index.js
├── package.json
├── resources
│   └── images
│   └── tokyo.jpg
├── styles
│   └── master.css
└── views
├── get
│   ├── home.html
│   └── posts.html
└── post
└── new.html
EDIT: after finding the answer to the question, the below information became relevant. I have commented out the new code that makes the CSS and background image load as desired.
Here is my routing and server code. I am not using Express, on purpose:
// routes
var homeREGEX = new RegExp('^/?$');
var newREGEX = new RegExp('^/posts/new/?$');
var postsREGEX = new RegExp('^/posts/?$');
// var cssREGEX = new RegExp('^/styles/master.css/?$'); <--| static resources also
// var tokyoREGEX = new RegExp('^/resources/images/tokyo.jpg/?$'); <--| need routes.
// server
var server = http.createServer(function(request, response){
var pathname = url.parse(request.url).pathname;
if (homeREGEX.test(pathname)) {
renderHome(request, response);
} else if (newREGEX.test(pathname)) {
renderPostForm(request, response);
} else if (postsREGEX.test(pathname)) {
addNewPost(request, response);
// } else if (cssREGEX.test(pathname)) { <--| and they need to get
// sendCSS(request, response); <--| served individually as
// } else if (tokyoREGEX.test(pathname)) { <--| they are requested
// sendTokyo(request, response);
} else {
error404(request, response);
}
});
What's the url you use in your browser when viewing the page ? My guess is that is does not contains the views/get part, which means that you don't need the ..\.. in your link href attributes.
Also, make sure your are actually serving these static files (it seems you're not). If you're using express (with nodejs ) for example, you'll need something like this :
app.use(express.static('resources'));
app.use(express.static('style'));
See express.static documentation.
Maybe you can try to put the exact path instead of ../../
<link href="/Procfile/styles/master.css" rel="stylesheet" type="text/css" />

Can you remove a folder structure when copying files in gulp?

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