Skip to content

Commit

Permalink
Add browserify and dependencies to script bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
Errec committed Aug 20, 2024
1 parent 06ebbd0 commit b4567e2
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 108 deletions.
115 changes: 66 additions & 49 deletions _gulp/combineTasks.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { parallel, series } from 'gulp';
import { readFile, writeFile } from 'fs/promises';
import { parallel, series, TaskFunction } from 'gulp';
import { browserSyncServe, createWatchTask } from './modules/buildEnvironment';
import { copyVendorCSS, createProjectFiles, createProjectStructure } from './modules/fileSetup';
import { confirmProjectDeletion, promptUser } from './modules/setupQuestions';
import { UserChoices } from './types';
import { deleteDirectory, fileExists } from './utils/fileSystem';
import { logger } from './utils/logger';

async function loadUserChoices(): Promise<UserChoices> {
try {
const { readFile } = await import('fs/promises');
const data = await readFile('_gulp/user-choices.json', 'utf8');
return JSON.parse(data);
} catch (error) {
Expand All @@ -25,33 +28,37 @@ async function createGulpTasks() {
const { cleanTask } = await import('./tasks/cleanTask');

const watchTask = createWatchTask(choices, {
styleTask: styleTask(choices),
scriptTask: scriptTask(choices),
markupTask: markupTask(choices),
imagesTask
styleTask: styleTask(choices) as TaskFunction,
scriptTask: scriptTask(choices) as TaskFunction,
markupTask: markupTask(choices) as TaskFunction,
imagesTask: imagesTask() as TaskFunction
});

const defaultTask = series(
cleanTask,
parallel(
styleTask(choices),
scriptTask(choices),
markupTask(choices),
imagesTask
),
browserSyncServe,
watchTask
);
const defaultTask: TaskFunction = (done) => {
return series(
cleanTask(),
parallel(
styleTask(choices),
scriptTask(choices),
markupTask(choices),
imagesTask()
),
browserSyncServe,
watchTask
)(done);
};

const buildTask = series(
cleanTask,
parallel(
styleTask(choices),
scriptTask(choices),
markupTask(choices),
imagesTask
)
);
const buildTask: TaskFunction = (done) => {
return series(
cleanTask(),
parallel(
styleTask(choices),
scriptTask(choices),
markupTask(choices),
imagesTask()
)
)(done);
};

return { defaultTask, buildTask };
} catch (error) {
Expand All @@ -60,34 +67,44 @@ async function createGulpTasks() {
}
}

export async function run() {
export async function setup(): Promise<void> {
try {
const { defaultTask, buildTask } = await createGulpTasks();

if (process.argv.includes('build')) {
buildTask((err?: Error | null) => {
if (err) {
logger.error(`Build failed: ${err.message}`);
} else {
logger.success('Build completed successfully');
}
});
} else {
defaultTask((err?: Error | null) => {
if (err) {
logger.error(`Development server failed: ${err.message}`);
} else {
logger.success('Development server started');
}
});
const projectExists = fileExists('src') || fileExists('dist');
if (projectExists) {
const shouldDelete = await confirmProjectDeletion();
if (!shouldDelete) {
logger.info('Project setup canceled. Exiting...');
return;
}
deleteDirectory('src');
deleteDirectory('dist');
}
} catch (error) {
logger.error(`An error occurred during execution: ${(error as Error).message}`);
process.exit(1);

const choices: UserChoices = await promptUser();

await writeFile('_gulp/user-choices.json', JSON.stringify(choices, null, 2));

createProjectStructure(choices);
createProjectFiles(choices);
copyVendorCSS(choices);

logger.success('Setup complete. Gulpfile has been generated.');
logger.info('Starting development server...');

const { defaultTask } = await createGulpTasks();
defaultTask((err?: Error | null) => {
if (err) {
logger.error(`Development server failed: ${err.message}`);
} else {
logger.success('Development server started');
}
});
} catch (error: unknown) {
logger.error(`An error occurred during setup: ${(error as Error).message}`);
}
}

run().catch(error => {
setup().catch(error => {
logger.error(`An error occurred: ${(error as Error).message}`);
process.exit(1);
});
19 changes: 13 additions & 6 deletions _gulp/modules/buildEnvironment.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { create as createBrowserSync } from 'browser-sync';
import { series, watch } from 'gulp';
import { series, TaskFunction, watch } from 'gulp';
import { UserChoices } from '../types';

const bs = createBrowserSync();
Expand All @@ -18,13 +18,20 @@ export function browserSyncReload(cb: () => void): void {
cb();
}

export function createWatchTask(choices: UserChoices, tasks: Record<string, () => void>) {
const stylePath = `src/${choices.style === 'Sass' ? 'sass' : 'scss'}/**/*.${choices.style === 'Sass' ? 'sass' : 'scss'}`;
const scriptPath = `src/${choices.script === 'TypeScript' ? 'ts' : 'js'}/**/*.${choices.script === 'TypeScript' ? 'ts' : 'js'}`;
const markupPath = `src/${choices.markup === 'Pug' ? 'pug' : 'html'}/**/*.${choices.markup === 'Pug' ? 'pug' : 'html'}`;
const imgPath = 'src/img/**/*';
interface Tasks {
styleTask: TaskFunction;
scriptTask: TaskFunction;
markupTask: TaskFunction;
imagesTask: TaskFunction;
}

export function createWatchTask(choices: UserChoices, tasks: Tasks) {
return function watchTask(): void {
const stylePath = `src/${choices.style === 'Sass' ? 'sass' : 'scss'}/**/*.${choices.style === 'Sass' ? 'sass' : 'scss'}`;
const scriptPath = `src/${choices.script === 'TypeScript' ? 'ts' : 'js'}/**/*.${choices.script === 'TypeScript' ? 'ts' : 'js'}`;
const markupPath = `src/${choices.markup === 'Pug' ? 'pug' : 'html'}/**/*.${choices.markup === 'Pug' ? 'pug' : 'html'}`;
const imgPath = 'src/img/**/*';

watch(stylePath, series(tasks.styleTask, browserSyncReload));
watch(scriptPath, series(tasks.scriptTask, browserSyncReload));
watch(markupPath, series(tasks.markupTask, browserSyncReload));
Expand Down
43 changes: 29 additions & 14 deletions _gulp/modules/gulpfileGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@ const { src, dest, watch, series, parallel } = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const autoprefixer = require('gulp-autoprefixer');
const cleanCSS = require('gulp-clean-css');
const babel = require('gulp-babel');
const terser = require('gulp-terser');
const browserify = require('browserify');
const babelify = require('babelify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const browserSync = require('browser-sync').create();
const imagemin = require('gulp-imagemin');
const rimraf = require('rimraf'); // Correct import of rimraf as a function
const del = require('del');
const plumber = require('gulp-plumber');
const sourcemaps = require('gulp-sourcemaps');
const gulpif = require('gulp-if');
const pug = ${choices.markup === 'Pug' ? "require('gulp-pug')" : 'null'};
const typescript = ${choices.script === 'TypeScript' ? "require('gulp-typescript')" : 'null'};
const tsify = ${choices.script === 'TypeScript' ? "require('tsify')" : 'null'};
const production = process.env.NODE_ENV === 'production';
function clean(cb) {
rimraf('dist', cb); // Correct usage of rimraf as a function
async function clean() {
await del(['dist']);
}
function styles() {
Expand All @@ -37,14 +42,24 @@ function styles() {
}
function scripts() {
return src('src/${choices.script === 'TypeScript' ? 'ts' : 'js'}/**/*.${choices.script === 'TypeScript' ? 'ts' : 'js'}')
.pipe(plumber())
.pipe(gulpif(!production, sourcemaps.init()))
${choices.script === 'TypeScript'
? '.pipe(typescript())'
: '.pipe(babel({ presets: ["@babel/preset-env"] }))'
}
.pipe(terser())
const b = browserify({
entries: 'src/${choices.script === 'TypeScript' ? 'ts' : 'js'}/main.${choices.script === 'TypeScript' ? 'ts' : 'js'}',
debug: !production,
})
.transform(babelify, {
presets: ['@babel/preset-env'],
extensions: ['.js', '.ts']
});
${choices.script === 'TypeScript' ? 'b.plugin(tsify);' : ''}
return b.bundle()
.pipe(source('main.js'))
.pipe(buffer())
.pipe(gulpif(!production, sourcemaps.init({ loadMaps: true })))
.pipe(dest('dist/js'))
.pipe(uglify())
.pipe(rename('main.min.js'))
.pipe(gulpif(!production, sourcemaps.write('.')))
.pipe(dest('dist/js'));
}
Expand Down Expand Up @@ -97,4 +112,4 @@ exports.default = series(clean, parallel(styles, scripts, markup, images), serve
`;

writeFile('gulpfile.js', gulpfileContent);
}
}
4 changes: 3 additions & 1 deletion _gulp/tasks/cleanTask.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import del from 'del';

export function cleanTask() {
return del(['dist']);
return function(cb: (error?: Error | null) => void) {
del(['dist']).then(() => cb()).catch(cb);
};
}
12 changes: 7 additions & 5 deletions _gulp/tasks/imagesTask.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { dest, src } from 'gulp';
import { dest, src, TaskFunction } from 'gulp';
import imagemin from 'gulp-imagemin';

export function imagesTask() {
return src('src/img/**/*')
.pipe(imagemin())
.pipe(dest('dist/img'));
export function imagesTask(): TaskFunction {
return function() {
return src('src/img/**/*')
.pipe(imagemin())
.pipe(dest('dist/img'));
};
}
2 changes: 1 addition & 1 deletion _gulp/tasks/markupTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import pug from 'gulp-pug';
import { UserChoices } from '../types';

export function markupTask(choices: UserChoices) {
return function () {
return function() {
return src(`src/${choices.markup.toLowerCase()}/**/*.${choices.markup === 'Pug' ? 'pug' : 'html'}`)
.pipe(plumber())
.pipe(choices.markup === 'Pug' ? pug() : plumber())
Expand Down
38 changes: 26 additions & 12 deletions _gulp/tasks/scriptTask.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import { dest, src } from 'gulp';
import babel from 'gulp-babel';
import plumber from 'gulp-plumber';
import browserify from 'browserify';
import { dest, TaskFunction } from 'gulp';
import rename from 'gulp-rename';
import sourcemaps from 'gulp-sourcemaps';
import terser from 'gulp-terser';
import typescript from 'gulp-typescript';
import uglify from 'gulp-uglify';
import tsify from 'tsify';
import buffer from 'vinyl-buffer';
import source from 'vinyl-source-stream';
import { UserChoices } from '../types';

export function scriptTask(choices: UserChoices) {
return function () {
return src(`src/${choices.script.toLowerCase()}/**/*.${choices.script === 'TypeScript' ? 'ts' : 'js'}`, { sourcemaps: true })
.pipe(plumber())
.pipe(choices.script === 'TypeScript' ? typescript() : babel({ presets: ['@babel/preset-env'] }))
.pipe(terser())
.pipe(sourcemaps.write('.'))
export function scriptTask(choices: UserChoices): TaskFunction {
return function() {
const b = browserify({
entries: `src/${choices.script === 'TypeScript' ? 'ts' : 'js'}/main.${choices.script === 'TypeScript' ? 'ts' : 'js'}`,
debug: true,
});

if (choices.script === 'TypeScript') {
b.plugin(tsify);
}

return b.bundle()
.pipe(source('main.js'))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(dest('dist/js'))
.pipe(uglify())
.pipe(rename('main.min.js'))
.pipe(sourcemaps.write('./'))
.pipe(dest('dist/js'));
};
}
10 changes: 5 additions & 5 deletions _gulp/tasks/styleTask.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { dest, src } from 'gulp';
import { dest, src, TaskFunction } from 'gulp';
import autoprefixer from 'gulp-autoprefixer';
import cssnano from 'gulp-cssnano';
import cleanCSS from 'gulp-clean-css';
import plumber from 'gulp-plumber';
import gulpSass from 'gulp-sass';
import sourcemaps from 'gulp-sourcemaps';
Expand All @@ -9,13 +9,13 @@ import { UserChoices } from '../types';

const sassCompiler = gulpSass(sass);

export function styleTask(choices: UserChoices) {
return function () {
export function styleTask(choices: UserChoices): TaskFunction {
return function() {
return src(`src/${choices.style.toLowerCase()}/**/*.${choices.style.toLowerCase()}`, { sourcemaps: true })
.pipe(plumber())
.pipe(sassCompiler({ indentedSyntax: choices.style === 'Sass' }))
.pipe(autoprefixer())
.pipe(cssnano())
.pipe(cleanCSS())
.pipe(sourcemaps.write('.'))
.pipe(dest('dist/css'));
};
Expand Down
2 changes: 1 addition & 1 deletion _gulp/user-choices.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"script": "JavaScript",
"script": "TypeScript",
"style": "Sass",
"markup": "Pug",
"addNormalize": true,
Expand Down
Loading

0 comments on commit b4567e2

Please sign in to comment.