Best practice for sharing ES6 code between a node server and an Ember client

Im trying to figure out how to reuse some code in a project without having one version for Ember and another for node.

The code:

  • Is written using ES6 syntax.
  • Has some npm dependencies.
  • Is not tied (or any of its dependencies) to any node server side API (like child processes, file I/O, etc).

What i would like to do is import someFunction from 'lib/someFunction' directly in my Ember code, same as in node (using Babel).

Is there any recommended way to do this?

4 Likes

I would suggest giving a try to JSPM which is a package manager capable of loading node modules (commonjs) as well as modules in other formats (ES6, AMD, global). Also you can take a look at my blog post explaining how to set up things with Ember and JSPM. Of course, if you choose to use JSPM, you’ll not be able to use ember-cli and therefore you may need to do some extra work with gulp etc to build a production version of your app. But I think you will not have problems importing most of the ember-cli addons with JSPM if need them.

P.S. I am not an active ember-cli user and therefore I cannot say for sure if ember-cli is capable of importing node modules with node dependencies into an app if they are not packaged as ember-cli addons. Might be.

P.P.S. webpack is an alternative to JSPM that is worth mentioning in my opinion.

Thanks for your reply; ive read your post and some info about these package managers and they look very promising. However as you said, they do not work with Ember CLI, and (as far i know) seems that it will be a core part of Ember development in a near future.

Personally, i like Ember CLI because it creates an integrated standard solution for many problems, and after all, thats the reason for why im using the Ember framework (web development fragmentation is extremely high in my opinion). So i will try to stick with it for the time being.

I hope Ember CLI may implement some way of importing npm packages without using a prefix (because then its necessary to copy the reusable code, and patch it every time it changes) or allow to switch the default RequireJS with Browserify.

@sarasa So have you found a solution?

@Alex_Rudenko Not the “best practice” solution (i did not have time for the involved project, so i resorted to just get it working); i assigned a global reference to the exported object of the library top level module, compiled the code into a single file, injected said object into RequireJS internal module map, and finally including the file manually in the application HTML.

After that, i can use the shared module normally in Ember code. However this has its drawbacks: its not integrated in the Ember CLI build pipeline, not easy to reuse internal npm dependencies in the browser, lacks automated testing integration, etc.

finally including the file manually in the application HTML

You should be able to the app.import the “disted” file and therefore it ends up concatenated inside your vendor file.

As for the build step, I wish I had an answer… trying to solve this elegantly myself and ended up transpiling it down and wrapping it in a factory which spits out an export or invokes define depending on the environment.