WordPress

php — środowisko programistyczne Gulp skonfigurowane do tworzenia motywów WordPress

  • 5 stycznia, 2024
  • 8 min read
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ń:

  1. Kompresuj obrazy.
  2. Konwertuj obrazy do formatu .webp.
  3. Kompiluj pliki SaSS do CSS.
  4. Przetwarzaj pliki .js
  5. 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:

  1. Czy powinienem także wykonać jakąś obróbkę plików .php?
  2. Czy przetwarzanie, które już skonfigurowałem, wystarczy?
  3. 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?
  4. 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.?
  5. 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'));


Źródło

Warto przeczytać!  Co można, a czego nie należy robić przy rejestracji domeny