├── .codeclimate.yml
├── .editorconfig
├── .github
└── workflows
│ └── pr.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin
└── index.js
├── lib
└── index.js
├── package.json
├── pnpm-lock.yaml
└── tests
├── __fixtures__
├── test.gif
├── test.jpg
├── test.png
└── test.svg
├── __snapshots__
└── index.spec.js.snap
└── index.spec.js
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | # This is a sample .codeclimate.yml configured for Engine analysis on Code
2 | # Climate Platform. For an overview of the Code Climate Platform, see here:
3 | # http://docs.codeclimate.com/article/300-the-codeclimate-platform
4 |
5 | # Under the engines key, you can configure which engines will analyze your repo.
6 | # Each key is an engine name. For each value, you need to specify enabled: true
7 | # to enable the engine as well as any other engines-specific configuration.
8 |
9 | # For more details, see here:
10 | # http://docs.codeclimate.com/article/289-configuring-your-repository-via-codeclimate-yml#platform
11 |
12 | # For a list of all available engines, see here:
13 | # http://docs.codeclimate.com/article/296-engines-available-engines
14 |
15 | engines:
16 | # to turn on an engine, add it here and set enabled to `true`
17 | # to turn off an engine, set enabled to `false` or remove it
18 | eslint:
19 | enabled: true
20 |
21 | # Engines can analyze files and report issues on them, but you can separately
22 | # decide which files will receive ratings based on those issues. This is
23 | # specified by path patterns under the ratings key.
24 |
25 | # For more details see here:
26 | # http://docs.codeclimate.com/article/289-configuring-your-repository-via-codeclimate-yml#platform
27 |
28 | ratings:
29 | paths:
30 | - src/**
31 |
32 | # You can globally exclude files from being analyzed by any engine using the
33 | # exclude_paths key.
34 |
35 | exclude_paths:
36 | - lib/**
37 | - **/__tests__/
38 | - **/__fixtures__/
39 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
11 | # Matches multiple files with brace expansion notation
12 | # Set default charset
13 | [*.{js,py}]
14 | charset = utf-8
15 |
16 | # 4 space indentation
17 | [*.py]
18 | indent_style = space
19 | indent_size = 4
20 |
21 | # Tab indentation (no size specified)
22 | [Makefile]
23 | indent_style = tab
24 |
25 | # Indentation override for all JS under lib directory
26 | [*.js]
27 | indent_style = space
28 | indent_size = 2
29 |
30 | # Matches the exact files either package.json or .travis.yml
31 | [{package.json,.travis.yml}]
32 | indent_style = space
33 | indent_size = 2
34 |
--------------------------------------------------------------------------------
/.github/workflows/pr.yml:
--------------------------------------------------------------------------------
1 | name: PR Workflow
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | strategy:
12 | matrix:
13 | node-version: [14, 16, 18]
14 | steps:
15 | - uses: actions/checkout@master
16 | - uses: pnpm/action-setup@master
17 | with:
18 | version: 7
19 |
20 | - name: Use Node.js ${{ matrix.node-version }}
21 | uses: actions/setup-node@master
22 | with:
23 | node-version: ${{ matrix.node-version }}
24 | cache: 'pnpm'
25 |
26 | - name: Install dependencies
27 | run: pnpm install
28 |
29 | - name: Run tests
30 | run: pnpm test
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by http://www.gitignore.io
2 |
3 | ### Editor
4 | *.swp
5 |
6 | ### Node ###
7 | # Logs
8 | logs
9 | *.log
10 |
11 | # Runtime data
12 | pids
13 | *.pid
14 | *.seed
15 |
16 | # OSX
17 | .DS_Store
18 |
19 | # Directory for instrumented libs generated by jscoverage/JSCover
20 | lib-cov
21 |
22 | # Coverage directory used by tools like istanbul
23 | coverage
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # Compiled binary addons (http://nodejs.org/api/addons.html)
29 | build/Release
30 |
31 | # Dependency directory
32 | # Commenting this out is preferred by some people, see
33 | # https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
34 | node_modules
35 |
36 | # Users Environment Variables
37 | .lock-wscript
38 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | dist: trusty
2 | sudo: required
3 | language: node_js
4 | node_js:
5 | - '6'
6 | - '8'
7 | before_script:
8 | - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
9 | - chmod +x ./cc-test-reporter
10 | - "./cc-test-reporter before-build"
11 | script:
12 | - npm test -- --coverage
13 | after_script:
14 | - if [[ "$TRAVIS_PULL_REQUEST" == "false" && `node --version` == *v8* ]]; then ./cc-test-reporter
15 | after-build --exit-code $TRAVIS_TEST_RESULT; fi
16 | env:
17 | global:
18 | secure: afTzTI4cFi/PB+p2svh9xy2wtzpgz5OD1cm0JipofHxWmartj4hSQJR62bX0bdq1eJvW2v6/Vso5W+F92GK+oi5i6S91So4S35JgjDPX9Xa+21h8iBRVOq9BhmwsDu2th67uTFKPNgnnvhRXi52JLi7kypsMwYqD+aDT+272BwVLK4nQ/nZC8lAySFDIKee+nmOBdBpRJrzC/oRSUmRbdzQUFdTh4uSpY7zmU5d3uNEP8JH94SMOsRcNtvNds/5e8nCMw5o/6b5GYZ8tZhkXlWtpm6SZrCMB0IjUKGX/tNGpl3mGIrIJSg2kW/9G+SZpR9FKTAbvpCXRQU4lnQ7Rgdug3QffUg79oje/p4Kf4q8oLENUU52Lm76ct6uP2Q1D6dD+wX+Gqd3VbIH5+jow0kENRKIrLnkAdLn+DVGpyeYl6iMOk9qnIvTrpDBK0JEa4z4ljryafhge1HYwnB8pdoYjysRl1mba/30ZmZpeMsuRbXrymPgwgypfZSacUiuNHh74CTK0ytGF9zVEg7WBziKe+9BCMaPpcxYp7wTfBoZ+4Pbg1knwCyphzAeh68KrMQhm+4Yghc1O5uJ/0OeNqBQh4UEj/Aj/sA2VmTvV0TwdM43+mx7XYR/bXjLn5jrVGXyTB7o7oORJwBDhVtdEfeU5qPjVparifVA1FMSHEpY=
19 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 | ### [0.5.1](https://github.com/tomchentw/imagemin-lint-staged/compare/v0.5.0...v0.5.1) (2022-06-24)
6 |
7 | ## [0.5.0](https://github.com/tomchentw/imagemin-lint-staged/compare/v0.4.0...v0.5.0) (2022-06-24)
8 |
9 |
10 | ### Features
11 |
12 | * **package.json:** upgrade dependencies ([#14](https://github.com/tomchentw/imagemin-lint-staged/issues/14)) ([d80565a](https://github.com/tomchentw/imagemin-lint-staged/commit/d80565a15e5b747cf6e8c67152cb16830b8e4042))
13 |
14 |
15 | # [0.4.0](https://github.com/tomchentw/imagemin-lint-staged/compare/v0.3.1...v0.4.0) (2019-01-02)
16 |
17 |
18 | ### Features
19 |
20 | * **lib:** change to commonjs export ([11e3382](https://github.com/tomchentw/imagemin-lint-staged/commit/11e3382))
21 | * **package.json:** remove `babel-multi-env` ([f427662](https://github.com/tomchentw/imagemin-lint-staged/commit/f427662))
22 |
23 |
24 |
25 |
26 | ## [0.3.1](https://github.com/tomchentw/imagemin-lint-staged/compare/v0.3.0...v0.3.1) (2019-01-02)
27 |
28 |
29 | ### Bug Fixes
30 |
31 | * **package.json:** update core dependencies ([#4](https://github.com/tomchentw/imagemin-lint-staged/issues/4)) ([c6a96f2](https://github.com/tomchentw/imagemin-lint-staged/commit/c6a96f2))
32 |
33 |
34 |
35 |
36 | # [0.3.0](https://github.com/tomchentw/imagemin-lint-staged/compare/v0.2.1...v0.3.0) (2017-11-23)
37 |
38 |
39 | ### Features
40 |
41 | * **index.js:** export minifyFile ([23b608f](https://github.com/tomchentw/imagemin-lint-staged/commit/23b608f))
42 |
43 |
44 |
45 |
46 | ## [0.2.1](https://github.com/tomchentw/imagemin-lint-staged/compare/v0.2.0...v0.2.1) (2017-11-14)
47 |
48 |
49 | ### Bug Fixes
50 |
51 | * **index.js:** use separate CLI entry file ([3c5d7fc](https://github.com/tomchentw/imagemin-lint-staged/commit/3c5d7fc))
52 | * **package.json:** use separate CLI entry file ([a605c3f](https://github.com/tomchentw/imagemin-lint-staged/commit/a605c3f))
53 |
54 |
55 |
56 |
57 | # 0.2.0 (2017-11-14)
58 |
59 |
60 | ### Features
61 |
62 | * **index.js:** add imagemin-lint-staged CLI ([341f094](https://github.com/tomchentw/imagemin-lint-staged/commit/341f094))
63 | * **package.json:** add with dependencies ([42c4166](https://github.com/tomchentw/imagemin-lint-staged/commit/42c4166))
64 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Tom Chen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # imagemin-lint-staged
2 | > imagemin CLI designed for lint-staged usage with sensible defaults
3 |
4 | [![Version][npm-image]][npm-url] [![PR Workflow][github-workflows-pr-image]][github-workflows-pr-url]
5 |
6 |
7 | ## Installation
8 |
9 | ```sh
10 | npm i --save-dev imagemin-lint-staged
11 | ```
12 |
13 | ## Usage
14 |
15 | Use in conjuntion with [lint-staged][lint-staged]. In your `package.json`
16 |
17 | ```json
18 | "lint-staged": {
19 | "*.{png,jpeg,jpg,gif,svg}": ["imagemin-lint-staged"]
20 | },
21 | ```
22 |
23 |
24 | ## Options
25 |
26 | N/A
27 |
28 |
29 | ## Contributing
30 |
31 | 1. Fork it
32 | 2. Create your feature branch (`git checkout -b my-new-feature`)
33 | 3. Commit your changes (`git commit -am 'Add some feature'`)
34 | 4. Push to the branch (`git push origin my-new-feature`)
35 | 5. Create new Pull Request
36 |
37 |
38 | [lint-staged]: https://github.com/okonet/lint-staged
39 | [npm-image]: https://img.shields.io/npm/v/imagemin-lint-staged.svg?style=flat-square
40 | [npm-url]: https://www.npmjs.org/package/imagemin-lint-staged
41 |
42 | [github-workflows-pr-image]: https://github.com/tomchentw/imagemin-lint-staged/actions/workflows/pr.yml/badge.svg
43 | [github-workflows-pr-url]: https://github.com/tomchentw/imagemin-lint-staged/actions/workflows/pr.yml
44 |
--------------------------------------------------------------------------------
/bin/index.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | "use strict";
3 | const { minifyFile } = require("../lib/index.js");
4 |
5 | Promise.all(process.argv.slice(2).map(minifyFile)).catch(function(e) {
6 | console.error(e);
7 | process.exit(1);
8 | });
9 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | const fs = require("fs");
3 | const promisify = require("util.promisify");
4 |
5 | const readFile = promisify(fs.readFile);
6 | const writeFile = promisify(fs.writeFile);
7 |
8 | const plugins = [
9 | [
10 | "imagemin-gifsicle",
11 | {
12 | interlaced: true,
13 | },
14 | ],
15 | [
16 | "imagemin-jpegtran",
17 | {
18 | progressive: true,
19 | },
20 | ],
21 | [
22 | "imagemin-optipng",
23 | {
24 | optimizationLevel: 5,
25 | },
26 | ],
27 | [
28 | "imagemin-svgo",
29 | {
30 | plugins: [
31 | {
32 | name: "preset-default",
33 | params: {
34 | overrides: {
35 | removeViewBox: false,
36 | },
37 | },
38 | },
39 | ],
40 | },
41 | ],
42 | ].map(([name, opts]) => require(name)(opts));
43 |
44 | const minifyFile = (exports.minifyFile = (filename) =>
45 | [...plugins, (it) => writeFile(filename, it)].reduce(
46 | (acc, it) => acc.then(it),
47 | readFile(filename)
48 | ));
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "imagemin-lint-staged",
3 | "version": "0.5.1",
4 | "description": "imagemin CLI designed for lint-staged usage with sensible defaults",
5 | "license": "MIT",
6 | "author": {
7 | "name": "tomchentw",
8 | "email": "developer@tomchentw.com",
9 | "url": "https://github.com/tomchentw"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/tomchentw/imagemin-lint-staged"
14 | },
15 | "bugs": {
16 | "url": "https://github.com/tomchentw/imagemin-lint-staged/issues"
17 | },
18 | "homepage": "https://github.com/tomchentw/imagemin-lint-staged/",
19 | "bin": "bin/index.js",
20 | "files": [
21 | "bin/",
22 | "lib/",
23 | "CHANGELOG.md"
24 | ],
25 | "keywords": [
26 | "imagemin",
27 | "CLI",
28 | "git hook",
29 | "compress images",
30 | "lint-staged"
31 | ],
32 | "scripts": {
33 | "test": "jest --runInBand",
34 | "release": "standard-version"
35 | },
36 | "lint-staged": {
37 | "*.{png,jpeg,jpg,gif,svg}": [
38 | "node ./bin/index.js"
39 | ],
40 | "*.{js,jsx,json,css}": [
41 | "prettier --write"
42 | ]
43 | },
44 | "babel": {
45 | "env": {
46 | "test": {
47 | "presets": [
48 | "@babel/preset-env"
49 | ]
50 | }
51 | }
52 | },
53 | "jest": {
54 | "testPathIgnorePatterns": [
55 | "\\d+\\.\\d+\\.\\d+"
56 | ]
57 | },
58 | "dependencies": {
59 | "imagemin-gifsicle": "^7.0.0",
60 | "imagemin-jpegtran": "^7.0.0",
61 | "imagemin-optipng": "^8.0.0",
62 | "imagemin-svgo": "^9.0.0",
63 | "util.promisify": "^1.0.0"
64 | },
65 | "devDependencies": {
66 | "@babel/core": "^7.2.2",
67 | "@babel/preset-env": "^7.2.3",
68 | "babel-jest": "^28.1.1",
69 | "husky": "^8.0.1",
70 | "jest": "^28.1.1",
71 | "lint-staged": "^13.0.2",
72 | "prettier": "^2.7.1",
73 | "rimraf": "^3.0.2",
74 | "standard-version": "^9.5.0"
75 | },
76 | "husky": {
77 | "hooks": {
78 | "pre-commit": "lint-staged"
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/tests/__fixtures__/test.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomchentw/imagemin-lint-staged/9882d7cd9b6de02fc6cdf7f1978a2f0096c20e20/tests/__fixtures__/test.gif
--------------------------------------------------------------------------------
/tests/__fixtures__/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomchentw/imagemin-lint-staged/9882d7cd9b6de02fc6cdf7f1978a2f0096c20e20/tests/__fixtures__/test.jpg
--------------------------------------------------------------------------------
/tests/__fixtures__/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tomchentw/imagemin-lint-staged/9882d7cd9b6de02fc6cdf7f1978a2f0096c20e20/tests/__fixtures__/test.png
--------------------------------------------------------------------------------
/tests/__fixtures__/test.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
295 |
--------------------------------------------------------------------------------
/tests/__snapshots__/index.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`index module minifyFile function should work as expected 1`] = `
4 | Array [
5 | Object {
6 | "f": "./__fixtures__/test.gif",
7 | "size": 78080,
8 | },
9 | Object {
10 | "f": "./__fixtures__/test.jpg",
11 | "size": 50986,
12 | },
13 | Object {
14 | "f": "./__fixtures__/test.png",
15 | "size": 71834,
16 | },
17 | Object {
18 | "f": "./__fixtures__/test.svg",
19 | "size": 25118,
20 | },
21 | ]
22 | `;
23 |
24 | exports[`index module minifyFile function should work as expected 2`] = `
25 | Array [
26 | Object {
27 | "f": "./__fixtures__/test.gif",
28 | "size": 80201,
29 | },
30 | Object {
31 | "f": "./__fixtures__/test.jpg",
32 | "size": 45131,
33 | },
34 | Object {
35 | "f": "./__fixtures__/test.png",
36 | "size": 61692,
37 | },
38 | Object {
39 | "f": "./__fixtures__/test.svg",
40 | "size": 20698,
41 | },
42 | ]
43 | `;
44 |
--------------------------------------------------------------------------------
/tests/index.spec.js:
--------------------------------------------------------------------------------
1 | import path from "path";
2 | import fs from "fs";
3 | import child_process from "child_process";
4 | import promisify from "util.promisify";
5 |
6 | const stat = promisify(fs.stat);
7 | const exec = promisify(child_process.exec);
8 |
9 | describe("index module", () => {
10 | const FILENAMES =
11 | "./__fixtures__/test.gif ./__fixtures__/test.jpg ./__fixtures__/test.png ./__fixtures__/test.svg".split(
12 | " "
13 | );
14 |
15 | const stats = () =>
16 | Promise.all(
17 | FILENAMES.map(async (f) => {
18 | const { size } = await stat(path.resolve(__dirname, f));
19 | return { f, size };
20 | })
21 | );
22 |
23 | const { minifyFile } = require("../lib");
24 |
25 | describe("minifyFile function", () => {
26 | it("should work as expected", async () => {
27 | const before = await stats();
28 | await Promise.all(
29 | FILENAMES.map((f) => minifyFile(path.resolve(__dirname, f)))
30 | );
31 | const after = await stats();
32 | await exec(`git checkout .`);
33 | expect(after).not.toEqual(before);
34 |
35 | expect(before).toMatchSnapshot();
36 | expect(after).toMatchSnapshot();
37 | });
38 | });
39 | });
40 |
--------------------------------------------------------------------------------