TryGhost / Ghost

Independent technology for modern publishing, memberships, subscriptions and newsletters.
https://ghost.org
MIT License
46.74k stars 10.19k forks source link

Create shared lib for common assets #93

Closed JohnONolan closed 11 years ago

JohnONolan commented 11 years ago

At the moment jQuery lives in

core > client > assets > vendor > jquery > jquery.min.js

This isn't particularly useful - because with an incredibly common library like jQuery what we really want is to have it in a shared location where it can be used by both admin, as well as themes/plugins - both front and back end. (ala wp_enqueue_script)

There are several assets which this workflow applies to - so this probably needs to be properly considered / worked into the structure of the app.

JohnONolan commented 11 years ago

Yeah ok I made a mess. Let's not dwell on it.

tgriesser commented 11 years ago

An idea to consider eventually, would be to use a package manager to handle libraries - and programmatically call it behind the scenes when starting the application in development mode. In my own applications I have something along the lines of:

// index.js
// Sets the environment to `development`, unless otherwise specified.
var env  = (process.env.NODE_ENV || (process.env.NODE_ENV = 'development'));
var when = require('when');

var gruntCompile = function () {
  var dfd   = when.defer();
  var spawn = require('child_process').spawn;
  spawn('grunt')
    .on('error', function(e) {
      dfd.reject(e);
    })
    .on('exit', function () {
      dfd.resolve('Grunting Complete!');
    });
  return dfd.promise;
};

// Grabs & Compiles the assets to run in the app.
var assetFetch = function () {
  var dfd = when.defer();
  var _ = require('underscore');
  var bower = require('bower');
  var componentsJson = require('./bower.json');
  var componentsDir = fs.readdirSync('./components');

  if (_.keys(componentsJson.dependencies).length !== componentsDir.length) {
    console.log('Installing Updated Bower Components, please wait.');
    bower.commands
      .install()
      .on('end', function() {
        console.log('Finished Bower install.');
        dfd.resolve(gruntCompile());
      })
      .on('error', function (e) {
        dfd.reject(e);
      });
  } else {
    dfd.resolve(gruntCompile());
  }
  return dfd.promise;
};

when((env === 'development' ? assetFetch() : true)).then(function() {
  require('./app');
}, function(e) {
  console.log(e.stack);
});

Where the bower installs all the necessary scripts from bower.json, and the gruntfile concatenates them into separate files, and would minify them for production - and then runs a watcher script.

This is really quickly hacked together for my own purposes, but a more refined version of something like this could be really nice for clean dependency management and not including these files in version control or needing them in any specific directory to add them to a single file - we could specify a structure for developers to add assets that would be brought into the build system when the app starts.

ricardobeat commented 11 years ago

Looks like my comment disappeared.

Either bower or a variation of curl -# http://code.jquery.com/jquery.js > lib/jquery.js should resolve this. It makes more sense for it to be a grunt task, than to run on app initialization.

task 'install:deps', ->
    for source, dest of {
        "http://code.jquery.com/jquery.js"  : "jquery.js"
        "http://backbonejs.org/backbone.js" : "backbone.js"
        ...
    } then request(source).pipe(fs.createWriteStream('lib/' + dest))
tgriesser commented 11 years ago

Right, it'd could be a grunt task that you ran on app initialization (so you didn't have to remember to run grunt from the cli)... nothing we need to do for now though.

jgable commented 11 years ago

What's the status of this, is there a consensus on what is needed to be done?

JohnONolan commented 11 years ago

ghost/core/shared/ makes most sense to me as the actual location for this. Everything else... cc/ @ErisDS

ErisDS commented 11 years ago

The shared libraries should absolutely live in /core/shared. There are several we can share inc jQuery, underscore, moment, handlebars.

I would also like to look into sharing handlebars helpers between client and server - though I'm not sure how to do that and I will put that in a separate issue.

I want to make the best use of tools available like bower and grunt. I do think that this should be a grunt task - preferably part of grunt init i.e. a run-once task that you should never have to run again unless a dependency changes.

ErisDS commented 11 years ago

@jgable @tgriesser @ricardobeat anyone wanna call dibs on this one?

ricardobeat commented 11 years ago

o/ — Sent from Mailbox for iPhone

On Tue, Jul 16, 2013 at 1:03 PM, Hannah Wolfe notifications@github.com wrote:

@jgable @tgriesser @ricardobeat anyone wanna call dibs on this one?

Reply to this email directly or view it on GitHub: https://github.com/TryGhost/Ghost/issues/93#issuecomment-21052055

ricardobeat commented 11 years ago

Are we going to use shared as shared between client & server, as opposed to admin & frontend - meaning moving models/permissions/data somewhere else?

Should shared libs go in core/shared/vendor, core/shared/lib, or core/shared/*?

ErisDS commented 11 years ago

Yes, shared is now intended for things we can share between the client and server.

This issue refers to 3rd party libraries like jQuery, underscore & backbone only, and they should live in core/shared/vendor.

I'm not sure what you mean about moving models/permissions/data? The lasted version of Ghost has all those things in a folder called server. Perhaps you haven't done an update yet? You'll also need to do a git clean -f and delete the few leftover bits yourself after updating.

ricardobeat commented 11 years ago

oh, failed pull. now i got it :heart_eyes: