Skip to content

Speed-up the development build #1432

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mgechev opened this issue Oct 5, 2016 · 2 comments
Closed

Speed-up the development build #1432

mgechev opened this issue Oct 5, 2016 · 2 comments

Comments

@mgechev
Copy link
Owner

mgechev commented Oct 5, 2016

Problem

Recently, while using the seed, I had to create a task which execution takes 5s. It is for svg sprite creation and compression but it was triggered on any file change. This is a lot for dev build since it blocks everything else, so the livereload cannot refresh the browser until the execution of the slowest task completes. I thought what we can do and with the current stateless task management (which is great but a bit limiting) there was no right way to approach.

Proposal

I was thinking that we can have a global state, which is mutated by utils/seed/watch.ts. So for instance:

export function watch(taskname: string) {
  return function () {
    let paths:string[]=[
      join(Config.APP_SRC,'**')
    ].concat(Config.TEMP_FILES.map((p) => { return '!'+p; }));

    plugins.watch(paths, (e: any) => {
      changedFiles.add(e.path);
      runSequence(taskname, () => {
        changedFiles.clean();
        notifyLiveReload(e);
      });
    });
  };
}

Later in the individual tasks, based on the file type we can check if any of the changed files requires their activation and can be skipped otherwise. For instance:

// build.js.dev
export = (done: any, filesChanged: string[]) => {
  if (hasTypeScriptFile(filesChanged)) {
    return gulp.src(...)
           .pipe(ts())
           .pipe(gulp.dest(...));
  } else {
    done();
  }
};

We can extend this even further by exporting not only a single function but a task object which processes only tasks of given type and/or has any other activation preconditions:

type FileType = RegExp;

interface ITask {
  precondition(files: string[]);
  processFiles?: FileType[];
  run(done: any): GulpStream | any;
}
const task: ITask = {
  precondition(files: string[]) {
    // decide if it should be activated
  },
  processFiles: [/\.ts$/],
  run(done) {
    // ...
  }
};

By default given task will be executed in all cases.

In order to keep the code DRYier, it'll be best to move the filtering logic in the task runner in tasks_tools.ts.

Basically it'll be a type of a chain of responsibility with inversion of control, because the tasks are not the ones which decide if the rest of the tasks in the chain should be executed.

@Bigous
Copy link
Contributor

Bigous commented Oct 6, 2016

In this case, the clean and livereload can be notified only if something that matters changes. Good.

@mgechev
Copy link
Owner Author

mgechev commented Oct 9, 2016

PR coming today.

mgechev added a commit that referenced this issue Oct 9, 2016
In dev executes tasks only when a specific file type has changed.
Fix #1432.
mgechev added a commit that referenced this issue Oct 9, 2016
In dev executes tasks only when a specific file type has changed.
Fix #1432.
mgechev added a commit that referenced this issue Oct 9, 2016
In dev executes tasks only when a specific file type has changed.
Fix #1432.
mgechev added a commit that referenced this issue Oct 9, 2016
In dev executes tasks only when a specific file type has changed.
Fix #1432.
mgechev added a commit that referenced this issue Oct 10, 2016
In dev executes tasks only when a specific file type has changed.
Fix #1432.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants