Wednesday, September 25, 2019

Using a common javascript folder for several NodeJS applications

There are some alternatives for sharing javascript code between multiple projects.
The most obvious one is to build a common package, and use it in every project.

Great, Right?

Well, not really.

What if you have multiple projects, each using the same common package, and you update the common package every day. What should you do after changing the common package code, and you want to use the new common package in each project?


The required steps are:

  1. Update the common package code
  2. Update the common package version
  3. Push the changes
  4. Publish the updated common package
But wait, we're not done yet.
For each project that is using the common package, follow the next steps:
  1. Update the project package.json to include the new common package version
  2. Run `npm install` to update the node_module, and to update the package-lock.json
  3. Push the change
Now, this is not fun.
Especially if you have many projects...

A Common Code Alternative

If you are the only maintainer of the package, it might be much simpler to directly include the files from each project. It is especially easy if you have a monorepo  GIT.

This prevents the updates hell for each time you update the common package.
It does means you need to invest time in setup of the projects and the common package build, but this is a one-time setup, and then every time you change the common package code, the steps are:
  1. Update the common package code
  2. Push the changes
  3. Run build for all of the projects. This can be done automatically by Jenkins, without manual actions.

Common code setup

Place the common code and the projects in the same root folder, for example:
  • GIT root folder
    • common-package
      • common1.js
      • common2.js
    • project1
    • project2
    • ...
In each project include the common package directly, for example:
const commonPackage = require('common-package/common1');
And use webpack.config.js to handle the common package includes:

module.exports = {

...

resolve: {
  alias: {
    'common-package': path.resolve(__dirname, "../commons-package"),
  }
},

...

};

Docker build

In case you build the projects using docker, you will need to run a script before the docker build, to handle the following:
  • copy the common-package folder into project1
  • set an environment variable to the copied location
  • use the environment variable in webpack
For example, the build-docker.sh could copy the folder:
rm -rf ./common-package
cp -r ../common-package ./
docker build ...
rm -rf ./common-package

The docker file should use the copied folder:
FROM node:12.7 as builder
WORKDIR /app
COPY src/package.json ./
COPY src/package-lock.json ./
RUN npm install

ENV COMMON_DIRECTORY=./common-package
COPY common-package ./common-package

COPY src ./
RUN npm run build

CMD ["npm", "start"]
And the webpack.config.js should be updated to:
const commonDir = process.env.COMMON_DIRECTORY || "../commons-package";

...

    'common-package': path.resolve(__dirname, commonDir),
...



No comments:

Post a Comment