# Δημιουργία Πακέτου

Για να δημιουργήσεις πακέτο πρεπεί να γίνει ώς εξήσου:

npm pack

npm pack (opens new window) θα παράγει ένα TGZ αρχείο το οποίο μπορείς να το μεταφέρεις όπου επιθυμείς. Ωστόσο, είναι δυνατό να δημοσιευθεί (opens new window) και σε κάποιο NPM registry.

Για να δουλέψεις με το published/packed είναι σημαντικό το περιβάλλον για το οποίο προορίζεται το πακέτο να έχει πρόσβαση στο πακέτο @es4x/create (opens new window) γιατί χρειάζεται να εγκαταστήσει κάποια κομμάτια απο την java.

# Docker

Docker images μπορούν να δημιουργηθούν με ευκολία:

es4x dockerfile

Η παραπάνω εντολή θα παράγει ένα dockerfile αρχείο που μετα μπορείς να το προσαρμόσεις όπως εσυ επιθυμείς.

Αρχικά έχει 3 στάδια:

  1. Στο πρώτο στάδιο η node χρησιμοποιείται για να εγκαταστήσει όλες τις NPM βιβλιοθήκες
  2. Στο δεύτερο στάδιο η java χρησιμοποιείται για να εγκαταστήσει όλες τις Maven βιβλιοθήκες
  3. Τέλος, η GraalVM image χρησιμοποιείται για ξεκινήσει η εφαρμογη.

Ως προεπιλογή χρησιμοποιείται το oracle/graalvm-ce (opens new window) docker image, αλλά μπορεί να αντικατασταθεί από οποιοδήποτε άλλο JDK image (καλύτερα να είναι >11) με υποστήριξη για JVMCI.

docker build . --build-arg BASEIMAGE=openjdk:11

Η Java 11 υποστηρίζει το jlink (opens new window).

Μπορείς να το χρησιμοποιήσεις για δημιουργήσεις και να βελτιώσεις κάποια modules και τις βιβλιοθήκες τους και να δημιουργήσεις το δικό σου runtime image.

es4x jlink

H παραπάνω εντολή θα παράγει βελτιστοποιημένο χρόνο εκτέλεσης, πράγμα που σημαίνει ότι μπορεί να χρησιμοποιηθεί αντί να βασίζεται σε μια πλήρη εγκατάσταση JDK. Συγκριτικά, μια εφαρμογή hello world θα καταναλώνει 80Mb, ενώ μια πλήρης εγκατάσταση JDK απαιτεί περίπου 200Mb.

Αυτή η δυνατότητα μπορεί να χρησιμοποιηθεί σε συνεργασία με το Dockerfile. Αντί να χρησιμοποιήσεις τη βασική image, χρησιμοποίησε τη βασική image OpenJDK. Στη συνέχεια, στο δεύτερο στάδιο, εκτέλεσε το jlink:

# Second stage (build the JVM related code)
FROM openjdk:11 AS JVM
ARG ES4X_VERSION=${project.version}
# Copy the previous build step
COPY --from=NPM /usr/src/app /usr/src/app
# use the copied workspace
WORKDIR /usr/src/app
# Download the ES4X runtime tool
RUN curl -sL https://github.com/reactiverse/es4x/releases/download/${ES4X_VERSION}/es4x-pm-${ES4X_VERSION}-bin.tar.gz | \
    tar zx --strip-components=1 -C /usr/local
# Install the Java Dependencies
# force es4x maven resolution only to consider production dependencies
RUN es4x install --only-prod
# Create the optimized runtime
RUN es4x jlink -t /usr/local

Αυτό θα παράγει το βελτιστοποιημένο χρόνο εκτέλεσης στο jre, το οποίο μπορεί να χρησιμοποιηθεί με μια μικρή base image για το τελικό στάδιο:

FROM debian:slim
# Collect the jars from the previous step
COPY --from=JVM /usr/local /usr/local
COPY --from=JVM /usr/src/app /usr/src/app
# use the copied workspace
WORKDIR /usr/src/app
# Bundle app source
COPY . .
# Define custom java options for containers
ENV JAVA_OPTS="-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:+UseContainerSupport"
# define the entrypoint
ENTRYPOINT [ "./node_modules/.bin/es4x-launcher" ]

Αυτό θα παράγει μια μικρή final image, αλλά ένα μεγαλύτερο layer καθώς συσκευάζετε και τον βελτιστοποιημένο χρόνο εκτέλεσης.