flovan / headstart

An automated front-end setup
https://flovan.me/headstart
MIT License
532 stars 31 forks source link

Add DUO, new package manager #34

Closed rovansteen2 closed 9 years ago

rovansteen2 commented 10 years ago

You said you didn't want to add Bower because of the way Headstart's folder structure is organized. Perhaps DUO (http://duojs.org/) is something that fits better. Looks very promising to me.

I'm not sure how to add it to Headstart, so I couldn't make a pull request. There is an example for Gulp here: https://github.com/duojs/duo/tree/master/examples/gulpfile

Would love to see a package manager added to Headstart.

flovan commented 10 years ago

The thing is, I am not convinced by what front-end package managers actually do that can't be done manually. There are a few advantages (the most prominent probably being the semantic versioning), but I still don't get how/why/when you'd actually have a benefit by using one. The libs I use a lot don't change very often, and if they do, I can just update them in my boilerplate. If I want to use a non-regular lib, I always have to check out the docs / repo, so I might as well download it. Can you give me an example of how this could help you specifically?

That being said, I see no problem in using this alongside Headstart, rather than included with. They offer a CLI themselves, so you can install it globally. This is just a concept (so not tested), but you could for example rename main.js to _main.js so the parser won't use it. Then use Duo to output the file without underscore:

duo assets/js/_main.js > assets/js/main.js

This way you can have Duo manage your dependencies and output the result as a file that Headstart can use.

rovansteen2 commented 10 years ago

Well, I can understand why you don't feel like using a package manager. But the main advantage for me is to have a really good control over the third party packages I use, and I'd rather do that with something that describes what I'm pulling in and automating that process instead of just dropping it in a folder and adding those files to git. Especially when I'm working in a team.

The solution you describe is not really practical because it would require you to run that command every time after you change something on top of running headstart.

Like I said I understand that you don't really need it but unlike Bower this doesn't really get in your way, but it does make Headstart more powerful.

flovan commented 10 years ago

You are probably right, and I am probably being stubborn, but another reason for not wanting to include this is because I don't want to bloat the codebase with features that may not end up being used a lot. I am already kind of regretting putting in Pagespeed Insights, and I don't want to slam in extra features just for the sake of having them.

I think this might be a good feature for Headstart 2, which is when I am planning to introduce more async stuff (such as Filament Group's loadCSS and loadJS, or maybe something like RequireJS or Browserify). Lots of front-end package managers have been popping up lately and they are getting better and more useful every day, so one of them is bound to end up in that release.

The next few 1.x releases will mainly be targeted at improving what's already there; mainly speeding up the entire thing and streamlining the Gulpfile (which is pretty massive and contains some eyebrow-raising methods to achieve certain features).

Headstart is, and always will be, an opinionated workflow, so if you would like to have it included sooner, please do fork away! It is all just open-source and there are great resources out there to help you get started with Gulp so you can make this into your own workflow. But if you can indulge me with your patience, I will do my best to give you something to look forward to. :ok_hand:

rovansteen2 commented 10 years ago

Sounds great! In the meantime I'll fork it and try out some things by myself. I'd love to contribute if I learn a bit more about Grunt. Thanks for your help.

flovan commented 10 years ago

No problem! I am going to reopen this, so when the time comes I can filter out the 2.0 milestone to see what I was going to put in. I will also be adding a CONTRIBUTE.md, probably by the next release, which will provide some pointers like whitespace, indenting etc.

Good luck with the fiddling around!

flovan commented 9 years ago

Note to self:

A great config file solution would be:

{
    [...]
    "dependencies": [
        "libs": {
            [...]
        },
        "dev": {
            [...]
        },
        "ie-head": {
            [...]
        },
        "ie-body": {
            [...]
        },
        "libs": {
            [...]
        },
    ]
}

And then being able to feed the dependencies array—as a whole or piece by piece—to Bower or DUO, so the downloaded libs can be written to specific directories (with or without something like main-bower-files).

Then again, no existing solution looks like it could handle that. So ... parsing the config, generating sub-configs, then getting the libs, grab the main files and move them and delete the setup files/folder(s) again? Sounds silly :neutral_face:

flovan commented 9 years ago

@MatthewMueller I mailed you a summary of my problem. I guess I could've just pinged like I just did, but what's done's done :grin:

Again, here's the config section for Duo that I'd like to use:

"duo": {
    "libs": ["jquery/jquery@1.11.2", "lodash/lodash@2.4.1", "ftlabs/fastclick@1.0.3"],
    "libs/dev": ["kayahr/console-shim"],
    "ie/head": ["aFarkas/html5shiv@3.7.2"],
    "ie/body": ["ie-behavior-span", "scottjehl/Respond@1.4.2"]
}

The goals is to loop over this, and create a file per section (4 in this case), and write each bundled file to the target folder (the key). My current attempt to do just that:

deps.lodash.forIn(settings.config.duo, function (value, key) {
    // Set the download dir
    duo.installTo('./duo-components/' + key);

    // Fetch individual components
    deps.lodash.each(value, function (module) {
        duo.include(module).run(function (err, src) {
            if (err) console.log('err', err);
            console.log('src', src);
        });
    });
});

EDIT: cc @yields

flovan commented 9 years ago

Success! But with a few gotchas... Poke @rovansteen.

First off, I don't find the configuration part to be more intuitive/easier than how it is right now (downloading manually):

.headstartrc (new config name for V2):

{
    [...],

    "duo": {
        "libs": ["jquery/jquery@1.11.2:dist/jquery.js", "lodash/lodash@2.4.1", "ftlabs/fastclick@v1.0.3"],
        "libs/dev": ["kayahr/console-shim@master:console-shim.js"],
        "ie/head": ["aFarkas/html5shiv@3.7.2:dist/html5shiv.js"],
        "ie/body": ["UmbraEngineering/Placeholder@master:src/ie-behavior-span.js", "scottjehl/Respond@1.4.2:dest/respond.min.js"]
    }
}

Just look at all those specific targets! If there is a release available, you need @x.x.x, or in the case of Fastclick, where the author used a different naming, you need @v.x.x.x. If the component doesn't contain a Bower config file, it makes things harder. You have to find the file you want, and add that too; :nested/folder/file.js. But then there are exceptions. jQuery has a Bower config, but it wasn't included in the build until I also pointed at it's location. And last, when there are no releases, and the file is in the root, you'd expect things to go down easy, but if there are multiple branches, you have to specify the branch @master or you might end up with a different one.

To me, that looks like a mighty list of big no-no's compared to just downloading the zip from Github.

But there's one more thing; all files get concatenated and exposed through a module, which means that you'll have to require the same lengthy strings again in your JS files, eg. var $ = require('jquery/jquery@1.11.2:dist/jquery.js');, OR they can be exposed through a global, eg deps.$ or deps.Fastclick, but that will likely result in conflicts as we're not dealing with one but multiple Duo builds.

</rant>

This needs further testing, maybe in a real situation. But that'll have to wait until I figure out some other stuff I want to change for this version. As far as automation is concerned, this might be easier once configured.