php — środowisko programistyczne Gulp skonfigurowane do tworzenia motywów WordPress
Powoli uczę się tworzenia niestandardowych motywów WordPress. Zauważyłem, że wiele osób używa gulp.js do automatyzacji wielu zadań, a teraz próbuję znaleźć „najlepszy” sposób skonfigurowania gulp.js dla lokalnych twórców motywów.
Na razie skonfigurowałem plik gulpfile.js do wykonywania następujących zadań:
- Kompresuj obrazy.
- Konwertuj obrazy do formatu .webp.
- Kompiluj pliki SaSS do CSS.
- Przetwarzaj pliki .js
- Inne zadania, takie jak oglądanie synchronizacji przeglądarki itp.
Poniżej znajduje się kod z mojego pliku gulpfile.js, ale przed jego opublikowaniem chciałem zadać kilka pytań na ten temat:
- Czy powinienem także wykonać jakąś obróbkę plików .php?
- Czy przetwarzanie, które już skonfigurowałem, wystarczy?
- Wiem, że jeśli chcę, aby mój kod korzystał z plików .webp, muszę użyć znacznika i HTML… Ale jak mogę poinformować gulp.js, aby automatycznie dodawał plik .webp podczas kompilacji plików?
- Czy istnieje sposób, aby poinformować pliki .php, np. plikfunctions.php, aby automatycznie korzystał z przetworzonych plików CSS? Czy też muszę ręcznie zmieniać wszystkie funkcje kolejkowania itp.?
- Czy istnieje potrzeba skonfigurowania gulp.js do działania w trybie produkcyjnym? Podobnie jak na serwerze na żywo?
Mój plik gulfile.js:
'use strict';
/*
* IMPORTS: Gulp and other plugins for processing.
*/
import gulp from 'gulp';
import imagemin from 'gulp-imagemin';
import imageminWebp from 'imagemin-webp';
import extReplace from 'gulp-ext-replace';
import newer from 'gulp-newer';
import gulpSass from 'gulp-sass';
import * as dartsass from 'sass';
import sourcemaps from 'gulp-sourcemaps';
import postcss from 'gulp-postcss';
import autoprefixer from 'autoprefixer';
import deporder from 'gulp-deporder';
import stripdebug from 'gulp-strip-debug';
import uglify from 'gulp-uglify';
import browserSync from 'browser-sync';
import postcssAssets from 'postcss-assets';
import cssnano from 'cssnano';
import cssclean from 'gulp-clean-css';
import babel from 'gulp-babel';
import del from 'del';
import zipTheme from 'gulp-zip';
import calcFunction from 'postcss-calc';
import colormin from 'postcss-colormin';
import discardEmpty from 'postcss-discard-empty';
import discardUnused from 'postcss-discard-unused';
import mergeLonghand from 'postcss-merge-longhand';
import mergeAdjacentRules from 'postcss-merge-rules';
import minifyFontValues from 'postcss-minify-font-values';
import minifyGradients from 'postcss-minify-gradients';
import normalizePositions from 'postcss-normalize-positions';
import normalizeUrl from 'postcss-normalize-url';
import uniqueSelectors from 'postcss-unique-selectors';
import zIndex from 'postcss-zindex';
import size from 'gulp-size';
import plumber from 'gulp-plumber';
import gutil from 'gulp-util';
// gulp-notify - at the very end .pipe(notify({ title: 'Sass', message: 'sass task complete' }));
/*
* CONFIGURATION
*/
const config = {
themeDir: './', // Theme folder
proxyUrl: ' // Proxy url for browsersync
themeName: 'theme-name',
paths: {
src : './src/', // Base source folder path
build : './build/', // Base dile output folder path
fonts: config.paths.src + 'fonts', // Font files
images: { // Folders for raw images and output
src : config.paths.src + 'images/**/*.{jpg,jpeg,png,svg,gif}',
build : config.paths.build + 'images',
},
webp: { // Folder for raw images and output
src : config.paths.src + 'images/**/*.{jpg,png}',
build : config.paths.build + 'images/webp',
},
js: { // Folder for raw js and output
src : config.paths.src + 'js/**/*.js',
build : config.paths.build + 'js/',
},
sass: { // Folder for raw scss and cs output
src : config.paths.src + 'scss/**/*.scss',
build : config.paths.build + 'css',
}, // Zip source and destination
zip: {
src : themeDir, // the whole theme folder
build : themeDir + 'zip/' // put the compressed zip inside /zip/ folder
}
},
options: { // OPTIONS FOR PLUGINS
sass: { // sass plugin options
outputStyle: 'compressed',
// Where are the images taken from
imagePath: config.paths.images.src,
includePaths: [
// Where are font files taken from
config.paths.fonts,
],
precision: 8,
errLogToConsole: true,
noCache: true
},
size: { // Configuration for size plugin
gzip: true, uncompressed: true,
pretty: true,
showFiles: true, showTotal: false,
},
cssnano: { // Configuration for cssnano plugin
'preset': [
'cssnano-preset-advanced',
{
// Get rid of comments
'discardComments': {
'removeAll': true
}
}
],
},
postcssAssets: { // postcssAssets plugin options
loadPaths: [config.paths.images.src, config.paths.fonts],
basePath: config.paths.src,
baseUrl: `/wp-content/themes/${config.themeName}/`
},
browsersync: { // Browsersync plugin options
options: {
logLevel: 'debug', injectChanges: true,
proxy: proxyUrl, browser: 'Google Chrome',
files: config.paths.build + '**/*',
open: false, notify: true, ghostMode: false,
ui: {
port: 8001
}
},
src: [
config.themeDir + '**/*.php',
config.themeDir + 'scss/**/*',
config.themeDir + 'scss/js/**/*',
config.themeDir + 'scss/images/**/*'
],
},
zip: [
`${config.paths.zip.src}`,
'*',
`!${config.paths.zip.src + '/node_modules'}`,
'!src/{images,js,scss}',
'!src/{images,js,scss}/**/*'
]
}
};
/*
* ERROR HANDLING
*/
// Customize the error message, add beep sound once the error occurred
// ...plus adding colors to the error message which is useful identifying the error
const onError = function( err ) {
console.log('An error occurred:', gutil.colors.magenta(err.message));
gutil.beep();
this.emit('end');
};
// add this to each workflow...
// .pipe(plumber({ errorHandler: onError }))
// this will make sure gulp does not terminate itself when watching, when an error occours
/*
* TASKS: Copy new files and folders from scss to build
* If files are copied, created or moved into scss, copy them into build as well
* ...except the already made folders and their sub-folders
*/
gulp.task('copy', () => {
return gulp.src([config.paths.src,'!src/{images,js,scss,fonts}','!src/{images,js,scss,fonts}/**/*'])
.pipe(plumber({ errorHandler: onError }))
.pipe(dest(config.paths.build));
});
/*
* TASKS: Image Processing - using 'imagemin'.
*/
// images - Compress all images
gulp.task('images', () => {
return gulp.src(config.paths.images.src)
.pipe(plumber({ errorHandler: onError }))
.pipe(newer(config.paths.images.build))
.pipe(imagemin()) // compresses .gif, .svg, .png, .jpg
.pipe(gulp.dest(config.paths.images.build));
});
// webp - Convert .jpg and .png into .webp
gulp.task('webp', () => {
return gulp.src(config.paths.webp.src)
.pipe(plumber({ errorHandler: onError }))
.pipe(imagemin({
verbose: true,
plugins: imageminWebp({ quality: 70 }) // converts to webp
}))
.pipe(extReplace('.webp')) // rename file to .webp
.pipe(gulp.dest(config.paths.webp.build));
/*
.on('end', () => {
console.log('WebP Conversion Complete.');
});
*/
});
/*
* TASKS: Sass Compilation - using 'gulp-sass' and 'dart-sass'.
*/
// Choose which sass compiler to use (because gulpSass does not have a default compiler anymore).
const sass = gulpSass(dartsass);
// css - CSS and SASS processing
gulp.task('css', gulp.series('images', 'webp', () => {
return gulp.src(config.paths.css.src ) // Source files. Could be an array.
.pipe(plumber({ errorHandler: onError }))
.pipe(sourcemaps.init()) // Creates a sourcemap: Allows errors to show proper error line placement
.pipe(sass(config.options.sass)) // Compile scss/sass into css.}
.on('error', sass.logError)
.pipe(postcss([ // Autoprefixing for browser compatibility, prefixes.
postcssAssets(config.options.postcssAssets),
autoprefixer(), // add browser prefixes...
colormin(),
calcFunction(),
discardEmpty(),
discardUnused(),
mergeLonghand(),
mergeAdjacentRules(),
minifyFontValues(),
minifyGradients(),
normalizePositions(),
normalizeUrl(),
uniqueSelectors(),
zIndex(),
cssnano(config.options.cssnano), // compressing colors & removing comments, to discarding overridden at-rules...
cssclean(), // minify css
]))
.pipe(size(config.options.size)) // Output production CSS size
.pipe(sourcemaps.write()) // Finishes writting the sourcemap
.pipe(gulp.dest(config.paths.css.build))// Sending compiled file to destination.
}));
/*
* TASKS: JavaSript Processing
*/
// JavaScript processing
gulp.task('js', () => {
return gulp.src(config.paths.js.src)
.pipe(sourcemaps.init()) // allows errors to show proper error line placement
// .pipe(jshint())
// .pipe(jshint.reporter('default'))
.pipe(deporder()) // use comments to show what files this file is dependent on as imports
// .pipe(concat()) // for combining multyple .js files into one .js file
.pipe(babel({
presets: ['@babel/env']
})) // rewrites newer js to be compatible with older js
.pipe(stripdebug()) // Strip error/debug code
.pipe(uglify()) // renaming variables + minifying.
.pipe(sourcemaps.write())
.pipe(gulp.dest(config.paths.js.build))
});
/*
.jshintrc file
{
"undef": true, // Warns when you use a variable that was not declared.
"unused": true, // Warns when defining a variable and never use it.
"browser": true // Defines globals exposed by modern browsers, like navigator and document.
}
*/
/*
* TASKS: Zip or compress your theme folder files
*/
gulp.task('zip', () => {
return gulp.src(config.options.zip)
.pipe(plumber({ errorHandler: onError }))
.pipe(zipTheme(config.themeName + '-zip.zip'))
.pipe(gulp.dest(config.paths.zip.build))
});
/*
* TASKS: Run all tasks (except zip) at once instead of seperately
* You can now use gulp build to run the copy, js, and css tasks in parallel.
* Note images is a dependency of the css task, as we set it up early so we need not call it directly.
*/
gulp.task('build', gulp.parallel('copy', 'css', 'js'));
/*
* WATCH: Enable File Watching And Browsersync
*/
// browser-sync
const browsersyncInstance = browserSync.create();
gulp.task('browsersync', (done) => {
browsersyncInstance.init(config.options.browsersync.src, config.options.browsersync.options);
done();
});
// watch for file changes and run appropriate task
gulp.task('watch', gulp.series('browsersync', () => {
// copy changes
gulp.watch(config.paths.src, gulp.series('copy'));
// image changes
gulp.watch(config.paths.images.src, gulp.series('images'));
// webp changes
gulp.watch(config.paths.webp.src, gulp.series('webp'));
// CSS changes
gulp.watch(config.paths.css.src , gulp.series('css')).on('error', handleError());
// JavaScript changes
gulp.watch(config.paths.js.src, gulp.series('js'));
// php file changes
gulp.watch('**/*.php').on('change', browserSync.reload);
}));
/*
* TASK: Delete /build/ folder when starting development - Since old files are not deleted automatically
*/
gulp.task('clean', () => del([config.paths.build]));
/*
* DEFAULT: Do this when runing 'gulp' by default - runs an initial build and starts the watch task:
*/
gulp.task('default', gulp.series('clean', 'build', 'watch'));