首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从node.js构建可执行文件的Shell脚本

从node.js构建可执行文件的Shell脚本
EN

Code Review用户
提问于 2018-03-23 08:30:43
回答 2查看 187关注 0票数 1

我正在尝试使用node.js节点封隔器归档成一个可执行文件。对于我的所有包,node.js的可执行文件都在{projectRoot}/node_modedules/.bin

项目结构如下:

代码语言:javascript
复制
|- node_modules
|   |-- .bin
|       |--- executable with source code 
|- compiled-bin
|   |-- compiled executable

我写了一个shell脚本来完成它。希望你能回顾一下:

代码语言:javascript
复制
#!/bin/bash
for filepath in ./node_modules/.bin/*; do
    export baseName="${filepath##*/}"
    nodec $filepath --clean-tmpdir --make-args=-j10 --output=./compile-bin/$baseName.out  
    chmod +x ./compile-bin/$baseName.out 
done

这是dockerfile,我曾经在容器中运行上面的脚本:

代码语言:javascript
复制
FROM node:8.3.0 as package

WORKDIR /usr/src/app
COPY . /usr/src/app

# Install dependencies
RUN apt-get update
RUN apt-get install -y -q --no-install-recommends \
  build-essential \
  python \
  make \
  squashfs-tools \
  gcc \
  g++ \
  clang-3.5 \
  clang++-3.5

# Install nodec compiler
RUN curl -L http://enclose.io/nodec/nodec-linux-x64.gz | gunzip > /usr/local/bin/nodec
RUN chmod +x /usr/local/bin/nodec

# Install npm packages
RUN npm i --no-optional \
  && ls -lh 

# Run build scripts
RUN mkdir compile-bin \
  && chmod +x ./build-script \
  && sync \
  && ./build-script
EN

回答 2

Code Review用户

发布于 2022-01-25 10:24:55

你的外壳脚本看起来很简单。虽然使用export是不必要的,但它看上去相当不错。

这个文件有点不同。还不完全清楚您是否打算在您正在设置的docker容器中使用已构建的应用程序,或者容器是否仅用于构建稍后移到其他位置的可执行文件。

现在,我假设您创建的码头容器有最终的工件,我强烈建议您查看多阶段构建,以细化最终结果。

除此之外,安装四个不同的C/C++编译器感觉很特别。将应用程序的依赖项分为两类,并保留一个可用于设置应用程序的package_list (和make_package_list)可能是有意义的。这与我的下一个建议非常吻合:利用docker的缓存机制。

目前,这个Docker容器将从头开始重新构建every单个代码集。这是因为您首先要将所有源文件COPY到容器中。您不需要这样做,而是要利用缓存的优势,执行很少首先更改的步骤:

代码语言:javascript
复制
FROM node:8.3.0 AS package

WORKDIR /usr/src/app

RUN apt-get update

# install building time dependencies
COPY make_package_list .
RUN make_package_list > xargs apt-get install -y -q --no-install-recommends
# install nodec compiler
RUN curl -L http://enclose.io/nodec/nodec-linux-x64.gz | gunzip > /usr/local/bin/nodec
RUN chmod +x /usr/local/bin/nodec

# install runtime dependencies
COPY package_list .
RUN package_list > xargs apt-get install -y -q --no-install-recommends

# NOW we copy the source files and start the build process
COPY . .
RUN npm i --no-optional \
  && ls -lh

# Run build scripts
RUN mkdir compile-bin \
  && chmod +x ./build-script \
  && sync \
  && ./build-script

这个设置应该会使第一次运行后的构建更快一些,只要应用程序的依赖关系没有改变。不过,对于npm依赖项来说,这并不适用。

也可以对此进行更改(复制包锁并在复制其余的源文件之前运行npm -i ),但是由于要复制完整的本地目录,当前脚本将使用本地包缓存。虽然这将是一个更快的构建,但它可能会在陈旧的包中引入一些微妙的问题,并且在COPY操作期间会花费更多的时间。

票数 1
EN

Code Review用户

发布于 2022-01-25 11:08:41

这个脚本不需要Bash。普通的POSIX外壳应该很好。

设置-e-u shell标志以确保在任何命令失败时以失败状态退出可能是一个好主意。

baseName真的需要在环境中导出吗?看起来,一个普通的变量应该很好。在这个上下文中,引号没有添加任何内容。也许包括目标路径(尽管我们可以删除冗余的初始./),以避免重复这两个后续的扩展。

请记住引用变量的扩展,特别是那些来自文件名globs的变量。

改进的代码

代码语言:javascript
复制
#!/bin/sh
set -eu

for filepath in node_modules/.bin/*
do
    outFile=compile-bin/${filepath##*/}
    nodec "$filepath" --clean-tmpdir --make-args=-j10 --output="$outFile" 
    chmod +x "$outFile"
done

也许我们可以简单地用chmod +x ./build-script && ./build-script代替sh build-script

正如在另一个答案中提到的,将整个工作目录复制为第一层将导致每次构建后续的所有内容。但我们可能不想把我们的来源复制到图像中。通常更好的做法是将卷装载到容器中,因此run命令变成:

代码语言:javascript
复制
docker run -v "$(pwd):/usr/src/app" $build_image sh build-script

然后,您可以多次使用构建映像,根据需要编译不同版本的代码。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/190277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档