Skip to content
This repository has been archived by the owner on Feb 10, 2019. It is now read-only.

Thoughts on approach #2

Open
Flet opened this issue Jan 8, 2015 · 13 comments
Open

Thoughts on approach #2

Flet opened this issue Jan 8, 2015 · 13 comments

Comments

@Flet
Copy link
Collaborator

Flet commented Jan 8, 2015

Thanks @ericelliott for spinning up this repo.

Ever since I read the issue on cloverfield regarding task runners I've been thinking about how this could be done. I created a gist that covers these thoughts here:
https://gist.github.com/Flet/ce3d94c2216e88d2fcc7

I understand that some of the ideas deviate a bit from your initial concept. Does any of this match your vision for this repository?

@ericelliott
Copy link
Owner

Let's bring discussion here... for reference:

Creating a new Task Runner Example

README.MD

Every task runner should have a README.MD file with the following sections:

  • Overview
    • Explain the focus/goals of the task runner and include links to resources and tutorials.
  • Highlights
    • Describe all the things that this task runner is known for being very good at doing.
  • Considerations
    • Describe the tasks/situations not suited for this task runner. This should include any special cases, incompatiblities, or weak points that should be considered.
    • It can be tough to point out the problems in the tools that you love, but please be as honest and objective as possible.

Tasks

Your task runner example must implement all of the tasks below. Each task should be mapped to an npm script prefixed with todotasks:in the package.json file.

Example package.json:

{
  "name": "todotasks-template-gulp",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "todotasks:lint": "gulp lintme",
    "todotasks:dev": "gulp watchmystuff"
  },
  "author": "",
  "license": "ISC"
}

(((With these mappings, we can create a scripts to measure and validate each task runner example. Validation could be part of the acceptance of PRs... Metrics could include things like timings for tasks and number of dependencies. )))

todotask:clean
Delete all files in the dist directory.

todotask:lint
Run eslint on all js files in the src/plainjs directory using thje .eslintrc file included in the template.

todotask:stylus
Use stylus to compile /src/stylus/*.styl and output to /dist/stylus.css

todotask:sass
Use none-sass to compile /src/css/*.scssand output to /dist/sass.css.

todotask:uglify
Take all JavaScript from /src/plainjs/*and generate a single concatenated+uglify'd file at dist/ugify.js. Please use uglfy for this task.

If you need to write the concatenated file to the filesystem before uglifying, write it to dist/concat.js.

todotask:transpile
Take all JavaScript from src/es6/* and transpile all files to es5. Output a single concatenated file to dist/es6.js.

todotask:browserify
Use browserify to generate dist/browserify.js from the file src/commonjs/app.js

todotask:webpack
Use webpack to generate dist/webpack.js from the file src/commonjs/app.js

todotask:build
This task should perform all of the above tasks in order. Note that this should use the task runners own internal task references (do not use the todotask:*npm scripts).

todotask:dev
This is the most complicated task. It should watch src/plainjs for changes and when a change is detected do the following:
- run eslint against all files insrc/plainjs and display any errors to stdout. Linting errors should not stop this task.
- rebuild a concatenated+uglify'd file at dist/ugify.js. To make this task fast, strive to rebuild only what needs to be rebuilt.

(((other potential tasks to add

  • sprite generation?
  • smoke tests?
  • image compression?)))

WIP Notes

Potential repository structure:

├── CONTRIBUTING.md
├── package.json
├── README.md
├── scripts
│   ├── generate-metrics.js //analyze all examples
│   └── validate-task-runner.js // validate an example
├── template // copy this dir for new examples
├── todotask-blah
├── todotask-grunt
└── todotasks-gulp

template - this is the default set of files to use whne creating a new task runner example. As described in the tasks above, the files are quite arbitrary (instead of being a real project) in order to keep things even simpler. It may still be a good idea to include a fully working app in each example as well... maybe a todomvc directory where we ask for a fully functional example that is not part of the metrics and is loose on requirements to give some freedom. Thoughts on this?

generate-metrics.js - for each task runner example, capture a series of metrics and spit out a little report. Can be pretty quick/dirty
- timings for build task
- analyze package.json and count required dev dependencies

validate-task-runner.js -- this would be a series of tests that would ensure the example meets the requirements. It can start out simply as a script that runs npm run todotask:build then verifies that all the output files exist. It could evolve from there as needed

@ericelliott
Copy link
Owner

Notes:

Kill todotasks: prefix. All scripts should be todotasks, so a todotasks prefix is not needed, and only adds typing.

Kill stylus - only one css transform task is needed. This isn't about picking which css preprocessor is best. It's about getting a general overview of which taskrunner is best suited for a tech-agnostic general purpose build system.

Kill transpile.

Kill webpack.

Again, this is about general purpose build systems, not about specific tech implementations. We'll look at webpack vs browserify elsewhere.

What's the purpose of these?

├── todotask-blah
├── todotask-grunt
└── todotasks-gulp

Where do we store implementations?

I think it would be instructive to have a place for them so that we can automatically build a website similar to TodoMVC from this repo. Similar to:

├── template // copy this dir for new examples

@Flet
Copy link
Collaborator Author

Flet commented Jan 8, 2015

Kill todotasks: prefix

The purpose of the todotask: prefix was to differentiate between the aliases needed for potential instrumentation and npm scripts required by the implementation For instance, if npm is the implementation, there could be some clash between the script names. I envision the package.json in the template directory would have these pre-typed with empty values.


Kill stylus
Kill webpack

Sure, fair enough. The thought here was to provide simple examples for a few common preprocessors/tools that users might want to use. Today a large user base is going to be using either straight concatenation/uglify, browserify, or webpack, so showing simple examples for these may be of benefit. This is part of the difference in vision I suppose. I'm fine with eliminating them.


Kill transpile

This was added as a direct response to a bullet found "The Challenge" section in this repo's README:

  • Example that transpiles from ES6 or CoffeScript, configurable to do so with or without sourcemaps
    Its an interesting task that can be implemented in different ways.

If its not considered vital it can certainly be removed.


What is the purpose of these?

These are supposed to represent directories of implementations committed to the repo. I'm fine wilth having a implementations directory to hold these if you want to keep the root clean.

@Flet
Copy link
Collaborator Author

Flet commented Jan 8, 2015

Additional requirements for new implementations:

  • Any dependencies required for the task runner should be listed in the devDependencies section of the package.json. Do this manually or via command line: npm install somedep --save-dev
  • If there are global installs required they should be installed automatically via a postinstall npm script. Example:
{
  "name": "todotasks-my-favorite-task-tool",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "postinstall":"npm install -g grunt foo bar",
// ...other things...
  },
  "author": "",
  "license": "ISC"
}

@ericelliott
Copy link
Owner

For instance, if npm is the implementation, there could be some clash between the script name

I think a more concrete example would be good here. I still have no idea why any script would not fall into the prefixed category.

The thought here was to provide simple examples for a few common preprocessors/tools that users might want to use.

We'll cross that bridge once we make a decision for Cloverfield. For now let's keep the barrier to providing example configs as low as we can.

This was added as a direct response to a bullet found "The Challenge" section in this repo's README:

Yeah, I don't think we should require that. Let's keep the barrier low.

I'm fine wilth having a implementations directory to hold these if you want to keep the root clean.

Yeah, let's do the implementations directory. =)

If there are global installs required they should be installed automatically via a postinstall npm script.

I'd prefer to call out global requirements in the implementation's README. We don't want to go installing stuff globally willy-nilly. Better to make those steps clear and explicit.

@Flet
Copy link
Collaborator Author

Flet commented Jan 8, 2015

Here is a snippet from a package.json I have with npm as the build tool:

"scripts": {
    "clean": "rimraf dist/*",
    "prebuild": "npm run clean -s",
    "build": "npm run build:scripts -s && npm run build:vendor && npm run build:styles -s",
    // more stuff
}

There is some overlap in names, which could cause some confusion or force the implementation to change its names to something less intuitive. Using a prefix means less potential for intruding on the implementation...

Taking a less scientific (and a more reality based) approach, npm is probably the only implementation where this would be a concern. So, we can dump the prefixes. 😄

I'd prefer to call out global requirements in the implementation's README
installing stuff globally willy-nilly

I can get behind this. It would still be convenient to be able to install any required globals via script, especially if we want to eventually automate the gathering of metrics/timings.

What if it was a script that had to be manually run? Maybe installglobals or something?

@ericelliott
Copy link
Owner

"build": "npm run build:scripts -s && npm run build:vendor && npm run build:styles -s"

Couldn't that be rewritten as:

"compile:js": "uglify",
"compile:vendor": "vendor",
"compile:styles": "sass",
"build": "npm run compile:js && npm run compile:vendor && npm run compile:styles"

And what does this have to do with prefixing with todotasks? If we automate verification, we'll just loop over an array of stuff that are todo tasks and only call those tasks, e.g.:

var todoTasks = ['dev', 'build', 'test'];
todoTasks.map(function (task) {
  // call task here
});

Right? It doesn't matter if there are extra tasks. We'll just ignore them. ;)

@Flet
Copy link
Collaborator Author

Flet commented Jan 13, 2015

Re: prefix
Yes things should work out fine with no prefix

So we have some good ideas with good editorializing here... We should probably reconcile this with the original text and commit it to this repo.

I'm happy to give it a shot tonight. Would this make sense to commit as CONTRIBUTING.md?

@ericelliott
Copy link
Owner

Yeah, if you want to add more detail about contributing that would be great. For now I've updated some getting started instructions in #3.

@ericelliott
Copy link
Owner

Did you want to take a closer look at updating the docs? I think we've got the important functionality, required tasks, etc... merged into the base example and the npm example, now.

@ericelliott
Copy link
Owner

Take a look at this PR: #8

Does that look like a good implementation for CSS?

I changed it so that the tests run last, because some browser tests may rely on CSS to pass.

@Flet
Copy link
Collaborator Author

Flet commented Jan 14, 2015

yeah looks good to me :)

@ericelliott
Copy link
Owner

Thanks! =)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants