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

consider bringing back CLI build plugins #524

Open
Swatinem opened this issue Apr 7, 2014 · 18 comments
Open

consider bringing back CLI build plugins #524

Swatinem opened this issue Apr 7, 2014 · 18 comments

Comments

@Swatinem
Copy link
Contributor

Swatinem commented Apr 7, 2014

I kind of see the reasoning to distinguish between simple builds with the CLI and more complex ones that use plugins and need a build scripts.

But its just soooo inconvenient to copy-paste build scripts all over for things that could be done in 2 lines of shell.
Going down that road, one might just use gulp or even the highly redundant boilerplate heavy grunt.

@jonathanong
Copy link
Contributor

i'm not sure how to do this. the field each plugin acts on is important, and the way it is ordered with the default plugins matter as well.

i think if you wanted to do this right now, you would have to re-use all the default middleware manually and specify the fields:

component build
  --use-scripts es6modules
  --use-scripts js
  --use-json json
  --use-templates templates

etc.

plus, there are also custom options and such you would have to handle. there's just too many different dimensions, and it would end up being larger than just writing a JS file.

i'm trying to think of a way where you can just just create a js file that looks like:

exports.scripts = function (build) {
  build
    .use()
    .use()
    .use()
}

without returning anything, and set its path as an env variable or something.

@Swatinem
Copy link
Contributor Author

Swatinem commented Apr 7, 2014

As far as I understand, you have to define the default middleware manually as well in a build script, right? Thats one of the reason why it is so highly redundant and copy-pasty.

Its also that I might want to have two different builds, one with component-jade, one with component-jade + component-istanbul.
Then I would either have to do separate build files, or one which has option parsing (might be as simple as one argv) logic.

I just think make/shell is more convenient.

@jonathanong
Copy link
Contributor

the use-case isn't the problem. it's actually implementing it. you're trying to map a 1-2 dimensional option space to like a 5 dimensional option space, which is pretty difficult.

@casio
Copy link

casio commented May 18, 2014

+1 for bringing CLI plugins back

The way browserify was able to achieve this is really super convenient.
Also I think not having this option might hinder adoption quite heavily.

Does it make sense to just have specified --use-X middleware applied after the default stuff?
That should go a long way for lots of usecases.
Where it doesnt, people can still use the API in their own scripts, then.

@jonathanhefner
Copy link

I also thought the CLI option was convenient. But I was thinking, wouldn't it be more convenient to list the build plugins in component.json? That way you wouldn't have to bother with a shell script (or type them out each time), and they could even be downloaded / resolved the way dependencies are.

As for ordering and configuration options, what about the following:

  • Plugins specify a file name regex for which files / extensions they apply to. (This could be an exported function instead of a regex if more sophisticated logic is needed.)
  • Plugins transform file names / extensions in memory in addition to file contents
  • Plugins also specify if they're a post-processor or a pre-processor, i.e. whether they require valid canonical JS/CSS/etc
  • Post-processors are applied after the default plugins, in any order(?)
  • Pre-processors are applied in any order based on the current in-memory file name, but only once per file
  • If these basic ordering constraints are insufficient (e.g. there are multiple ES6 plugins that operate on *.js but need to be applied in a specific order), a "meta" plugin can be created which is just a normal plugin component that delegates to other plugins in a specific order. It could look like the simplified build script that @jonathanong mentions above.
  • If any extra configuration options are necessary, they can be specified in a hash alongside the plugin version number in the consumer project's component.json

@tj
Copy link
Contributor

tj commented Jun 13, 2014

setting them up in the manifest might be reasonable, still very leaky compared to scripting but less leaky than via the CLI at least

@jonathanhefner
Copy link

Leaky as in leaky abstraction? I suppose the non-deterministic ordering makes it that way. But having plugins be components which can, themselves, depend on / delegate to other plugin components provides a DRY way of composing deterministic builder pipelines. Then, being able to specify at least a root plugin (pipeline) in the manifest could give people the brevity they want. (Said root plugin could be remote or local, allowing people to reuse existing published pipelines, or switch to customized local ones with zero friction.)

Having a single combined pipeline (selected over by regex), instead of separate pipelines for each asset type, also simplifies things, IMHO.

@tj
Copy link
Contributor

tj commented Jun 13, 2014

yeah just leaky as far as logic you can apply and how and what options you pass etc. for simple cases cli/json are nice

@Paulmicha
Copy link

I'm currently assessing the feasability of using Component (for me and my team) as the ONLY tool for structuring, reusing and compiling CSS across different projects (using SuitCSS, at least with Rework & minification)

Use case : Build SuitCSS Components & custom ones with Rework + minification
Caveat : having to use an additional custom build script every time is a potential deal breaker

Having no scripting for simple cases is less error-prone, less time-consuming - and of course, lowering the perceived difficulty of this tool is a critical factor of its immediate adoption.

"list the build plugins in component.json"
-> Sounds better than the now mandatory additional custom build script, +1

@anthonyshort
Copy link
Contributor

@Paulmicha We're currently using Component for all of our CSS, and have been for a while, with a Makefile to run Myth over the built file and using Suit for some utils. Works a treat and highly recommended. Just use a makefile and everything is nice and simple.

@Paulmicha
Copy link

"with a Makefile to run Myth" -> this is an extra tool, and the people I will try to convince will probably just hear "it works if you also use this like this and..." and then give up.

@anthonyshort
Copy link
Contributor

Well I mean you'll probably have some sort of build tool, and in that you'll probably be running a minifier over it, so just run Myth/Rework over it too :)

@Paulmicha
Copy link

"you'll probably have some sort of build tool" -> No : that's the whole point, I think.
Besides, that's out of the scope of this issue - "bringing back CLI build plugins" (and/or "list the build plugins in component.json") : the simplistic use case I added to this discussion (build CSS-only components like SuitCSS with Rework & minification) is quite different than building an entire app (http://blog.kewah.com/2014/build-a-web-app-with-component/).
I know that this perspective is perhaps a little edge-case, but I believe there is value in making possible this minimalistic use of Component, where it does this only one thing really well - so it could be used on any kind of projects.

@jasonkuhrt
Copy link
Member

I basically agree that --use is a legitimate feature. I-think-but-cannot-proove that a non-trivial quantity of use-cases benefit from it. It just makes intuitive sense, but I agree with everyone that good interface behaviour here is complicated (harder than complex). I don't think the current programatic .use(...) is even right yet so that precludes any serious discussion of --use for me.

@visionmedia As far as the passing of options goes that does not seem like that hard of a problem to solve. Either improve the CLI parser with --use foobar 'key=value, key=value or we create a way for field names in component.json that match the plugin to be applied to said plugin at --use time. In fact both might be worth supporting. Lots of ways to make this work and work well.

@jonathanhefner
Copy link

I've been giving some thought to how make this feature less magical / easier to reason about. What about something like this inside component.json:

{
  "build": {
    "myFile1.js": ["plugin1", "plugin2", "plugin3"],
    "myFile2.js": ["plugin2"],
    "myFile3.css": ["plugin7", "plugin8"],
    // etc
  },
  "plugins": {
    "plugin2": { /* configuration */ },
    "plugin7": { /* configuration */ }
    // etc
  }
}

The downside of this is that, with less magic, it's duplicating build script functionality. The upside is that it's friendlier / easier for common cases.

@jasonkuhrt
Copy link
Member

@jonathanhefner generally I like, seems quite usable, and multiple bundles fall out of this super simply, no? I assume that all plugins would first check node_modules/.bin/* and then only if not found there look up the bin path.

@stephenmathieson
Copy link
Contributor

rather than adding a bunch of weird stuff to component.json, what about builder.json? we could possibly make component-build(1) respect it..

@jasonkuhrt
Copy link
Member

@stephenmathieson Hm not against the idea at all but another file to specify a few fields is not great for the end user. Too much modularity for the end goal in a lot of use cases I would imagine.

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

9 participants