so I've had strictly a MVC programming background (Laravel, CodeIgniter, Django, etc.) and more and more I'm build bigger projects in Node.js but I'm having a difficult time figuring out a solid way of structuring my project that makes sense...
I've done some research and I love the way J. Cole Morrison does it here but it makes for extremely fat route files.
The structure is something like
app
-router
-index.js (your main route def. that imports individual route files)
--routes
This is nice and readable but all of your logic is stuffed in the routes folder which just doesn't make sense (or does it?). I guess I'd expect something more along the lines of seperate controllers that will handle your thinking. Does anyone else have Ideas or structures they use or is this a good way to go?
After using node.js / express.js in some projects, I have found Kraken's (1.+) structure very useful. It uses folders as part of the routes. Also, it comes with a scaffolding tool, so the mvc structure is easy to keep. This is not the only solution, but it is a good one indeed.
Disclosure: This is copy from kraken.js
/config Application configuration including environment-specific
configs
/controllers Routes and logic
/locales Language specific content bundles
/lib Common libraries to be used across your app
/models Models
/public Web resources that are publicly available
/public/templates Server and browser-side templates
/tasks Grunt tasks to be automatically registered by
[grunt-config-dir]
/tests Unit and functional test cases
index.js Application entry point
Related
I have no fullstack code experience with Spring Boot and I am wondering what is the most proper way or common approach for keeping frontend code in Spring Boot projects.
So, should I create a folder called frontend under src/main and keep Angular or React code in this directory as shown below?
- my-app-name
|
-- src
|
-- main
|
---- frontend
---- java
---- resources
Or should I prefer src/main/resource ?
As it was already pointed out by multiple people in the comments, you should bundle the frontend and backend separately. The reason for this is also that you need to build, package and deploy them separately and you need a separate pipeline for each of them. For example your spring boot app will be built as a docker container and deployed to kubernetes while it does not make much sense to host the frontend in such way, it could be hosted in a CDN.
This leaves us with your second point - monorepo vs multiple repositories. Both have their pros and cons. You can find a lot of articles on this topic online. I assume, that this is a small project and you'll work on both frontend and backend by yourself at once. In such case, you can do very well with the monorepo approach. You can do a change across both frontend and backend in a single commit, the refactoring will be easier etc. But if you choose to go with mutliple repositories, there is nothing wrong with it.
One more thing to consider is where and how you'll manage your API contract between the frontend and backend. There are again multiple approaches here. I'd advise not to go without the API contract specs (like doing everything by hand on both server and client side) and in case you go with monorepo don't create your dependency between the frontend and backend directly (on the file level), that create unecessarry coupling between those two.
The express-generator tool creates a file called bin/www and uses it as the application's main entry-point. I believe I've seen a couple of other modules do this as well, but the vast majority simply use index.js.
What is the rationale behind this? Of course I understand why you would split the server and the code for setting up the program into a separate modules, but why bin/www and not index.js? Why nest the main-entry point to a program two levels deeper than the stuff it calls? And remove the file-extension, making it even less descriptive?
Is there a clever, non-obvious reason behind this? Should I use this for my node-modules as well?
Thank you!
[edit]:
All good answers, thank you folks! I've accepted the one pointing out that this is standard behaviour for packages that include executables. Here's some more reading I've come across on this:
https://docs.npmjs.com/files/package.json#bin
https://blog.npmjs.org/post/118810260230/building-a-simple-command-line-tool-with-npm
You're used to running npm run, but not sysadmin. He will look for executables (attribute x) in thebin directory.
The entry point index.js is for node module. All packages that provide commands to run on the console contain the bin directory.
The extension is removed because it is not a script, but as a program. And these do not have extensions.
express-generator create a basic structure for an express application. By convention, the entry point of the app is index.js or app.js. In fact, express-generator create an app.js at the root of the application with the initial setup of express.
Also by convention, the bin/ directory is used for binary files, and by extension for the scripts you can directly launch (note the shebang at the first line of www file). This is common on Linux that binary file has no extension and it could explain the choice to keep this habit for this file.
www, by convention again, is used for naming web application (like /var/www/html in Apache server)
Anyway, as the documentation says,
The app structure created by the generator is just one of many ways to
structure Express apps. Feel free to use this structure or modify it
to best suit your needs.
See also this answer who talk about the core structure of express between version 3 & 4, with the removing of external module.
This seems like a situation that must be incredibly common, but I've yet to find a good solution to it. I'm a little new to modern Javascript, so please forgive me (or better yet, correct me) if I'm using the wrong terminology here and there.
I'm developing a web application. It's got a server, running as Javascript (ES6, I believe - using import/export) in node.js, using express.js for a router (and built by express-cli). And it's got a client side, also Javascript, mostly Vue modules (and built by vue-cli). I admit I don't really understand a lot of the boilerplate build code express-cli and vue-cli emitted, but it does work. I am not using any of a long list of frameworks that are assumed in the many pages google found for me when I tried to find an answer to this question.
Obviously, the client and server will be sending data structures (instances of various classes) back and forth, which I know how to do. And these ought to be the same class definitions.
I made an attempt to make webpack build both server and client, and that failed, so now I've split the application into two projects, each with its own folder tree, its own package.json, its own node_modules, and I'm using just webpack-dev-server for the client and nodemon/babel for the server. A third folder contains the shared code, which is imported by the client and the server. I got this to work well enough for proof of concept, but getting both sides (and Visual Studio Code) to recognize that the shared code is part of them is turning out to be a challenge, and I'm pretty sure I'm just going down the wrong path.
So, my question is, what is currently considered the best practice (or at least, a good practice) way to structure and build a client/server application of this type? An ideal answer to this question would include both folder structure and enough of the major configuration files to help me figure out how to write mine. A reference to an up-to-date and reliable source of information on this topic would satisfy me nicely.
I suspect that the right answer includes merging everything back into a single project and doing something clever with the webpack config files and maybe project.json... but what exactly that clever thing might be has so far eluded me.
Thanks!
In my opinion, you're right to use separate folders for your node.js(server)/vue.js(client app) as they're effectively 2 separate projects.
Apart from sharing some configs, utilities and validation, the app and server typically have little overlap: they're typically doing 2 very different things, require different build tools, different runtime environments, have different security concerns, and if you consider the future possibility of leveraging your client codebase to create a native IOS/android... app the difference between the 2 codebases will only increase.
For my current project, I have a folder structure whereby my server resides in the project root and my client is in a subfolder /app. Here's an simplified outline of how I've structured my node.js/vue.js project:
constants
config.js (server environment, database connection, api keys etc)
settings.js (business logic)
pricing.js
drivers
auth.js
db-connect.js
email.js
sms.js
socket-io-server.js
models (mongoose database models)
node_modules
routes (express routes)
api.js
auth.js
schema (json schema for automated validation)
login-validation.js
register-validation.js
services
billing.js
validation.js
app (this is my client sub-project sharing some server modules)
public (the output of the webpack client bundle including index.html)
src (ES6 source code, images, SASS/Stylus, fonts etc)
css
html (handlebars templates)
index.hbs
home.hbs
account.hbs
pricing.hbs
img
js
api
client-services
socket-io-client.js
store.js
router.js
vuex-utils.js
dom-utils.js
components (Vue components)
Profile.vue
Payment.vue
index.js (root and entry point for webpack)
webpack.config.js
.env.development.js
.env.production.js
package.json
server.js (node.js server root entry point)
This is by no means prescriptive. Notice, that I've organized the project files largely by function. Here's a link to an article proposing structuring around features.
A shared (client/server) module folder has pros and cons. The main downside I can see is that module sharing changes during development. For that reason my server codebase and modules reside in the project root folder - and some are also imported by the client app. The project root folder then naturally hosts a shared package.json and node_modules folder.
As your app develops, and you gain insight, it's fine to re-structure as the need arises (some IDEs make refactoring easier than others). If the Visual Studio Code IDE or webpack are not working well with your folder structure, it may be a configuration issue or the problem may stem from incorrect require/import paths. IDE inspections may help you find those errors or your IDE may struggle to be useful because of those errors.
My IDE (webstorm) and webpack v4 have no problems with the above folder structure or the location of modules in general (I have re-structured my app in many different ways) and got more adept at optimally configuring my IDE and webpack.
Webpack is very specific about the location of it's configuration file, input/output paths, whether it is executed from the project root or /app folder and it can take a lot of time to get it working properly. Nevertheless, it will locate modules referenced by the correct require/import paths. Here's the part of my webpack.config.js that sets up file entry/output.
const sourcePath = './src';
module.exports = {
entry: [
sourcePath + '/js/index.js'
],
output: {
path: __dirname + '/public', //location of webpack output files
publicPath: '/', //address that browser will request the webpack files
filename: 'js/index.[contenthash].js', //output filename
chunkFilename: 'js/chunk.[contenthash].js' //chunk filename
},
...
I've located my webpack.config.js and execute webpack inside the /app subfolder. My package.json scripts section to start the node.js server and have webpack build & watch my app files is:
"scripts": {
"start": "if [$NODE_ENV == 'production']; then node server.js; else nodemon server.js; fi",
"build": "cd ./app; webpack;"
},
Which allows me to start the node server with:
> npm start
and have webpack watch/re-build my bundle with:
> npm run build
Visual Studio Code has a rich IntelliSense experience and a feature called Automatic Type Acquisition which should allow it to support modules you import regardless of their location. This article provides more information on configuring VS Code for node.js.
There seems to be silent agreement on directory structure of node.js. At least I couldn't find any information on official site.
From what I've understand browsing opensource projects.
Usually project has /bin and /lib directory.
/bin contains modules entry point[s].
/lib contains 'helper' code.
I guess this is based on Unix directory structure.
And it makes sense for good-old compiled programs with executables and dlls.
AFAIK /lib was used to share libraries between programs.
In node, however, true dependencies are in node_modules.
/lib is used for application code.
Why not use /src?
This model is designed from execution point of view. But all projects, I've seen, use it to structure the code under develpment too. Also I've seen github-projects where whole module is just one file in bin directory.
I'm new to node.js and would like to know how people in community came to those decisions.
I guess what you mentioned about lib and src happened because of node philosophy to design small modules, not only in terms of code size, but most importantly in terms of scope. This principle has its roots in unix philosophy, particularly -
Small is beautiful.
Make each program do one thing well.
The architecture that I follow for developing web applications is broken into models, services, routes and controllers. I use lib for utilities and helper functions. Also a lot of node applications are built using express which itself has minimal api. In short, it is basically a matter of choice to choose convention or configuration.
I have worked in a web project with a heavy part on JavaScript, and I have noticed that there was no style how to use JavaScript. What unsettled me most is that everyone added files here and there, which resulted in a mess to organize and deliver them. Because this will be happen in every new project, I would like to have something like a styleguide for JavaScript. This styleguide should address the following questions:
How should JavaScript files be organized in the file system during development?
How should the JavaScript parts be separated from the HTML and other parts of the application?
How should JavaScript files be delivered in the real application, so that less code has to be loaded on each request and not too much requests have to be sent?
Is there something public available as a starting point for developing our own styleguide? What are your experiences in using your styleguide? Are developers following it easily, what are the simple and what are the difficult parts in it?
(I know, more question than one, but I'm interested in the whole story here. As a background, we have used JQuery and JSF, but I don't think that will have an impact on the answer.)
If you're doing heavy client side, you are probably going the MVC way.
So I'll answer your questions with the approach taken by the brunch. Brunch projects use MVC library Backbone.js, and have strict directory structure.
How should JavaScript files be organized in the file system during development?
src/
app/
collections/
controllers/
models/
styles/
templates/
views/
vendor/
build/
web/
config.yaml
Use Stitch to organize your files as CommonJS modules. Then you will be able to use require() to define dependency between them, as well as to combine them into one file later.
How should the JavaScript parts be separated from the HTML and other parts of the application?
build directory is used to store html; build/web is used to store javascript, images, and css.
How should JavaScript files be delivered in the real application, so that less code has to be loaded on each request and not too much requests have to be sent?
At the build stage, all JavaScript is minified and combined into one file (build/web/js/app.js), so that client will have to make only one HTTP request when he / she visits your site for the first time.
It's probably a good idea to make building process as easy as possible. Brunch does that by offering brunch watch command, which monitors filesystem for changes and builds code instantly with the help of Stitch and some other tools.
(It should be noted that during development brunch projects also use CoffeeScript as the primary language; it is transparently compiled by brunch before stitching the resulting JavaScript. However, this doesn't matter as long as file organization is concerned, and is out of scope of your question.)
For all JavaScript files definitely use a separate directory. Have as many files as possible semantically. One large constructor should correspond to a separate file. Never use filename prefixes where you can create a directory.
Unix-style directory structure is often found on GitHub:
src -- for the source JavaScript.
lib -- for libraries.
tests -- for unit tests.
bin -- for executables.
dist -- for compiled files.
For compiling we use a Makefile with targets for production and development. The production version is all of files JSHint`ed, minified and concatenated into one. The development target is generating a server-side script that includes all JavaScript files dynamically (for easy inclusion into HTML).
But generally it depends. We used a widget directory for one project. This widget directory had a set of separate widget subdirectories (e.g. slider, tabs, modal-window), each of which had the following layout (inspired by DOMLoader):
html -- for HTML templates.
css -- for CSS files necessary for the widget.
js -- for the widget JavaScript constructor.
Crockford has a few stylistic guidelines and the Yahoo exceptional performance site has details which might be useful to you.
I can recommend a book: JavaScript Patterns by Stoyan Stefanov.
I think one of the best book about javascript