5

有没有办法在构建时使用 Node.js 和 npm 自动压缩某些文件?

例如,我有一个项目,该文件结构如下所示:

Project/
--lib/
--node_modules/
--test/
--index.js
--package.json

例如,我希望能够将 lib 文件夹、node_modules 和 index.js 中的某些模块压缩到一些 zip 存档中,以将其上传到 AWS Lambda。我不需要压缩测试文件夹或测试 Node.js 模块(mocha 和 chai)。我什至创建了一个用于生成 zip 文件的 bash 脚本,但是有没有办法在调用“npm install”时自动执行这个脚本?

这应该是一个标准问题,它应该有一个标准的解决方案,但我无法发现这样的。

更新

感谢 michael,决定使用 gulp。这是我的脚本,以防其他人需要它用于 AWS Lambda:

var gulp = require('gulp');
var clean = require('gulp-clean');
var zip = require('gulp-zip');
var merge = require('merge-stream');

gulp.task('clean', function () {
    var build = gulp.src('build', {read: false})
        .pipe(clean());
    var dist = gulp.src('dist', {read: false})
        .pipe(clean());

    return merge(build, dist);
});

gulp.task('build', function() {
    var index = gulp.src('index.js')
        .pipe(gulp.dest('build'));
    var lib = gulp.src('lib/**')
        .pipe(gulp.dest('build/lib'));
    var async = gulp.src('node_modules/async/**')
        .pipe(gulp.dest('build/node_modules/async'));
    var collections = gulp.src('node_modules/collections/**')
        .pipe(gulp.dest('build/node_modules/collections'));
    var underscore = gulp.src('node_modules/underscore/**')
        .pipe(gulp.dest('build/node_modules/underscore'));
    var util = gulp.src('node_modules/util/**')
        .pipe(gulp.dest('build/node_modules/util'));
    var xml2js = gulp.src('node_modules/xml2js/**')
        .pipe(gulp.dest('build/node_modules/xml2js'));

    return merge(index, lib, async, collections, underscore, util, xml2js);
});

gulp.task('zip', ['build'], function() {
    return gulp.src('build/*')
        .pipe(zip('archive.zip'))
        .pipe(gulp.dest('dist'));
});

gulp.task('default', ['zip']);
4

8 回答 8

8

我意识到这个答案对于原始海报来说来得太晚了。但是我对打包一个 Lambda 函数有几乎相同的问题,所以对于后代来说,这是一个不需要任何额外的 devDependencies(如 gulp 或 grunt)的解决方案,只需npm pack与以下内容一起使用package.json(但假设你有sed并且zip可用给你):

{
  "name": "my-lambda",
  "version": "1.0.0",
  "scripts": {
    "postpack": "tarball=$(npm list --depth 0 | sed 's/@/-/g; s/ .*/.tgz/g; 1q;'); tar -tf $tarball | sed 's/^package\\///' | zip -@r package; rm $tarball"
  },
  "files": [
    "/index.js", 
    "/lib"
  ],
  "dependencies": {
    "async": "*",
    "collections": "*",
    "underscore": "*",
    "util": "*",
    "xml2js": "*"
  },
  "bundledDependencies": [
    "async",
    "collections",
    "underscore",
    "util",
    "xml2js"
  ],
  "devDependencies": {
    "chai": "*",
    "mocha": "*"
  }
}

给定上面的 package.json,调用npm pack将产生一个package.zip文件,其中包含:

index.js
lib/
node_modules/
├── async/
├── collections/
├── underscore/
├── util/
└── xml2js/

files数组是要包含的内容的白名单。在这里,它只是index.jslib目录。

但是,npm 也将自动包含package.json, README(以及变体,如README.md, CHANGELOG(及其变体)和LICENSE(以及替代拼写LICENCE),除非您明确排除它们(例如使用.npmignore)。

bundledDependencies数组指定捆绑的包。在这种情况下,它是所有依赖项,但没有 devDependencies。

最后,运行postpack脚本,npm pack因为会npm pack生成一个 tarball,但我们需要为 AWS Lambda 生成一个 zip。

可以在https://hackernoon.com/package-lambda-functions-the-easy-way-with-npm-e38fc14613ba获得有关 postpack 脚本正在做什么的更详细说明(也是一般方法的来源) .

于 2019-03-18T11:40:37.590 回答
3

你应该看看npm scripts

您仍然需要在存储库中放置一个 bash 脚本,但它会在某些npm任务执行时自动触发。

于 2015-07-09T00:39:03.233 回答
3

我会使用 gulp-sftp、gulp-tar 和 gulp-gzip 以及别名作为命令来使用 gulp。.bash_aliases在您的用户主文件夹中创建一个名为的文件,其中包含

alias installAndUpload='npm install && gulp runUploader'

重新启动后,您可以使用此别名同时调用这两个操作。

一个 gulp 文件可能看起来像这样

var gulp = require('gulp');
var watch = require('gulp-watch');
var sftp = require('gulp-sftp');
var gzip = require('gulp-gzip');

gulp.task('runUploader', function () {
    gulp.src('.path/to/folder/to/compress/**')
        .pipe(tar('archive.tar'))
        .pipe(gzip())
        .pipe(gulp.dest('path/to/folder/to/store')) // if you want a local copy
        .pipe(sftp({
            host: 'website.com',
            user: 'johndoe',
            pass: '1234'
        }))
});

当然,你也可以添加 gulp-watch 来自动创建 tar/zip 并在目录发生变化时上传。

于 2015-07-09T00:45:50.707 回答
2

npm-pack-zip 为我工作。

npm install --save-dev npm-pack-zip

为了使用 aws 发布整个 lambda,我在 package.json 中使用了这个节点脚本:

    "publish": "npm-pack-zip && aws lambda update-function-code --function-name %npm_package_name% --zip-file fileb://%npm_package_name%.zip && rm %npm_package_name%.zip"
于 2020-02-14T21:47:05.620 回答
1

如果您需要自动化任务,请查看GruntGulp

在 Grunt 需要插件的情况下:

https://www.npmjs.com/package/grunt-zip

https://www.npmjs.com/package/grunt-aws-lambda

于 2015-07-09T00:46:57.340 回答
1

您可以使用Zip-Build,这个小包将使用您package.json文件中的数据并创建一个名为project-name_ version.zip 的压缩文件。

免责声明:我是这个库的开发者。

如何使用 zip-build

只需在您的项目中安装为开发依赖项:

$ npm install --save-dev zib-build

然后修改你的构建脚本package.json,在最后添加 && zip-build,如下所示:

"scripts": {
  "build": your-build-script && zip-build
}

如果您的构建目录命名为不同,build并且您所需的压缩文件目录命名为不同dist,您可以提供目录名称作为 zip-build 的参数:

"scripts": {
  "build": your-build-script && zip-build build-dirname zip-dirname 
}
于 2020-12-04T15:36:56.263 回答
0

在https://gist.github.com/ctulek/6f16352ebdfc166ce905查看我的要点

这将 gulp 用于您提到的所有任务,除了最初创建 lambda 函数(它只更新代码)

它假定每个 lambda 函数都在其自己的文件夹中实现,并且您需要定义您的 AWS 凭证配置文件。

于 2015-10-21T21:59:15.930 回答
0

如果您是基于 UNIX 的,您也可以zip在您的脚本之一中使用该命令:

"scripts": {
  "zip": "zip -r build.zip build/"
  "build": "build",
  "build-n-zip": "build && zip
}

上面在根目录创建了 a build.zip,它是/build文件夹的压缩版本。

如果您想压缩多个文件夹/文件,只需将它们添加到末尾:

"scripts": {
  "zip": "zip -r build.zip build/ some-file.js some-other-folder/"
}
于 2021-08-25T14:40:14.310 回答