So for some reason, I'm having some problems with my gulp scripts where gulp scripts won't write the appropriate js to the bundled file.
So I have the following folder structure:
theme/
- dist/
--- css/
----- bundle.css
--- js
----- bundle.js
- src/
--- scss/
----- bundle.scss
--- js/
----- bundle.js
----- components/
------- test.js
Here is the gulp styles task which works perfect - What it does is that it takes all of the contents inside src/scss/ and bundles it and exports it to dist/css/bundle.css.
export const styles = () => {
return src(['src/scss/bundle.scss', 'src/scss/admin.scss', 'src/scss/bulmapress.scss'])
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(cleanCss({compatibility:'ie8'})
.pipe(dest('dist/css'))
.pipe(server.stream());
}
My src/scss/bundle.scss file has the following:
#import "components/header";
#import "components/footer";
Here is the task that I have for gulp scripts where once I run the task, it doesn't compile the content inside src/js/components etc.. it compiled things that are inside src/js/bundle.js which is just a storage component to define import "components/test". Here is the task:
export const scripts = () => {
return src(['src/js/bundle.js'])
.pipe(dest('dist/js'));
}
I'm not sure what I'm doing wrong, or if this is natural behavior? What might be a better alternative to do this? Below is the full gulpfile.babel.js if anyone wants to check it out.
Would it be better for js to not be bundled into bundle.js and just be minimized into it's own separate file?
import { src, dest, watch, series, parallel } from 'gulp'; //import { src, dest, watch, series, parallel } from 'gulp';
import yargs from 'yargs';
import sass from 'gulp-sass';
import cleanCss from 'gulp-clean-css';
import gulpif from 'gulp-if';
import sourcemaps from 'gulp-sourcemaps';
import imagemin from 'gulp-imagemin';
import del from 'del';
import browserSync from "browser-sync";
import zip from "gulp-zip";
import info from "./package.json";
import replace from "gulp-replace";
const PRODUCTION = yargs.argv.prod;
const server = browserSync.create();
export const serve = done => {
server.init({
proxy: "http://localhost:8888/starter"
});
done();
};
export const reload = done => {
server.reload();
done();
};
export const styles = () => {
return src(['src/scss/bundle.scss', 'src/scss/admin.scss', 'src/scss/bulmapress.scss'])
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(cleanCss({compatibility:'ie8'})
.pipe(dest('dist/css'))
.pipe(server.stream());
}
export const scripts = () => {
return src(['src/js/bundle.js'])
.pipe(dest('dist/js'));
}
You have to transpile ES6 code to ES5 code using gulp-babel before you do uglification or minification.
Read this article about gulp tasks to understand how gulp works:
https://medium.com/#sudoanushil/how-to-write-gulp-tasks-ce1b1b7a7e81
Related
Let's say I have this folder structure:
parent
|-parent.html
|-parent.js
|-child
|--child.html
|--child.js
I want them to output in the same structure in my dist folder.
By default this is what gets output:
dist/assets/parent.js
dist/assets/child.js
I want them to output like this:
dist/parent/parent.js
dist/parent/child/child.js
I tried changing the assetFileNames option of Rollup but it didn't do anything.
The output filenames are configured in Rollup with build.rollupOptions. Set output.entryFileNames to configure the location of the entry .js files to match their original directory structure:
// vite.config.js
import { fileURLToPath } from 'url';
import { defineConfig } from 'vite';
import path from 'path';
const rootDir = fileURLToPath(new URL('.', import.meta.url));
export default defineConfig({
build: {
rollupOptions: {
input: {
parent: './parent/parent.html',
child: './parent/child/child.html',
},
output: {
entryFileNames: (assetInfo) => {
// assetInfo.facadeModuleId contains the file's full path
if (assetInfo.facadeModuleId) {
const assetPath = path.dirname(assetInfo.facadeModuleId).replace(rootDir, '');
return assetPath + '/[name]-[hash].js';
} else {
return 'assets/js/[name]-[hash].js';
}
},
},
},
},
});
demo
Notes
Assets (such as .css files) and shared modules (vendor .js chunks) cannot be redirected with the solution above because the asset info from the related hooks do not provide the file's full path.
In a vanilla Rollup project, output.preserveModules=true would've accomplished the original goal, but that option conflicts with Vite's own settings for Rollup.
I am trying to create a gulpfile.js to compile scss to css and JS components to a main JS file. But it's not working properly.
The issues i am facing, when I run the command gulp:
It doesn't compile JS components to a main JS file.
It compiles SCSS but when i save any file, the git-bash terminal executing files infinitely, here is the screenshot:
Here is my gulpfile.js:
"use strict";
const source = 'assets/';
// Load Modules
const { src, dest, watch, series } = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const postcss = require('gulp-postcss');
const cssnano = require('cssnano');
const terser = require('gulp-terser');
const browsersync = require('browser-sync').create();
// Scss Task
function scssTask() {
return src(`${source}/scss/zaincss.scss`)
.pipe(sass())
.pipe(postcss([cssnano()]))
.pipe(dest(`${source}/css`));
}
// Javascript Task
function jsTask() {
return src(`${source}/js/scripts/*.js`)
.pipe(terser())
.pipe(dest(`${source}/js/scripts/`));
}
// BrowserSync Tasks
function browserSyncServe(done) {
browsersync.init({
server: {
baseDir: '.'
},
injectChanges: true
});
done()
}
function browserSyncReload(done) {
browsersync.reload();
done();
}
// Watch Task
function watchTask() {
watch('*.html', browserSyncReload);
watch(['assets/scss/**/*.scss', 'assets/js/**/*.js'], series(scssTask, jsTask, browserSyncReload));
}
// Default Gulp Task
exports.default = series(
scssTask, jsTask, browserSyncServe, watchTask
);
I have googled a lot, but i am stuck. Please help me.
Part of the problem is you are watching the same directory that you are storing your js files in:
// Javascript Task
function jsTask() {
return src(`${source}/js/scripts/*.js`)
.pipe(terser())
.pipe(dest(`${source}/js/scripts/`));
}
So you send the files to ${source}/js/scripts/ but you are watching that location in your watch task: 'assets/js/**/*.js'. So any change in that location starts the process all over again.
Store you minified js files someplace else than the same directory you are watching for changes.
I have a js linting task:
js-lint.js
import eslint from 'gulp-eslint';
import gulp from 'gulp';
import util from 'gulp-util';
import config from '../config';
gulp.task('js-lint', (callback) => {
gulp
.src(config.js.lint)
.pipe(eslint({ envs: ['browser'] }))
.pipe(eslint.format())
.on('end', callback);
});
This and other tasks are used in my main gulpfile like so:
gulpfile.babel.js
gulp.task('build', (callback) => {
runSequence(
'clean',
'js-lint',
'scss-lint',
[
'fonts',
'images:production',
'js:production',
'scss:production',
'svg-sprite:production',
],
callback,
);
});
The build task runs clean and js-lint (which passes) but then stops the runSequence. If I comment out the usage of js-lint the build completes as expected.
I am not using eslint.failAfterError() and the linting is working correctly as expected. So why does the process stop?
I am using browserify and babel to compile and bundle my react app. The files from client/ are bundled up into a single file static/bundle.js. But I use a relative import which seems to not be handled correctly.
Here's my file structure
client/
components/
main.js
App.js
static/
bundle.js
gulpfile.js
and here's my gulpfile and the offending import
// client/App.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import App from './components/main.js';
render(
<App />,
document.getElementById('root'),
);
// gulpfile.js
var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
gulp.task('build', function() {
browserify({
entries: 'client/App.js',
extensions: ['.js'],
debug: true
})
.transform(babelify, {presets: ['es2015', 'react']})
.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest('static'));
});
The problem is the line import App from './components/main.js';.
When I look in static/bundle.js, there is a line var _main = require('./components/main.js');, which doesn't make sense because relative to bundle.js there is no ./components/main.js. That was defined relative to client/App.js.
Does browserify not handle such things and is there another tool I should be using in addition, or am I doing something else incorrect?
You have to add paths to your browserify options. If you do not add that browserify doesn't know where to look for to find your module.
module.exports = function(grunt){
grunt.initConfig({
browserify: {
options:{
browserifyOptions: {
// ...
paths: [
'./node_modules',
'./client'
]
}
},
// ...
},
// ...
});
}
This was an issue before they solve it.
Right now, only my app.js and the files that I use inside it are being bundled. I want the files inside my libs to also be bundled together into that same js file. Here is my folder structure inside my js folder:
.
├── app.js
├── components
└── libs
└── materialize.min.js
And here is my gulpfile where I'm bundling them all together:
import gulp from 'gulp'
import source from 'vinyl-source-stream'
import buffer from 'vinyl-buffer'
import browserify from 'browserify'
import babelify from 'babelify'
import uglify from 'gulp-uglify'
import watchify from 'watchify'
const jsDirs = {
src: './client/js/app.js',
dest: './dist/js'
}
function buildBundle(b) {
b.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest(jsDirs.dest))
}
gulp.task('scripts', () => {
let b = browserify({
cache: {},
packageCache: {},
fullPaths: true
})
b = watchify(b.transform(babelify))
b.on('update', () => buildBundle(b))
b.add(jsDirs.src)
buildBundle(b)
})
gulp.task('default', ['scripts'])
Is there any way to include my libs js files which aren't being used by app.js?
you should be able to call b.require(path) multiple times. (that's how I do it for mine)
Something like :
import gulp from 'gulp'
import source from 'vinyl-source-stream'
import buffer from 'vinyl-buffer'
import browserify from 'browserify'
import babelify from 'babelify'
import uglify from 'gulp-uglify'
import watchify from 'watchify'
const jsDirs = {
src: './client/js/app.js',
dest: './dist/js',
requires: [
'./libs/materialize.min.js',
['./libs/whatever.js', 'whatever']
]
}
function buildBundle(b) {
b.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest(jsDirs.dest))
}
gulp.task('scripts', () => {
let b = browserify({
cache: {},
packageCache: {},
fullPaths: true
});
b = watchify(b.transform(babelify))
[].concat(jsDirs.requires || []).forEach(function (req) {
var path = req,
expose = null;
if (typeof path !== 'string') {
expose = path[1];
path = path[0]
}
b.require(path, expose ? { expose: expose } : {});
});
b.on('update', () => buildBundle(b))
b.add(jsDirs.src)
buildBundle(b)
})
gulp.task('default', ['scripts'])
this also let you expose the lib for futur requires