vigetlabs / blendid

A delicious blend of gulp tasks combined into a configurable asset pipeline and static site builder
MIT License
4.97k stars 685 forks source link

additionalTasks access rev-manifest #569

Open schellenbergk opened 5 years ago

schellenbergk commented 5 years ago

I've written an additionTask for critical css:

additionalTasks: {
    initialize(gulp, PATH_CONFIG, TASK_CONFIG) {
      var projectDestPath = path.resolve(process.env.INIT_CWD, PATH_CONFIG.dest); 
      var revManifestPath = path.resolve(projectDestPath, 'rev-manifest.json');

      gulp.task('criticalCss', function () {
        loadJsonFile(revManifestPath).then(json => {
          critical.generate({
            base: projectDestPath,
            src: 'index.html',
            inline: true,
            target: {
              html: path.resolve(projectDestPath,'index-critical.html'),
              uncritical: path.resolve(projectDestPath, json['css/app.css'].replace('.css', '-uncritical.css'))
            },
            minify: true,
            extract: true,
          });
        });
      });
    },
    development: {
      prebuild: null,
      postbuild: null,
    },
    production: {
      prebuild: null,
      postbuild: ['criticalCss']
    }
  }

however production.postbuild executes before replaceFiles task therefore it will never have access to rev-manifest.json: (productionTask)

gulpSequence(prebuild, tasks.assetTasks, tasks.codeTasks, rev, 'size-report', static, postbuild, 'replaceFiles', cb)

At this time, I can only get my criticalCss task to work only if I update productionTask to:

gulpSequence(prebuild, tasks.assetTasks, tasks.codeTasks, rev, 'size-report', static, 'replaceFiles', postbuild, cb)

Perhaps we could add another hook for this kind of case, something like:

gulpSequence(prebuild, tasks.assetTasks, tasks.codeTasks, rev, 'size-report', static, postbuild, 'replaceFiles', postreplacefiles, cb)
mikeebee commented 5 years ago

This addition would be fantastic.

Hey @schellenbergk, does your build task quit ok and show the ✨ Done in Xs message once it's finished? Mine doesn't unless I remove...

const critical = require('critical');

...from my task-config.js file (which I obviously need!), while all the tasks run as expected, once I see the message Finished 'build' after 11 s the task doesn't quit and I have to manually CTRL + C and I've no idea why.

I see this issue even without your suggested additions to the main package. Any ideas?

schellenbergk commented 5 years ago

Hi @mikeebee , Yes mine does exit with Done in Xs. Remember for this to work you would need to modify productionTask and move postbuild after 'replaceFiles' task. However, unless this feature gets implemented I've made a workaround outside of Blendid:

Create a file criticalCss.js with:

const critical = require('critical');
const fs = require('file-system');
const path = require('path');
const loadJsonFile = require('load-json-file');

const projectDestPath = path.resolve(process.env.PWD, 'public/');
const revManifestPath = path.resolve(projectDestPath, 'rev-manifest.json');

console.log('Critical CSS...');
fs.copyFile('public/index.html', 'public/index-uncritical.html', {
  done: function (err) {
    loadJsonFile(revManifestPath).then(json => {
      critical.generate({
        base: projectDestPath,
        src: 'index.html',
        width: 1300,
        height: 900,
        inline: true,
        target: {
          html: path.resolve(projectDestPath, 'index.html'),
          uncritical: path.resolve(projectDestPath, json['css/app.css'].replace('.css', '-uncritical.css'))
        },
        minify: true,
        extract: true,
      });
      console.log("Complete!");
    });
  }
});

Then modify your package.json and update build script to:

"scripts": {
    "start": "yarn run blendid",
    "build": "yarn run blendid build && node criticalCss.js",
    ...
mikeebee commented 5 years ago

Hi @schellenbergk, ah yes this works perfectly!

I wish I knew why the task won't quit when I'm using additionalTasks with critical. For my purposes, running a task on production.postbuild would be fine. I'll stick with your implementation for the time being, it's a better solution anyway, I just hate not knowing what the issue is.

Thanks again for your help, I would have been stuck otherwise!

schellenbergk commented 5 years ago

I'm glad I could help :)