How to organize node,js/webpack project with server, client, and shared code?

一笑奈何 提交于 2021-02-08 02:03:14

问题


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!


回答1:


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.



来源:https://stackoverflow.com/questions/47643449/how-to-organize-node-js-webpack-project-with-server-client-and-shared-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!