Skip to content

Instantly share code, notes, and snippets.

@bodinsamuel
Last active April 14, 2023 13:00
Show Gist options
  • Save bodinsamuel/c52f9e5eee6e3b7d5e8813108b3fd0aa to your computer and use it in GitHub Desktop.
Save bodinsamuel/c52f9e5eee6e3b7d5e8813108b3fd0aa to your computer and use it in GitHub Desktop.

Clean Package.json before build

When installing for production or in docker, it's important to keep package.json light and use cache. When building you can not remove all devDependencies since some of them are useful for building but not all of them. This is also useful if you bump the version prop regularly. This script will clean up dependencies and returns only the mandatory fields. Adapt to your need ☺️

jq 'walk(
  if type == "object" then with_entries(select(.key | test("jest|prettier|eslint|semantic|dotenv|nodemon|renovate") | not)) 
  else . end) | { name, type, dependencies, devDependencies, packageManager, workspaces }'

Playground example

Example in Docker

# ------------------
# package.json cache
# ------------------
FROM apteno/alpine-jq:2022-03-27 AS deps

# To prevent cache invalidation from changes in fields other than dependencies
COPY package.json /tmp
RUN jq 'walk(if type == "object" then with_entries(select(.key | test("jest|prettier|eslint|semantic|nodemon|renovate") | not)) else . end) | { name, type, dependencies, devDependencies, packageManager, workspaces }' < /tmp/package.json > /tmp/deps.json

# ------------------
# New base image
# ------------------
FROM node:16.16.0-bullseye as tmp

# Setup the app WORKDIR
WORKDIR /app/tmp

# Copy and install dependencies separately from the app's code
# To leverage Docker's cache when no dependency has change
COPY --from=deps /tmp/deps.json ./package.json
COPY yarn.lock .yarnrc.yml ./
COPY .yarn .yarn

# Install dev dependencies
RUN true \
  && yarn install
  
# Copy everything back after installation
COPY . /app/tmp

# Remove all dev dependencies
RUN true \
  && yarn worskpaces focus --all --production \
  && rm -rf .yarn/

# ---- Web ----
# Resulting new, minimal image
# This image must have the minimum amount of layers
FROM node:16.16.0-bullseye as web

ENV NODE_ENV production

# Bash is just to be able to log inside the image and have a decent shell
# OpenSSL is here to handle HTTPS requests correctly
RUN apt-get -y install bash curl openssl

# Do not use root to run the app
USER node

WORKDIR /app

COPY --from=tmp --chown=node:node /app/tmp /app

EXPOSE 8000

Warnings

Removing fields and packages on the fly can definitely break your builds.

  • Typescript can break if you have referenced a removed package in types in tsconfig.json
  • Typescript won't compile if you remove all @types by default
  • Yarn can break in certain scenario if there is no name prop

Use regex at your advantages to restrict too wide selector, eg: jest|prettier vs ^jest$|prettier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment