现代前端项目的编译构建方案

从自己写js第一天到今天,js构建模式发生了太大的变化,从自己的第一个js项目: https://loveyu.org/2429.html 到现在这些看懂都困难的js项目,差不多过去了十多年了吧。

举个例子,看看今天的项目构建最终方案:

# 打包要使用的镜像
FROM harbor.example.net/base-nvm-of-frontend:1.0.0 AS build-src

#建立工作目录
RUN mkdir -p /data \
    && mkdir -p /data/m \
    && mkdir -p /data/pc

WORKDIR /data

# 安装git过程中需要进行交互,使用-y命令自动执行交互安装
# 执行apt-get update的时候,会下载一些临时文件到该目录,所以删除
RUN apt-get update \
    && apt-get install -y git \
    && rm -rf /var/lib/apt/lists/*

COPY ./m/package.json ./m/package.json
COPY ./pc/package.json ./pc/package.json
COPY ./m/package-lock.json ./m/package-lock.json
COPY ./pc/package-lock.json ./pc/package-lock.json

# 为了执行nvm命令,执行 /root/.bashrc脚本
RUN source /root/.bashrc \
    && nvm install "v8.9.4" \
    && nvm use "v8.9.4" \
    && npm install example-npm -g --registry=http://npm.example.net/

RUN cd /data/pc \
    && source /root/.bashrc \
    && nvm use "v8.9.4" \
    && npm install --registry=http://npm.example.net/

RUN cd /data/m \
    && source /root/.bashrc \
    && nvm use "v8.9.4" \
    && npm install --registry=http://npm.example.net/

# #####################   缓存到此结束   ########################################

# m版制文件并开始打包
ARG BUILD_ARG
ARG ENV_ARG
COPY ./docker/ /data/docker

COPY ./m/ /data/m
# 处理zzc-design-mobile引用文件的大小写问题
RUN cd /data/m \
    && source /root/.bashrc \
    && nvm use "v8.9.4" \
    && echo "当前构建: m_${ENV_ARG}" \
    && cp /data/docker/${ENV_ARG}-host.json /data/m/local_server/host/.host.json \
    && echo "开始打包" \
    && npm run ${BUILD_ARG}

# pc版制文件并开始打包
COPY ./pc/ /data/pc
RUN cd /data/pc \
    && source /root/.bashrc \
    && nvm use "v8.9.4" \
    && echo "当前构建: pc_${ENV_ARG}" \
    && echo "开始打包" \
    && npm run ${BUILD_ARG}

# 生产要使用的镜像
FROM harbor.example.net/base-nginx:1.18.0 AS build-image

COPY --from=build-src /data/m/dist /data/example/m/dist/
COPY --from=build-src /data/pc/dist /data/example/pc/dist/
COPY ./docker/nginx.conf /etc/nginx/nginx.conf

EXPOSE 8888

整体构建过程看起来还是蛮简单的,无非就是分为2个大部分,打包和复制打包结果,但是实际涉及到缓存复用等一大堆麻烦的问题,隔壁的同事整整折腾了2天才搞定。

很关键的一点,看harbor.example.net/base-nvm-of-frontend:1.0.0,为什么基础镜像是一个看起来像专项定制,实际上它就是专项定制。毕竟你要知道npm安装这个事情是存在一定概率的,而且也要知道node-sass这类安装及其困难,一不小心就安装失败,进程修改代码5分钟,安装编译5小时。

于是整体镜像化还是很重要的,所以就有了定制化的底包。

FROM harbor.example.net/base-nvm:0.38.0
USER root

#建立工作目录
RUN mkdir -p /data \
    && mkdir -p /data/m \
    && mkdir -p /data/pc

WORKDIR /data

# 安装git过程中需要进行交互,使用-y命令自动执行交互安装
# 执行apt-get update的时候,会下载一些临时文件到该目录,所以删除
RUN apt-get update \
    && apt-get install -y git \
    && rm -rf /var/lib/apt/lists/*

COPY ./m/package.json ./m/package.json
COPY ./pc/package.json ./pc/package.json
COPY ./m/package-lock.json ./m/package-lock.json
COPY ./pc/package-lock.json ./pc/package-lock.json

RUN cd /data/pc \
    && source /root/.bashrc \
    && nvm use "v8.9.4" \
    && npm install --registry=http://npm.example.net/

RUN cd /data/m \
    && source /root/.bashrc \
    && nvm use "v8.9.4" \
    && npm install --registry=http://npm.example.net/

上面的镜像大致就是这个样子的,特点就是先把依赖安装一遍,倒是打包之前再次安装就不用安装那些老大难的包了,效率极佳。不过镜像的大小就此增加了1.2G(看依赖),有些可能少一些。

其实这里还是没完的,base-nvm这个镜像也是来之不易,并非npm一下子就能安装成功,都是安装了无数次,踩了无数个坑总结经验,而且每次前端的骚操作还让经验不可用。

FROM debian:buster
USER root
ENV TZ=Asia/Shanghai \
    NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
    && sed -i "s|deb.debian.org/debian|mirrors.tuna.tsinghua.edu.cn/debian|g" /etc/apt/sources.list \
    && sed -i "s|security.debian.org/debian-security|mirrors.tuna.tsinghua.edu.cn/debian-security|g" /etc/apt/sources.list \
    && apt-get update \
    && apt-get install -y curl ca-certificates procps net-tools dnsutils iputils-ping \
                          telnet git build-essential bzip2 python2 autoconf automake nasm make cmake flex \
                          libtool libpng-dev libjpeg-dev libpng-tools zlib1g-dev imagemagick \
                          optipng advancecomp parallel -y \
    && curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash \
    && export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" \
    && [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \
    && rm /bin/sh && ln -s /bin/bash /bin/sh && echo "替换sh为bash, 用于支持source命令" \
    && nvm install 8.9.4 \
    && nvm install 8.12.0 \
    && nvm install 11.15.0 \
    && nvm install 12.18.3 \
    && nvm use "v12.18.3" \
    && nvm alias default "v12.18.3" \
    && nvm cache clear \
    && rm -rf /var/lib/apt/lists/* \
    && nvm --version \
    && node -v

看到这里,发现底包居然是debian:buster,是的就是它,它打包就是比centos和apline镜像好用,不过官方的方案似乎是ubuntu,差别不大。

只能说一个后端折腾前端,太难了,这些破事和我有半毛钱关系?别说为什么有那么多版本,就是有那么多,都预装省得了。还有为啥要装一堆软件,这个你去问那些node_modules的作者,安装个依赖为啥还要编译,为啥还要搞网络检查和下载,我不懂。

当前还没有任何评论

写下你最简单的想法