We need to move a large application from silverlight over to html5.
The application will have a client and server part.
Because of the size of the application I thought it might be worth deviding some of the functionality into npm modules.
That way if I require to use it on the server side, i can and if I want to use it on the client (using aurelia) i can do that through jspm.
From a reusability of modularized js would you recon using npm being the best approach to maintain a versioned reusable stack or are there other ways of dealing with this?
Just want to do a sanity check to make sure I am on the right track.
Modularized code is definitely the way to go, I don't see any issue with using NPM as a versioned repo to deal with this especially as the code grows and is used by more and more people, however another approach might be using the githubs version tags, this might be a simpler solution as well (or atleast keeping everything in once place)
Related
I think it has something to do with using webpack directly and therefore gives more flexibility. But I'm not completely sure if someone can explain what "ejecting" means. Also what are the ramifications of ejecting a create react app? Is it bad to do this, or?
To bootstrap a react project it will require for you to know about things like Webpack or Babel which might be a sticking point for people who do not want to learn about these.
create-react-app provides a fully configured environment with reasonable defaults (and possible to extend). Most infrastructure-related work is hidden from you, and whenever there are changes in one of the dependent packages this is taken care of for you -- it will only be required to update react-scripts.
I highly recommend this presentation by one of CRA authors it will give you a better idea of the project.
Now eject means that all of the configuration will be exposed to you. You will see every package which runs your project. Now you are responsible for maintaining all of that configuration.
This is not necessarily a bad thing; you are then left with more code to maintain, but you get full control in return.
Background
Starting on a new vue.js (2.0) project. I've worked with vue-cli in other projects (vuejs-templates/webpack) and found the build process difficult to grasp when doing any kind of changes.
On top of that, webpack is infamous for its lacking documentation, therefore it turned out to be a lot of work even to achieve minor tweaks to the build process.
In general, I believe I understand both webpack and vue-loader. I'm still having a hard time getting the full picture of vuejs-templates/webpack though.
Question
I'm considering rolling my own webpack config for this app, but I'm concerned I'll eventually end up with a build process as big as the current vuejs-templates/webpack.
My plan was to work my way up from vuejs-templates/webpack-simple and not overcomplicate things too much.
What I have in mind is a config / build process situated somewhere in between vuejs-templates/webpack-simple and vuejs-templates/webpack.
I'm interested to see how others (with perhaps more experience that I have) feel about vuejs-templates/webpack. Wonder if it will just get harder to use as the project grows or if it will all make sense eventually.
Does it make sense to roll my own webpack config / build process or should I just suck it up and use vuejs-templates/webpack?
After about a month of working with Vue, vue-cli & webpack, I figured out the following:
1. Roll-your-own boilerplate
This feels a lot like re-inventing the wheel. There's more than meets the eye: writing up all the config, loaders, picking a folder structure & setting up tests takes a considerable amount of time.
You'll be frequently shifting focus from developing your app to tweaking the build. There will be many small things you need as you develop, but the pain will be considerably reduced by using vue-loader from the start.
To sum up: this is a very big decision & you'll need to be ready to invest a considerable amount of time in it to be fully set up.
If your setup is so custom that you have to roll your own boilerplate, then be sure you'll have to redo a lot of the work that's been done already in templates/webpack. If you must, don't hesitate to get some inspiration from the current templates/webpack boiler, there are some neat tricks that you might want to use in your boiler. You could also start from the simpler webpack template and work your way up from there.
2. Fork templates/webpack
If you plan to redo some of the folder structure and perhaps change some of the core libs, it's a good idea to do your own fork of templates/webpack instead of starting from scratch.
It's not going to be easy at first, but as you begin to comprehend the structure & tools involved you'll realize the initial frustrations were well worth it.
As a bonus, you can install it through vue-cli and easily re-use it for other projects:
vue init username/repo my-project
3. Tweak templates/webpack
Sometimes you won't know in advance how your boilerplate will look like. In that case, I've realized it's fine to start with templates/webpack and do small changes along the way.
In that case, it's going to be hard to move it to it's own repo and install it via vue-cli. My recommendation is to take notes on whatever changes you do to the boilerplate (or add a #hash or smth to those commits).
That way, when you start your next project you can follow approach #2 and use it via vue-cli.
Conclusion
I think many of the issues you'll have with changing templates/webpack are also bound to pop up while doing it from scratch. It's probably because of Webpack's poor documentation (hey, Webpack 2 is looking better!) and the ridiculous amount of tools you need nowadays to build a JavaScript project.
Use templates/webpack and don't look back, the time you'll spent understanding it and vue-loader is waaay below the time you'll spend setting up your own boilerplate.
One big benefit I've always perceived with using NodeJS on the server is the potential for sharing bits of code between the server and client side (ex. input validation). Now that I'm actually developing using NodeJS one difficulty that I've found is determining the responsibility and context in which each body of code is executed. Below I'll list a few of the difficulties I've had in hopes gain some enlightenment on conventions or guidance that I may be overlooking that could help elevate these issues.
Build-Time Code
Build time code for projects that use Gulp, Grunt, or vanilla NPM in a way that follow the basic documentation are generally pretty easy to follow. Most smaller projects tend to keep all of the code within a single file and the file tends to be named a conventional name like gulpfile.js, however with bigger projects I've seen these scripts begin to be split out. I've seen some cases where the gulp file is split into multiple files and placed under a separate directory. Even worse I've found cases where the gulpfile.js file isn't even named as such causing new developers to hunt around to find where the gulpfile is located and once it is located the gulp command always has to be run with the specific --gulpfile option.
Run-Time Server-Side Code
The entry point for basic node applications appear to simply require pointing out a specific JavaScript file when running the node command (ex. node script.js). For web server applications, such as those using Express, I've noticed that by convention the entry point file is often called server.js and can usually be found in the root directory of the application. In some other cases however such as when running the web server in a developer environment I've seen gulp tasks take on the responsibility of launching Node. In these cases there seems to be multiple ways to include the entry point but one example I've found is just starting up the webpack complier followed by a require statement for the entry point script. Figuring out how to incorporate normal guidance on how to accomplish a typical node debug command is non-trivial in this type of setup. Besides the entry point of the application, there doesn't seem to be any general guidance on directory structure for NodeJS/Express applications that keeps server-side specific code in it's place to help locate it and to keep it separate from build-time and client-side code.
The server-side story becomes even more complex in cases where the server side code is used both for the purpose for serving up static content, server-side generated views (such as with MVC), as well as for providing an API to the client side. My preference is to separate API from the application project but I get the feeling from others that there is a sense of overcomplexity involved in doing so where I see it as a reasonable separation of concerns.
Run-Time Client-Side Code
Since client-side code can often have various entry points based on the first page that is requested this can be tricky. However because of the general transparency of URLs with how they map to resources for typical cases it as well as how powerful the debugging tools have become in modern browsers, it isn't too much trouble following the follow of the scripts. The difficult instead for the client side code comes more for typical build processes which generally end up copying the files around and placing them into a production like structure under a different name. An example would be a project that has a folder called src or js that holds client-side and server-side code intermingled except for that only a portion of the files happen to be included in a build task which transforms and often concatenates the files and places them in a distribution folder. Common names of these distribution folders that I've seen are dist, public, www, and wwwroot. Often if not always these directories are at the root of the project which at least makes it a bit easier to locate without having to interrogate the build scripts.
My hope is that there is some general guidance on how to put all of this together in a sane way perhaps by an authoritative source mainly to give guidance to those like myself who may want start off on the right foot. As a side effect perhaps being able to reference some sort of standard even if it is a loose one may also reduce the amount of boilerplate a team has to invent and discuss as they get started. Within each of the contexts listed above there will obviously be some technology specific conventions such as those followed for AngularJS, Meteor, or ReactJS on the client-side. The conventions I'm looking for are more specific to separating the main highlevel contexts in end-to-end JavaScript applications where the language and platform no longer become obvious way to differentiate between each.
Build-Time Code
IMHO if you have so much build-time code that it's more than say 1000 lines and requires more than a handful of files, something has gone off the rails. Either you don't know how to make good use of existing packages from npm or you don't understand how to refactor generic code and publish as independent npm packages. If you feel like you need guidance about a project's build-time code because it is so large and complex, my suggestion is to modularize and split out into separate projects - each published independently to npm. Also just check your overall approach. What are you doing that is so custom and requires so much machinery?
Run-Time Server Side Code
Please see my other answer to ExpressJS How to structure an application?
Generally I'd rather see client side code and server side code either completely separate npm packages (separate git repos, separate package.json files, published independently) (if they are large enough) or otherwise co-mingled in the same module and grouped by coupling (all the code relating to a feature kept together including front and back end code), especially if your code base has a substantial amount of code that works in both environments.
I have an open-source full-stack node/JS application called mjournal that keeps browser code and node code alongside each other. You can have a look and see if it feels logical to you and easy to understand where code lives. It is by no means a popular approach, so many folks will dislike it, but it feels good to me personally since I've embraced "group by coupling" as a general principle.
Figuring out how to incorporate normal guidance on how to accomplish a typical node debug command is non-trivial in this type of setup
Yeah, that's nonsense. Your app should start with npm start or something like node server.js. Elaborate gulp/grunt setups that confuse new developers are unnecessary complexity you should just eliminate.
The server-side story becomes even more complex in cases where the server side code is used both for the purpose for serving up static content
In my experience, the code to serve up static content boils down to 5 lines or less, so no big deal. If you have a non-microscopic amount of code dealing with serving static content, again something has gone way off the rails.
Run-Time Client Side Code
My hope is that there is that there is some general guidance on how to put all of this together in a sane way perhaps by an authoritative source mainly to give guidance to those like myself who may want start off on the right foot.
There are some people in the node community that have adopted the "convention over configuration" approach in use by Ruby on Rails, EmberJS, and some other large projects. If you like that approach, check out tools that use it like SailsJS, EmberJS, Yeoman generators, etc.
But in general, looking for a "standard" is not how the node.js/javascript/web community rolls. Small npm packages. File layouts that are forced into obviousness due to smallness. I feel your frustration here as front-end toolchains are so complex, but ultimately it's because JavaScript in the browser took too many decades to create a reasonable module system. Things may start to standardize in the next few years now that ES6 modules are an official spec, but with so much code already written in CommonJS and it's terrible precursors like RequireJS/AMD, we'll be dealing with them probably for the foreseeable future.
I am attempting to make a javascript library which I would prefer to be compatible with both browsers and node. However, there is some functionality offered in the node API that isn't offered in browsers (such as compression). I know it would be possible to code this functionality in javascript so it would be cross-compatible, but the node native compression will probably perform much better as it is much lower level.
How should I split between browser-compatible code and code that uses node API?
The way I see it, I could do one of the following:
make 2 separate scripts, one for node and one for browsers
make my code figure out the environment it is in and act accordingly
make all my code the same, but lose some performance improvements I would have had in node
What should I do to solve this?
I know this is an old question, however, today it is possible easily with Browserify. Browserify lets you write nodejs modules with require() syntax and have them converted to browser complain code easily!
They even ported zlib which you mention to work with it, so that dependency is OK.
I hope this helps future readers, browserify helped me :)
I'm planning on writing a spine/backbone.js style web application which basically just transfers a large application.js file to the client's browser that communicates with the node.js backend using ajax. The problem is that I don't know how to structure such a project, since I've never seen examples of such an application. I can picture some pros and cons with different ways of doing this
Keep everything in one project folder. Both the server side and client side code resides in the same folders which means they can share resources such as form input validation and language files. This seems like a good solution, but I have no clue how I would bundle only the code that the client needs, and not the server code. Just in general I don't know how to accomplish this. If it has been done before, I would like to see some sample code, perhaps even a git repo
Create two separate projects. One for the client and one for the server. This seems a lot more simple and straight forward, but not as elegant when it comes to sharing resources. I would have to write code such as form input validation twice.
Any thoughts?
Your first situation is a very tricky scenario and I would suggest that we're not quite there yet. Some would argue that there's little reason to try to get there, as front/back ends will always be tasked with slightly and sometimes drastically different tasks. Libraries like derby show promise, but aren't quite there yet.
I discussed this recently with a friend and we came to the conclusion that perhaps the best bet for now would be to serialize models over websockets, and then ensure that the node server and client app stay in sync.
I may work on such a library, but for now I'm still developing with 2 folders and copies of models on both sides. Layout mark-up gets sent from the server, with all other content rendered client-side after receiving JSON from the server. Frankly, the amount of duplication isn't really that substantial. A little irritating but also maintains greater flexibility to grow in different directions.
This won't be a complete answer to your question, but one library that might help if you choose to pursue such an endeavour might be Browserify.
It's designed so you can use a similar require() function with a preprocessed, or on-the-fly generated from module source, js file containing many different modules. These modules can be shared with the server side through the same require() mechanism.
I don't know explicity of a Backbone implemented on the server side as a server side counter part for model sync, that would seem to be the first goal you are looking for, aloowing code that makes sense to be shared, such as models and validation, to be usefully shared.
Another thing to look at is requirejs, which uses more traditional script tag asynchronous loading f js modules, but also works within node.js aloowing the same AMD modules to a be shared between node and client code.
Was realtime required? Otherwise the Derby approach might be a little too heavy. Express.js proposes a structure where client js is separated in public folder, and provides methods to get a quick RESTful API running, which you can then access with your application.js.
I guess you could load "classic" js files from public into node via eval() too.
Things have moved much ahead now, and things like
browserify influenced coding can help us achieve this easily
there will always be some uncommon code between server and client sides, But the goal shall always be to keep all the logic code in different modules(which are later used from both environments). This is better from TDD point of view as well, also keeps your keyboard press count to lesser.
Have a look at things like this stack -
http://mindthecode.com/lets-build-an-angularjs-app-with-browserify-and-gulp/
Having said that your option1 did not seem that manageable to me, if you had the right coders coding the right code.