Let’s say we have the following folder structure:
rootDirectory
│
│
├──a
│ ├──a.txt
│
├──b
│ ├──a
│ ├──a.txt
│
├──c.txt
also, let’s say we need to write a Gulp task that will take a.txt in the a folder, and c.txt; perform some manipulations on them, and then pipe them into the build directory. What I want is for the files copied in the build folder to keep their directory structure in the build folder (and I do not want files that were not supposed to be processed by the task to get in the build folder), like so:
rootDirectory
│
│
├──a
│ ├──a.txt
│
├──b
│ ├──a
│ ├──a.txt
│
├──c.txt
│
├──build
│
├──a
│ ├──a.txt
│
├──c.txt
Now, here is what puzzles me. If I specify paths to specific files:
gulp.task('foo', function(){
var files = [
path.join(__dirname, 'c.txt'),
path.join(__dirname, 'a/a.txt')
];
gulp.src(files)
.pipe(gulp.dest(path.join(__dirname, build));
});
then I will flatten the folder structure in the build directory.
If, however, I use the globbing pattern:
gulp.task('foo', function(){
var files = [
path.join(__dirname, '**/c.txt'),
path.join(__dirname, '**/a/a.txt')
];
gulp.src(files)
.pipe(gulp.dest(path.join(__dirname, build));
});
then the folder structure is preserved, but this globbing pattern will also target b/a.txt, which I do not want.
Is there a way to achieve what I describe in Gulp? Basically, telling Gulp: "Here, take this file, do whatever you need with this, and put it in another path keeping the folder structure starting from this root path"? Apart from specifically negating globbing paths that I do not want to match?
In order to preserve hierarchy you should pass {base: "."} parameter to the gulp.src. Something like this:
gulp.task('foo', function(){
var files = [
path.join(__dirname, 'c.txt'),
path.join(__dirname, 'a/a.txt')
];
gulp.src(files, {base: '.'})
.pipe(gulp.dest(path.join(__dirname, build));
});
Related
I am creating a multipage website that uses javascript to, among other things, create and read the entry "darkTheme" in local storage if the user enables dark mode. It works flawlessly in (index.html), but when I navigate to another page on the website (e.g. FAQ.html), I am unable to access that variable (Firefox says there is "No data present for selected host") and the dark theme reverts to light, since no variable was created for it.
I don't want to have the user enable dark theme on every page individually. So how can I make it so that variable can be accessed across all other pages in my website instead of just the index?
This is the structure of the website so far:
.
├── img
│ ├── banner1.png
│ └── banner2.png
├── js
│ ├── FAQ.js
│ └── theme.js
├── html
│ └── FAQ.html
├── index.html
└── style.css
The Java script:
let darkTheme = localStorage.getItem('darkTheme');
const themeToggle = document.querySelector('#themeButton');
const bodyBackground = document.getElementById('#body');
const enableDark = () => {
document.body.classList.add('darktheme');
localStorage.setItem('darkTheme', 'enabled');
themeToggle.innerHTML = `<i id="themeButton__icon" icon-name="sun"></i>`;
lucide.createIcons();
};
const disableDark = () => {
document.body.classList.remove('darktheme');
localStorage.setItem('darkTheme', null);
themeToggle.innerHTML = `<i id="themeButton__icon" icon-name="moon"></i>`;
lucide.createIcons();
};
if (darkTheme === 'enabled') {
document.body.classList.add('notransition');
enableDark();
document.body.classList.remove('notransition');
} else {
disableDark();
}
themeToggle.addEventListener('click', () => {
darkTheme = localStorage.getItem('darkTheme');
if (darkTheme !== 'enabled') {
enableDark();
} else {
disableDark();
}
});
If I inspect index.html with FF, under Storage > Local Storage I see that the variable is created. But if I do the inspection to FAQ.html, there isn't any variable there. I expected to be able to access the variable from the "parent" page in "child" page as well.
BTW, I am working on the project by opening the .html on my machine with a browser and making edits on a text editor. I haven't hosted it somewhere yet. I am assuming that this behaviour will continue once I host it, please let me know if this is not the case.
This is my first website, am I approaching this in a poor way?
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
})
]}
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 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/'));
});
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