component-bundle icon indicating copy to clipboard operation
component-bundle copied to clipboard

standalone attribute in component.json?

Open matchdav opened this issue 11 years ago • 12 comments

I want to build some of the modules as standalones, but there doesn't seem to be an easy way to do declare standalone names for each bundle; I would like to be able to declare the standalone names in component.json, like

{
"local":["robert","stannis"],
"standalone":{
  "robert":"DeadKing",
  "stannis":"IncumbentKing"
}
}

so that they can be exported to anywhere.

I realize this is probably not a great pattern to encourage, but it does provide more flexibility, I think.

matchdav avatar Mar 24 '14 00:03 matchdav

Well, the --standalone option doesn't allow you to change the name of your modules, but it will build your modules in their own standalone file, using their name as what is exported (unless --standalone some_other_name is provided).

I'm not sure I understand the use case here. If your module is called "robert", why wouldn't it be called "robert" when it's built in standalone mode?

stephenmathieson avatar Mar 25 '14 18:03 stephenmathieson

I have a base module called 'experiment' basically representing the data model. 'experiment-edit' and 'experiment-render' both extend 'experiment'. I want 'Experiment', 'ExperimentEdit' and 'ExperimentRender' as my exportables.

matchdav avatar Mar 25 '14 19:03 matchdav

Is this more like a plugin use case? Like, transform the name using an inflector?

matchdav avatar Mar 25 '14 19:03 matchdav

I believe this is doable with the current software, but you'll break away from the lowercase naming convention:

{
  "name": "your-thing",
  "paths": ["lib"],
  "local": [
    "Experiment",
    "ExperimentEdit",
    "ExperimentRender"
  ]
}

You'll just have to rename your components to match. I know this isn't ideal, but it'd likely work.

My original thought here was a plugin, but I'm not sure how it'd work. Thoughts?

I'm also thinking about how totally useless --standalone <name> is. What if we changed --standlone to take a name map (or added a new argument all together)? We could do something like:

$ component-bundle --standalone "{ experiment: Experiment, experiment-edit: ExperimentEdit, ...}"

/cc @yields have any ideas here?

stephenmathieson avatar Mar 25 '14 19:03 stephenmathieson

@stephenmathieson IMHO at this point you would want to use builder directly, it makes it extremely simple :D

@matchdav just curios if "expirement-render" renders the expirement, why not have "expirement-boot" and render the expirement there, why do you want them exported ?

yields avatar Mar 25 '14 20:03 yields

Just using builder directly makes sense, thats true.

stephenmathieson avatar Mar 25 '14 20:03 stephenmathieson

@yields I understand that's a better way to do it, but I'm reorganizing another monkey's code and it's kind of a stop-gap TBH. I just don't want the current namespaces to break.

Back to the point it does seem to me that if the command line lets me set a flag, there should be a corresponding option in the package build options, especially when it's a batch operation like this, and it seems like it should be a simple patch, check keys(pkg.standalone) against pkg.local, grab the val for the key, set the flag, done.

matchdav avatar Mar 25 '14 23:03 matchdav

I understand that's a better way to do it, but I'm reorganizing another monkey's code and it's kind of a stop-gap TBH. I just don't want the current namespaces to break

makes sense, but i don't think it's a good idea to add this feature especially because it's a stop-gap / fix for old code.

i think you are much better of just appending <script src=rename.js></script> and rename all the expirement-edit etc.. to whatever you need.

yields avatar Mar 25 '14 23:03 yields

So this is how I'm doing it,

module.exports = function (builder) {
    var standalone = builder.config.standalone,
    standalones = Object.keys(standalone),
    name = builder.local(),
    globalName = (standalones && standalones.indexOf && standalones.indexOf(name) > -1)? standalones[name] : false,
    expose = (globalName) ? '\nvar ' + globalName = ' = require(\''+name+'\');\n' : false;
    expose && builder.append(expose);
};

But it seems a bit shitty to have to do that when there's already a flag to fire the amd(js) build.

matchdav avatar Mar 26 '14 06:03 matchdav

For what it's worth, your plugin can be simplified quite a bit:

module.exports = function (builder) {
  var map = builder.config.standalone;
  var local = builder.local();
  var name = map[local];
  var js = name
    ? '\nvar ' + name + ' = require("' + local + '");\n'
    : '';
  builder.append(js);
};

I'm using a very similar plugin for autoboot-like behaviour in my bundles.

stephenmathieson avatar Mar 26 '14 12:03 stephenmathieson

Hmm. Upon testing, that gave me problems because

a) local is an object not a string b) the appended js lives within the module scope, not global, so it doesn't really ape standalone like I want it to. I suppose I could use the builder hooks to wrap it all in a self-executing anon func, but that seems even messier.

The amd method is private, and that's a perfectly OK decision, but I want to use it.

This is the patch I came up with.

https://github.com/matchdav/component-bundle/commit/f5db8ecb8fc9933f6c27affd977cd1e4e7ef0450 If you don't like it that's cool, I'll just use this fork until we're done refactoring on our end.

matchdav avatar Mar 26 '14 19:03 matchdav

a - yeah, noticed that. i obviously didn't test that :p b - what about 'window[' + name + '] = require("' + builder.config.locals[0] + '")'?

i don't think we'll take a patch for this, as it can be done with a plugin in just a few lines.

stephenmathieson avatar Mar 26 '14 23:03 stephenmathieson