@h4ad/node-modules-packer
Advanced tools
Comparing version 1.1.0 to 1.2.0
@@ -28,2 +28,4 @@ import { DependencyInfo, ExtractorContainer } from '@h4ad/dependency-extractor'; | ||
'output-file': import("@oclif/core/lib/interfaces").OptionFlag<string>; | ||
minify: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>; | ||
'minify-keep-names': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>; | ||
quiet: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>; | ||
@@ -30,0 +32,0 @@ }; |
@@ -9,2 +9,3 @@ "use strict"; | ||
const core_1 = require("@oclif/core"); | ||
const esbuild_1 = tslib_1.__importDefault(require("esbuild")); | ||
const rimraf_1 = tslib_1.__importDefault(require("rimraf")); | ||
@@ -54,2 +55,6 @@ const custom_command_1 = tslib_1.__importDefault(require("../../common/custom-command")); | ||
args.push('--output-file', options.outputFile); | ||
if (options.minify !== undefined) | ||
pushFlagBoolean('minify', options.minify); | ||
if (options.minifyKeepNames !== undefined) | ||
pushFlagBoolean('minify-keep-names', options.minifyKeepNames); | ||
return await this.run(args, loadOptions); | ||
@@ -186,2 +191,14 @@ } | ||
this.logMessage(flags, 'log', 'Getting artifacts to zip'); | ||
const isJsFileRegex = /(\.js|\.cjs|\.mjs)$/; | ||
const keepNames = !!flags['minify-keep-names']; | ||
const transformAsyncCode = (code) => esbuild_1.default | ||
.transform(code, { minify: true, keepNames }) | ||
.then(result => result.code); | ||
const transformerFunction = (filePath, metadataPath) => { | ||
const isJsFile = isJsFileRegex.test(filePath) || isJsFileRegex.test(metadataPath); | ||
if (!isJsFile) | ||
return undefined; | ||
return transformAsyncCode; | ||
}; | ||
const transformer = flags.minify ? transformerFunction : undefined; | ||
const artifacts = [ | ||
@@ -192,2 +209,3 @@ { | ||
type: 'directory', | ||
transformer, | ||
shouldIgnore: shouldIgnoreNodeFile, | ||
@@ -209,2 +227,3 @@ }, | ||
metadataPath, | ||
transformer, | ||
type, | ||
@@ -317,2 +336,14 @@ }); | ||
}), | ||
minify: core_1.Flags.boolean({ | ||
description: 'Minify each .js file with esbuild.', | ||
default: false, | ||
required: false, | ||
allowNo: true, | ||
}), | ||
'minify-keep-names': core_1.Flags.boolean({ | ||
description: 'Keep the names during minification.', | ||
default: false, | ||
required: false, | ||
allowNo: true, | ||
}), | ||
quiet: core_1.Flags.boolean({ | ||
@@ -319,0 +350,0 @@ char: 'q', |
@@ -95,3 +95,16 @@ /** | ||
outputFile?: string; | ||
/** | ||
* Pass all .js files to esbuild transform to reduce the file size. | ||
* | ||
* @default false | ||
*/ | ||
minify?: boolean; | ||
/** | ||
* Keep the names of all properties and class names during minification. | ||
* | ||
* @reference {@link https://esbuild.github.io/api/#keep-names} | ||
* @default false | ||
*/ | ||
minifyKeepNames?: boolean; | ||
} | ||
//# sourceMappingURL=headless.d.ts.map |
import { ZipFile } from 'yazl'; | ||
export declare type TransformAsyncCode = (code: Uint8Array) => Promise<string>; | ||
export interface ZipArtifact { | ||
@@ -11,8 +12,10 @@ path: string; | ||
shouldIgnore?: (fileName: string) => boolean; | ||
transformer?: (filePath: string, metadataPath: string) => TransformAsyncCode | undefined; | ||
} | ||
export declare class FasterZip { | ||
run(rootPath: string, outputPath: string, zipArtifacts: ZipArtifact[]): Promise<void>; | ||
readdirAndAddToZip(zipFile: ZipFile, rootPath: string, source: ZipArtifact, path: string, onErrorOnStream: (reason?: any) => void, callback: (err: Error | null) => void): void; | ||
private handleArtifact; | ||
protected readdirAndAddToZip(zipFile: ZipFile, rootPath: string, source: ZipArtifact, path: string, onErrorOnStream: (reason?: any) => void): Promise<void>; | ||
protected addFileToZip(zipFile: ZipFile, source: ZipArtifact, rootPath: string, filePath: string, onErrorOnStream: (reason?: any) => void): Promise<void>; | ||
protected handleArtifact(artifact: ZipArtifact, zipfile: ZipFile, rootPath: string, onErrorOnStream: (reason?: any) => void): Promise<void>; | ||
} | ||
//# sourceMappingURL=zip.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.FasterZip = void 0; | ||
const tslib_1 = require("tslib"); | ||
const fs_1 = tslib_1.__importStar(require("fs")); | ||
const fs_1 = require("fs"); | ||
const path_1 = require("path"); | ||
const yazl_1 = require("yazl"); | ||
const fs_2 = require("./fs"); | ||
const string_stream_1 = require("./string-stream"); | ||
const string_to_uint_1 = require("./string-to-uint"); | ||
class FasterZip { | ||
@@ -23,69 +25,46 @@ async run(rootPath, outputPath, zipArtifacts) { | ||
} | ||
readdirAndAddToZip(zipFile, rootPath, source, path, onErrorOnStream, callback) { | ||
fs_1.default.readdir(path, (err, files) => { | ||
if (err) | ||
return callback(err); | ||
let pending = files.length; | ||
if (!pending) | ||
return callback(null); | ||
files.forEach(file => { | ||
const filePath = (0, path_1.join)(path, file); | ||
fs_1.default.stat(filePath, (_err, stats) => { | ||
if (_err) | ||
return callback(_err); | ||
if (stats.isDirectory()) { | ||
this.readdirAndAddToZip(zipFile, rootPath, source, filePath, onErrorOnStream, __err => { | ||
if (__err) | ||
return callback(__err); | ||
pending -= 1; | ||
if (!pending) | ||
return callback(null); | ||
}); | ||
} | ||
else { | ||
if (!source.shouldIgnore || | ||
(source.shouldIgnore && !source.shouldIgnore(filePath))) { | ||
const metadataPath = source.metadataPath | ||
? filePath.replace(source.path, source.metadataPath) | ||
: (0, path_1.relative)(rootPath, filePath); | ||
const readStream = (0, fs_1.createReadStream)(filePath).once('error', err => onErrorOnStream(err)); | ||
zipFile.addReadStream(readStream, (0, path_1.normalize)(metadataPath)); | ||
} | ||
pending -= 1; | ||
if (!pending) | ||
return callback(null); | ||
} | ||
}); | ||
}); | ||
}); | ||
async readdirAndAddToZip(zipFile, rootPath, source, path, onErrorOnStream) { | ||
const filePaths = await (0, fs_2.readdirAsync)(path).then(files => files.map(file => (0, path_1.join)(path, file))); | ||
const filePathsAndStats = await Promise.all(filePaths.map(async (filePath) => [filePath, await (0, fs_2.statAsync)(filePath)])); | ||
await Promise.all(filePathsAndStats.map(async ([filePath, stat]) => { | ||
if (stat.isFile()) { | ||
if (source.shouldIgnore && source.shouldIgnore(filePath)) | ||
return; | ||
await this.addFileToZip(zipFile, source, rootPath, filePath, onErrorOnStream); | ||
} | ||
else { | ||
await this.readdirAndAddToZip(zipFile, rootPath, source, filePath, onErrorOnStream); | ||
} | ||
})); | ||
} | ||
async handleArtifact(artifact, zipfile, rootPath, onErrorOnStream) { | ||
await new Promise((resolve, reject) => { | ||
async addFileToZip(zipFile, source, rootPath, filePath, onErrorOnStream) { | ||
const metadataPath = (0, path_1.normalize)(source.metadataPath | ||
? filePath.replace(source.path, source.metadataPath) | ||
: (0, path_1.relative)(rootPath, filePath)); | ||
const transformer = source.transformer && source.transformer(filePath, metadataPath); | ||
const readStream = (0, fs_1.createReadStream)(filePath).once('error', err => onErrorOnStream(err)); | ||
if (transformer) { | ||
try { | ||
if (artifact.type === 'directory') { | ||
this.readdirAndAddToZip(zipfile, rootPath, artifact, artifact.path, onErrorOnStream, err => { | ||
if (err) | ||
reject(err); | ||
else | ||
resolve(); | ||
}); | ||
} | ||
else { | ||
const metadataPath = artifact.metadataPath | ||
? artifact.path.replace(artifact.path, artifact.metadataPath) | ||
: (0, path_1.relative)(rootPath, artifact.path); | ||
const readStream = (0, fs_1.createReadStream)(artifact.path).once('error', err => { | ||
onErrorOnStream(err); | ||
}); | ||
zipfile.addReadStream(readStream, (0, path_1.normalize)(metadataPath)); | ||
resolve(); | ||
} | ||
const code = await (0, string_to_uint_1.streamToUInt8Array)(readStream); | ||
const finalContent = await transformer(code); | ||
const fileContentReadable = new string_stream_1.StringStream(finalContent); | ||
zipFile.addReadStream(fileContentReadable, metadataPath); | ||
} | ||
catch (e) { | ||
reject(e); | ||
zipFile.addReadStream(readStream, metadataPath); | ||
} | ||
}); | ||
} | ||
else | ||
zipFile.addReadStream(readStream, metadataPath); | ||
} | ||
async handleArtifact(artifact, zipfile, rootPath, onErrorOnStream) { | ||
if (artifact.type === 'directory') { | ||
await this.readdirAndAddToZip(zipfile, rootPath, artifact, artifact.path, onErrorOnStream); | ||
} | ||
else { | ||
await this.addFileToZip(zipfile, artifact, rootPath, artifact.path, onErrorOnStream); | ||
} | ||
} | ||
} | ||
exports.FasterZip = FasterZip; | ||
//# sourceMappingURL=zip.js.map |
@@ -1,1 +0,1 @@ | ||
{"version":"1.1.0","commands":{"run":{"id":"run","description":"Pack files and node dependencies to zip file.","strict":true,"pluginName":"@h4ad/node-modules-packer","pluginAlias":"@h4ad/node-modules-packer","pluginType":"core","aliases":[],"examples":["<%= config.bin %> <%= command.id %> /project/path -i dist"],"flags":{"json":{"name":"json","type":"boolean","description":"Format output as json.","helpGroup":"GLOBAL","allowNo":false},"include":{"name":"include","type":"option","char":"i","description":"Include more files during packing (eg: -i dist).","required":false,"helpValue":"package.json","multiple":true},"ignore-file-ext":{"name":"ignore-file-ext","type":"option","char":"e","description":"Force ignore specific file extension.","required":false,"multiple":true},"disable-default-ignore-file-ext":{"name":"disable-default-ignore-file-ext","type":"boolean","description":"Disable including default ignored extensions that we consider as useless.","required":false,"allowNo":true},"include-node-path":{"name":"include-node-path","type":"option","description":"Force include folders starting with the specified path (eg --include-node-path \"dev-dependency\" will include node_modules/dev-dependency), but you need to MANUALLY add your sub-dependencies if dev-dependency has production dependencies.","required":false,"helpValue":"dev-dependency","multiple":true},"ignore-node-path":{"name":"ignore-node-path","type":"option","description":"Force exclude folders starting with specified path (eg: -n \"typeorm/browser\" will exclude node_modules/typeorm/browser).","required":false,"helpValue":"typeorm/browser","multiple":true},"prod":{"name":"prod","type":"boolean","description":"Include production dependencies when pack node dependencies.","required":false,"allowNo":true},"peer":{"name":"peer","type":"boolean","description":"Include peer dependencies when pack node dependencies.","required":false,"allowNo":true},"dev":{"name":"dev","type":"boolean","description":"Include development dependencies when pack node dependencies.","required":false,"allowNo":true},"optional":{"name":"optional","type":"boolean","description":"Include optional dependencies when pack node dependencies.","required":false,"allowNo":true},"output-path":{"name":"output-path","type":"option","description":"Specify output path for the zip file.","required":false,"multiple":false,"default":"./"},"output-file":{"name":"output-file","type":"option","description":"Specify output file name for the zip file.","required":false,"multiple":false,"default":"deploy.zip"},"quiet":{"name":"quiet","type":"boolean","char":"q","description":"Run without logging.","required":false,"allowNo":false}},"args":[{"name":"dir","description":"Project root directory","required":false,"default":"./"}]}}} | ||
{"version":"1.2.0","commands":{"run":{"id":"run","description":"Pack files and node dependencies to zip file.","strict":true,"pluginName":"@h4ad/node-modules-packer","pluginAlias":"@h4ad/node-modules-packer","pluginType":"core","aliases":[],"examples":["<%= config.bin %> <%= command.id %> /project/path -i dist"],"flags":{"json":{"name":"json","type":"boolean","description":"Format output as json.","helpGroup":"GLOBAL","allowNo":false},"include":{"name":"include","type":"option","char":"i","description":"Include more files during packing (eg: -i dist).","required":false,"helpValue":"package.json","multiple":true},"ignore-file-ext":{"name":"ignore-file-ext","type":"option","char":"e","description":"Force ignore specific file extension.","required":false,"multiple":true},"disable-default-ignore-file-ext":{"name":"disable-default-ignore-file-ext","type":"boolean","description":"Disable including default ignored extensions that we consider as useless.","required":false,"allowNo":true},"include-node-path":{"name":"include-node-path","type":"option","description":"Force include folders starting with the specified path (eg --include-node-path \"dev-dependency\" will include node_modules/dev-dependency), but you need to MANUALLY add your sub-dependencies if dev-dependency has production dependencies.","required":false,"helpValue":"dev-dependency","multiple":true},"ignore-node-path":{"name":"ignore-node-path","type":"option","description":"Force exclude folders starting with specified path (eg: -n \"typeorm/browser\" will exclude node_modules/typeorm/browser).","required":false,"helpValue":"typeorm/browser","multiple":true},"prod":{"name":"prod","type":"boolean","description":"Include production dependencies when pack node dependencies.","required":false,"allowNo":true},"peer":{"name":"peer","type":"boolean","description":"Include peer dependencies when pack node dependencies.","required":false,"allowNo":true},"dev":{"name":"dev","type":"boolean","description":"Include development dependencies when pack node dependencies.","required":false,"allowNo":true},"optional":{"name":"optional","type":"boolean","description":"Include optional dependencies when pack node dependencies.","required":false,"allowNo":true},"output-path":{"name":"output-path","type":"option","description":"Specify output path for the zip file.","required":false,"multiple":false,"default":"./"},"output-file":{"name":"output-file","type":"option","description":"Specify output file name for the zip file.","required":false,"multiple":false,"default":"deploy.zip"},"minify":{"name":"minify","type":"boolean","description":"Minify each .js file with esbuild.","required":false,"allowNo":true},"minify-keep-names":{"name":"minify-keep-names","type":"boolean","description":"Keep the names during minification.","required":false,"allowNo":true},"quiet":{"name":"quiet","type":"boolean","char":"q","description":"Run without logging.","required":false,"allowNo":false}},"args":[{"name":"dir","description":"Project root directory","required":false,"default":"./"}]}}} |
{ | ||
"name": "@h4ad/node-modules-packer", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "", | ||
@@ -11,3 +11,3 @@ "main": "lib/index.js", | ||
"postpack": "rimraf oclif.manifest.json", | ||
"prepack": "yarn build && oclif manifest && oclif readme", | ||
"prepack": "npm run build && oclif manifest && oclif readme", | ||
"clean": "rm -rf ./lib/", | ||
@@ -89,6 +89,5 @@ "cm": "cz", | ||
"@oclif/plugin-version": "^1.1.1", | ||
"plist": "^3.0.5", | ||
"esbuild": "^0.15.3", | ||
"rimraf": "^3.0.2", | ||
"semver": "^7.3.7", | ||
"tslib": "^2.4.0", | ||
"yazl": "^2.5.1" | ||
@@ -101,2 +100,3 @@ }, | ||
"@semantic-release/github": "^8.0.4", | ||
"@types/bluebird": "^3.5.36", | ||
"@types/chai": "^4", | ||
@@ -108,3 +108,4 @@ "@types/mocha": "^9.0.0", | ||
"@types/rimraf": "^3.0.2", | ||
"@types/sinon": "^10.0.13", | ||
"@types/terser": "^3.12.0", | ||
"@types/uglify-js": "^3.16.0", | ||
"@types/unzipper": "^0.10.5", | ||
@@ -135,5 +136,5 @@ "@types/yazl": "^2.4.2", | ||
"semantic-release": "^19.0.3", | ||
"sinon": "^14.0.0", | ||
"tape": "^5.5.3", | ||
"ts-node": "^10.4.0", | ||
"tslib": "^2.4.0", | ||
"typescript": "^4.5.5", | ||
@@ -140,0 +141,0 @@ "unzipper": "^0.10.11" |
@@ -23,10 +23,13 @@ <h1 align="center"> | ||
This is a library to package all your node_modules and other files you want inside your project to a zip file. It's like using `npm prune --production` but without all the heavy I/O operations. | ||
This is a library to package all your node_modules and other files you want inside your project to a zip file. | ||
It's like using `npm prune --production` but without all the heavy I/O operations. | ||
You can use this library to deploy applications in serverless environments, for example, without having to do | ||
lots of crazy configurations with webpack. | ||
lots of crazy configurations with webpack, also this library allows you to minify all `.js` files using `esbuild`. | ||
I personally created this library inspired by an internal library I created for my company to deploy our NestJS apps | ||
for AWS Lambda, with this guy I improve deployment time [by up to 432%](./benchmark#results) (M2 SSD) with the benefit that my Webstorm doesn't go crazy | ||
with dependency indexing every time I implement because I no longer need to run `npm prune --production` just to get a descending build size. | ||
for AWS Lambda. | ||
With this guy I improve deployment time by up to [441% (284% minified)](./benchmark#results) and reduce the bundle | ||
size by up to [68% (122% minified)](./benchmark#results) with the benefit that my Webstorm doesn't go crazy with dependency indexing | ||
every time I deploy because I no longer need to run `npm prune --production` just to get a descending build size. | ||
@@ -45,2 +48,4 @@ > Wait, you're asking me why I build and deploy the APIs on my computer instead of using CI/CD? | ||
- If you use terraform to deploy in serverless environments, just point the output file to terraform and that's it. | ||
- If you want to minify all `.js` files, see `--minify` flag. | ||
- If you want to remap the files, like renaming `dist` to `build`. | ||
- If you like to deploy your app manually. | ||
@@ -93,2 +98,16 @@ - This library can give you more control over how you compress your files without having to write a lot of code to do so. | ||
Minify all `.js` files to reduce the bundle size: | ||
```bash | ||
node-modules-packer run ./ -i dist --minify | ||
``` | ||
> All `.js` files are minified, including files and folders that you include with `-i` flag. | ||
If you want to preserve the class names, properties and other symbols, you can run with `--minify-keep-names`: | ||
```bash | ||
node-modules-packer run ./ -i dist --minify --minify-keep-names | ||
``` | ||
Exclude unwanted file extensions from node_modules: | ||
@@ -159,2 +178,4 @@ | ||
outputFile: 'deploy.zip', | ||
minify: true, | ||
minifyKeepNames: true, | ||
}); | ||
@@ -522,3 +543,3 @@ | ||
[--include-node-path <value>] [--ignore-node-path <value>] [--prod] [--peer] [--dev] [--optional] [--output-path | ||
<value>] [--output-file <value>] [-q] | ||
<value>] [--output-file <value>] [--minify] [--minify-keep-names] [-q] | ||
@@ -540,2 +561,4 @@ ARGUMENTS | ||
dependencies. | ||
--[no-]minify Minify each .js file with esbuild. | ||
--[no-]minify-keep-names Keep the names during minification. | ||
--[no-]optional Include optional dependencies when pack node dependencies. | ||
@@ -557,3 +580,3 @@ --output-file=<value> [default: deploy.zip] Specify output file name for the zip file. | ||
_See code: [src/commands/run/index.ts](https://github.com/H4ad/node-modules-packer/blob/v1.1.0/src/commands/run/index.ts)_ | ||
_See code: [src/commands/run/index.ts](https://github.com/H4ad/node-modules-packer/blob/v1.2.0/src/commands/run/index.ts)_ | ||
@@ -560,0 +583,0 @@ ## `node-modules-packer version` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
97770
11
76
912
628
43
3
+ Addedesbuild@^0.15.3
+ Added@esbuild/android-arm@0.15.18(transitive)
+ Added@esbuild/linux-loong64@0.15.18(transitive)
+ Addedesbuild@0.15.18(transitive)
+ Addedesbuild-android-64@0.15.18(transitive)
+ Addedesbuild-android-arm64@0.15.18(transitive)
+ Addedesbuild-darwin-64@0.15.18(transitive)
+ Addedesbuild-darwin-arm64@0.15.18(transitive)
+ Addedesbuild-freebsd-64@0.15.18(transitive)
+ Addedesbuild-freebsd-arm64@0.15.18(transitive)
+ Addedesbuild-linux-32@0.15.18(transitive)
+ Addedesbuild-linux-64@0.15.18(transitive)
+ Addedesbuild-linux-arm@0.15.18(transitive)
+ Addedesbuild-linux-arm64@0.15.18(transitive)
+ Addedesbuild-linux-mips64le@0.15.18(transitive)
+ Addedesbuild-linux-ppc64le@0.15.18(transitive)
+ Addedesbuild-linux-riscv64@0.15.18(transitive)
+ Addedesbuild-linux-s390x@0.15.18(transitive)
+ Addedesbuild-netbsd-64@0.15.18(transitive)
+ Addedesbuild-openbsd-64@0.15.18(transitive)
+ Addedesbuild-sunos-64@0.15.18(transitive)
+ Addedesbuild-windows-32@0.15.18(transitive)
+ Addedesbuild-windows-64@0.15.18(transitive)
+ Addedesbuild-windows-arm64@0.15.18(transitive)
- Removedplist@^3.0.5
- Removedtslib@^2.4.0
- Removed@xmldom/xmldom@0.8.10(transitive)
- Removedbase64-js@1.5.1(transitive)
- Removedplist@3.1.0(transitive)
- Removedxmlbuilder@15.1.1(transitive)