容器化的Angular构建每次都重新编译



上下文

最近,我一直在尝试将我的Angular构建容器化,因为我将前端和后端一起部署在一个映像中。Dockerfile如下:

# Build frontend
FROM node:16 AS node-build
WORKDIR /app
COPY frontend/package.json frontend/package-lock.json ./
RUN npm install
COPY frontend .
RUN npm run build
# Build backend
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS dotnet-build
WORKDIR /app
COPY backend ./
RUN dotnet restore Api
RUN dotnet publish Api -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=dotnet-build /app/out .
COPY --from=node-build /app/dist/film-portal wwwroot/
ENTRYPOINT ["dotnet", "Api.dll"]

问题

上面的Dockerfile完美地构建了有问题的图像,部署后它就像一个魅力。然而,构建所花费的时间比我希望的要多。让我解释一下:

只有当package.jsonpackage-lock.json发生更改时,才运行npm install。这很好,节省时间
  • 无论何时触摸前端代码,都会运行npm run build。这当然是预期的行为,但它每次都会重新编译Angular库代码,而不是缓存编译后的结果(就像从本地shell执行npm run build时的情况一样)
  • 我正在寻找一种方法来缓存编译angular库代码的结果,因此npm run build只需要构建我自己的代码(完成时间更短)。在假想语法中,我需要在Dockerfile中为前端阶段提供以下内容:

    FROM node:16 AS node-build
    WORKDIR /app
    COPY frontend/package.json frontend/package-lock.json ./
    RUN npm install
    RUN npm compile-angular
    COPY frontend .
    RUN npm run build
    

    这里,npm compile-angular将仅在package.jsonpackage-lock.json改变时编译角度位,而不是每次我触摸前端代码中的某个文件时。

    不幸的是,据我所知,Angular CLI中没有专门编译Angular库代码的命令,只剩下用户代码。此外,我阅读的所有教程都没有提到重新编译的问题,所以我可能在这里遗漏了一些东西。尽管如此,我很难想象我是第一个遇到这个问题的人,我想至少应该有一个变通办法。因此,总结一下:

    1. 有没有办法避免在像我这样的码头化设置中重新编译Angular库代码
    2. 如果没有,是否至少有一个变通方法,可能是在Docker之外执行构建步骤

    经过长时间的搜索,我在angular cli存储库中找到了有关Issue 17017的信息。对此问题的一条评论提到,有一个黑客可以触发ESM编译:./node_modules/.bin/ngcc --properties es2015。有了这些知识,我修改了我的Dockerfile,它就像一个魅力,不再在每次更改我自己的代码时重新编译Angular库代码:

    # Build frontend
    FROM node:16 AS node-build
    WORKDIR /app
    COPY frontend/package.json frontend/package-lock.json ./
    RUN npm ci
    # Hack to make sure the angular modules are compiled at this stage
    RUN ./node_modules/.bin/ngcc --properties es2015
    COPY frontend .
    RUN npm run build
    # Build backend
    FROM mcr.microsoft.com/dotnet/sdk:5.0 AS dotnet-build
    WORKDIR /app
    COPY backend ./
    RUN dotnet restore Api
    RUN dotnet publish Api -c Release -o out
    # Build runtime image
    FROM mcr.microsoft.com/dotnet/aspnet:5.0
    WORKDIR /app
    COPY --from=dotnet-build /app/out .
    COPY --from=node-build /app/dist/film-portal wwwroot/
    ENTRYPOINT ["dotnet", "Api.dll"]
    

    最新更新