├── .commitlintrc.json ├── .eslintignore ├── .eslintrc.json ├── .github └── workflows │ ├── publish.yml │ └── release.yml ├── .gitignore ├── .husky ├── commit-msg ├── common.sh └── pre-commit ├── .prettierrc.json ├── .vscode ├── extensions.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README.zh_CN.md ├── package.json ├── packages ├── core │ ├── build.config.ts │ ├── package.json │ └── src │ │ ├── index.ts │ │ ├── types.ts │ │ └── utils.ts └── playground │ └── basic │ ├── .gitignore │ ├── index.html │ ├── package.json │ ├── public │ ├── favicon.ico │ └── images │ │ ├── static-test.gif │ │ ├── static-test.jpg │ │ ├── static-test.png │ │ └── static-test.svg │ ├── shim-vue.ts │ ├── src │ ├── App.vue │ ├── assets │ │ ├── test.gif │ │ ├── test.jpg │ │ ├── test.png │ │ └── test.svg │ └── main.ts │ ├── tsconfig.json │ └── vite.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── tsconfig.json └── vitest.config.ts /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "browser": true, 5 | "es2021": true, 6 | "es6": true, 7 | "node": true 8 | }, 9 | "extends": [ 10 | "eslint:recommended", 11 | "plugin:@typescript-eslint/recommended", 12 | "prettier" 13 | ], 14 | "parser": "@typescript-eslint/parser", 15 | "parserOptions": { 16 | "ecmaVersion": 12, 17 | "sourceType": "module" 18 | }, 19 | "plugins": ["@typescript-eslint"], 20 | "rules": { 21 | "no-console": 1, 22 | "@typescript-eslint/no-non-null-assertion": "off", 23 | "@typescript-eslint/ban-ts-comment": "off", 24 | "@typescript-eslint/no-explicit-any": "off" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Npm Publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | publish-npm: 10 | if: "contains(github.event.head_commit.message, 'release')" 11 | runs-on: ${{matrix.os}} 12 | 13 | strategy: 14 | matrix: 15 | os: [ubuntu-latest] 16 | node-version: [16.x] 17 | fail-fast: false 18 | 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v2 22 | 23 | - name: Install pnpm 24 | uses: pnpm/action-setup@v2.0.1 25 | with: 26 | version: 6.28.0 27 | 28 | - name: Use Node.js ${{ matrix.node-version }} 29 | uses: actions/setup-node@v2 30 | with: 31 | node-version: ${{ matrix.node-version }} 32 | registry-url: https://registry.npmjs.org/ 33 | cache: 'pnpm' 34 | 35 | - name: Install Dependencies 36 | run: pnpm install 37 | 38 | - name: Publish to NPM 39 | run: pnpm -r publish --access public --no-git-checks 40 | env: 41 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 42 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - v* 7 | 8 | jobs: 9 | build: 10 | name: Create Release 11 | runs-on: ${{matrix.os}} 12 | 13 | strategy: 14 | matrix: 15 | os: [ubuntu-latest] 16 | fail-fast: false 17 | 18 | steps: 19 | - name: Checkout code 20 | uses: actions/checkout@master 21 | 22 | - name: Create Release for Tag 23 | id: release_tag 24 | uses: yyx990803/release-tag@master 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.OPER_TOKEN }} 27 | with: 28 | tag_name: ${{ github.ref }} 29 | body: | 30 | Please refer to [CHANGELOG.md](https://github.com/anncwb/vite-plugin-imagemin/blob/main/CHANGELOG.md) for details. 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | es 5 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # shellcheck source=./_/husky.sh 4 | . "$(dirname "$0")/_/husky.sh" 5 | 6 | npx --no-install commitlint --edit "$1" 7 | -------------------------------------------------------------------------------- /.husky/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | command_exists () { 3 | command -v "$1" >/dev/null 2>&1 4 | } 5 | 6 | # Workaround for Windows 10, Git Bash and Yarn 7 | if command_exists winpty && test -t 1; then 8 | exec < /dev/tty 9 | fi 10 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | . "$(dirname "$0")/common.sh" 4 | 5 | [ -n "$CI" ] && exit 0 6 | 7 | # Format and submit code according to lintstagedrc.js configuration 8 | pnpm exec lint-staged --concurrent false 9 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "printWidth": 80, 6 | "trailingComma": "all" 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "octref.vetur", 4 | "dbaeumer.vscode-eslint", 5 | "stylelint.vscode-stylelint", 6 | "esbenp.prettier-vscode", 7 | "mrmlnc.vscode-less", 8 | "lokalise.i18n-ally", 9 | "antfu.iconify", 10 | "mikestead.dotenv", 11 | "heybourn.headwind" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "./node_modules/typescript/lib", 3 | "typescript.enablePromptUseWorkspaceTsdk": true, 4 | //=========================================== 5 | //============= Editor ====================== 6 | //=========================================== 7 | "explorer.openEditors.visible": 0, 8 | "editor.tabSize": 2, 9 | "editor.defaultFormatter": "esbenp.prettier-vscode", 10 | "diffEditor.ignoreTrimWhitespace": false, 11 | //=========================================== 12 | //============= Other ======================= 13 | //=========================================== 14 | "breadcrumbs.enabled": true, 15 | "open-in-browser.default": "chrome", 16 | //=========================================== 17 | //============= files ======================= 18 | //=========================================== 19 | "files.eol": "\n", 20 | "search.exclude": { 21 | "**/node_modules": true, 22 | "**/*.log": true, 23 | "**/*.log*": true, 24 | "**/bower_components": true, 25 | "**/dist": true, 26 | "**/elehukouben": true, 27 | "**/.git": true, 28 | "**/.gitignore": true, 29 | "**/.svn": true, 30 | "**/.DS_Store": true, 31 | "**/.idea": true, 32 | "**/.vscode": false, 33 | "**/yarn.lock": true, 34 | "**/tmp": true, 35 | "out": true, 36 | "dist": true, 37 | "node_modules": true, 38 | "CHANGELOG.md": true, 39 | "examples": true, 40 | "res": true, 41 | "screenshots": true, 42 | "yarn-error.log": true, 43 | "**/.yarn": true 44 | }, 45 | "files.exclude": { 46 | "**/.cache": true, 47 | "**/.editorconfig": true, 48 | "**/.eslintcache": true, 49 | "**/bower_components": true, 50 | "**/.idea": true, 51 | "**/tmp": true, 52 | "**/.git": true, 53 | "**/.svn": true, 54 | "**/.hg": true, 55 | "**/CVS": true, 56 | "**/.DS_Store": true 57 | }, 58 | "files.watcherExclude": { 59 | "**/.git/objects/**": true, 60 | "**/.git/subtree-cache/**": true, 61 | "**/.vscode/**": true, 62 | "**/node_modules/**": true, 63 | "**/tmp/**": true, 64 | "**/bower_components/**": true, 65 | "**/dist/**": true, 66 | "**/yarn.lock": true 67 | }, 68 | "stylelint.enable": true, 69 | "stylelint.packageManager": "yarn", 70 | "liveServer.settings.donotShowInfoMsg": true, 71 | "workbench.settings.enableNaturalLanguageSearch": false, 72 | "prettier.requireConfig": true, 73 | "workbench.sideBar.location": "left", 74 | "cSpell.words": [ 75 | "vben", 76 | "windi", 77 | "browserslist", 78 | "tailwindcss", 79 | "esnext", 80 | "antv", 81 | "tinymce", 82 | "qrcode", 83 | "sider", 84 | "pinia", 85 | "sider", 86 | "nprogress", 87 | "INTLIFY", 88 | "stylelint", 89 | "esno", 90 | "vitejs", 91 | "sortablejs", 92 | "mockjs", 93 | "codemirror", 94 | "iconify", 95 | "commitlint", 96 | "vditor", 97 | "echarts", 98 | "cropperjs", 99 | "logicflow", 100 | "vueuse", 101 | "zxcvbn", 102 | "lintstagedrc", 103 | "brotli", 104 | "tailwindcss", 105 | "sider" 106 | ] 107 | } 108 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.6.1](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.5.2...v0.6.1) (2022-01-29) 2 | 3 | ### Bug Fixes 4 | 5 | - mjs support ([1285598](https://github.com/anncwb/vite-plugin-imagemin/commit/12855987d015925d482d5c0e4a5e5ebd48676156)) 6 | 7 | ## [0.5.3](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.5.2...v0.5.3) (2022-01-27) 8 | 9 | ## [0.5.3](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.5.2...v0.5.3) (2022-01-27) 10 | 11 | ## [0.5.2](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.4.6...v0.5.2) (2022-01-24) 12 | 13 | # [0.5.0](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.4.6...v0.5.0) (2021-12-28) 14 | 15 | ### Performance Improvements 16 | 17 | - refactor image compression logic ([166a9a5](https://github.com/anncwb/vite-plugin-imagemin/commit/166a9a5dd62105a156aeabab91574ccd69f5f1be)) 18 | 19 | ## [0.4.6](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.3.0...v0.4.6) (2021-09-27) 20 | 21 | ### Bug Fixes 22 | 23 | - readme ([094b500](https://github.com/anncwb/vite-plugin-imagemin/commit/094b500cc55f8e768e6ccf1394c9b46fbc5a8388)) 24 | 25 | ### Features 26 | 27 | - support svgo2 ([aa81b70](https://github.com/anncwb/vite-plugin-imagemin/commit/aa81b706498567a7b43c19927802abafb2cc754d)) 28 | 29 | ## [0.4.4](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.3.0...v0.4.4) (2021-08-23) 30 | 31 | ### Features 32 | 33 | - support svgo2 ([aa81b70](https://github.com/anncwb/vite-plugin-imagemin/commit/aa81b706498567a7b43c19927802abafb2cc754d)) 34 | 35 | # [0.4.0](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.3.0...v0.4.0) (2021-07-05) 36 | 37 | ### Features 38 | 39 | - support svgo2 ([aa81b70](https://github.com/anncwb/vite-plugin-imagemin/commit/aa81b706498567a7b43c19927802abafb2cc754d)) 40 | 41 | ## [0.3.2](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.3.0...v0.3.2) (2021-05-09) 42 | 43 | ## [0.3.1](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.3.0...v0.3.1) (2021-05-09) 44 | 45 | # [0.3.0](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.2.9...v0.3.0) (2021-04-03) 46 | 47 | ## [0.2.9](https://github.com/anncwb/vite-plugin-imagemin/compare/v0.2.8...v0.2.9) (2021-03-02) 48 | 49 | ## 0.2.7 (2021-02-22) 50 | 51 | ### Bug Fixes 52 | 53 | - fix window path ([f313847](https://github.com/anncwb/vite-plugin-imagemin/commit/f313847f0d6be9f30cb1ab28cef83acd27682794)) 54 | - webp default false ([13feff9](https://github.com/anncwb/vite-plugin-imagemin/commit/13feff90ea0310ab64c153762c73f01057ffe3cb)) 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-present, Vben 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vite-plugin-imagemin 2 | 3 | **English** | [中文](./README.zh_CN.md) 4 | 5 | [![npm][npm-img]][npm-url] [![node][node-img]][node-url] 6 | 7 | A vite plugin for compressing image assets 8 | 9 | ## Install (yarn or npm) 10 | 11 | **node version:** >=12.0.0 12 | 13 | **vite version:** >=2.0.0 14 | 15 | ``` 16 | yarn add vite-plugin-imagemin -D 17 | ``` 18 | 19 | or 20 | 21 | ``` 22 | npm i vite-plugin-imagemin -D 23 | ``` 24 | 25 | ### China installation note 26 | 27 | Because imagemin is not easy to install in China. Several solutions are now available 28 | 29 | 1. Use yarn to configure in package.json (recommended) 30 | 31 | ```json 32 | "resolutions": { 33 | "bin-wrapper": "npm:bin-wrapper-china" 34 | }, 35 | 36 | ``` 37 | 38 | 2. Use npm, add the following configuration to the computer host file 39 | 40 | ```bash 41 | 42 | 199.232.4.133 raw.githubusercontent.com 43 | ``` 44 | 45 | 3. Install with cnpm (not recommended) 46 | 47 | ## Usage 48 | 49 | - Configuration plugin in vite.config.ts 50 | 51 | ```ts 52 | import viteImagemin from 'vite-plugin-imagemin' 53 | 54 | export default () => { 55 | return { 56 | plugins: [ 57 | viteImagemin({ 58 | gifsicle: { 59 | optimizationLevel: 7, 60 | interlaced: false, 61 | }, 62 | optipng: { 63 | optimizationLevel: 7, 64 | }, 65 | mozjpeg: { 66 | quality: 20, 67 | }, 68 | pngquant: { 69 | quality: [0.8, 0.9], 70 | speed: 4, 71 | }, 72 | svgo: { 73 | plugins: [ 74 | { 75 | name: 'removeViewBox', 76 | }, 77 | { 78 | name: 'removeEmptyAttrs', 79 | active: false, 80 | }, 81 | ], 82 | }, 83 | }), 84 | ], 85 | } 86 | } 87 | ``` 88 | 89 | ### Options 90 | 91 | | params | type | default | default | 92 | | -------- | ------------------------------------- | ------- | ------------------------------------------------------------ | 93 | | verbose | `boolean` | `true` | Whether to output the compressed result in the console | 94 | | filter | `RegExp or (file: string) => boolean` | - | Specify which resources are not compressed | 95 | | disable | `boolean` | `false` | Whether to disable | 96 | | svgo | `object` or `false` | - | See [Options](https://github.com/svg/svgo/#what-it-can-do) | 97 | | gifsicle | `object` or `false` | - | See [Options](https://github.com/imagemin/imagemin-gifsicle) | 98 | | mozjpeg | `object` or `false` | - | See [Options](https://github.com/imagemin/imagemin-mozjpeg) | 99 | | optipng | `object` or `false` | - | See [Options](https://github.com/imagemin/imagemin-optipng) | 100 | | pngquant | `object` or `false` | - | See [Options](https://github.com/imagemin/imagemin-pngquant) | 101 | | webp | `object` or `false` | - | See [Options](https://github.com/imagemin/imagemin-webp) | 102 | 103 | ## Example 104 | 105 | **Run Example** 106 | 107 | ```bash 108 | 109 | npm run dev:play 110 | npm run dev:build 111 | 112 | ``` 113 | 114 | ## Sample project 115 | 116 | [Vben Admin](https://github.com/anncwb/vue-vben-admin) 117 | 118 | ## License 119 | 120 | MIT 121 | 122 | ## Inspiration 123 | 124 | [vite-plugin-compress](https://github.com/alloc/vite-plugin-compress) 125 | 126 | [npm-img]: https://img.shields.io/npm/v/vite-plugin-imagemin.svg 127 | [npm-url]: https://npmjs.com/package/vite-plugin-imagemin 128 | [node-img]: https://img.shields.io/node/v/vite-plugin-imagemin.svg 129 | [node-url]: https://nodejs.org/en/about/releases/ 130 | -------------------------------------------------------------------------------- /README.zh_CN.md: -------------------------------------------------------------------------------- 1 | # vite-plugin-imagemin 2 | 3 | **中文** | [English](./README.md) 4 | 5 | [![npm][npm-img]][npm-url] [![node][node-img]][node-url] 6 | 7 | 一个压缩图片资产的 vite 插件 8 | 9 | ## 安装 (yarn or npm) 10 | 11 | **node version:** >=12.0.0 12 | 13 | **vite version:** >=2.0.0 14 | 15 | ``` 16 | yarn add vite-plugin-imagemin -D 17 | ``` 18 | 19 | or 20 | 21 | ``` 22 | npm i vite-plugin-imagemin -D 23 | ``` 24 | 25 | ### 中国安装注意 26 | 27 | 由于 imagemin 在中国不好安装。现提供几个解决方案 28 | 29 | 1. 使用 yarn 在 package.json 内配置(推荐) 30 | 31 | ```json 32 | "resolutions": { 33 | "bin-wrapper": "npm:bin-wrapper-china" 34 | }, 35 | 36 | ``` 37 | 38 | 2. 使用 npm,在电脑 host 文件加上如下配置即可 39 | 40 | ```bash 41 | 42 | 199.232.4.133 raw.githubusercontent.com 43 | ``` 44 | 45 | 3. 使用 cnpm 安装(不推荐) 46 | 47 | ## 使用 48 | 49 | - vite.config.ts 中的配置插件 50 | 51 | ```ts 52 | import viteImagemin from 'vite-plugin-imagemin' 53 | 54 | export default () => { 55 | return { 56 | plugins: [ 57 | viteImagemin({ 58 | gifsicle: { 59 | optimizationLevel: 7, 60 | interlaced: false, 61 | }, 62 | optipng: { 63 | optimizationLevel: 7, 64 | }, 65 | mozjpeg: { 66 | quality: 20, 67 | }, 68 | pngquant: { 69 | quality: [0.8, 0.9], 70 | speed: 4, 71 | }, 72 | svgo: { 73 | plugins: [ 74 | { 75 | name: 'removeViewBox', 76 | }, 77 | { 78 | name: 'removeEmptyAttrs', 79 | active: false, 80 | }, 81 | ], 82 | }, 83 | }), 84 | ], 85 | } 86 | } 87 | ``` 88 | 89 | ### 配置说明 90 | 91 | | 参数 | 类型 | 默认值 | 说明 | 92 | | -------- | ------------------------------------- | ------- | ----------------------------------------------------------- | 93 | | verbose | `boolean` | `true` | 是否在控制台输出压缩结果 | 94 | | filter | `RegExp or (file: string) => boolean` | - | 指定哪些资源不压缩 | 95 | | disable | `boolean` | `false` | 是否禁用 | 96 | | svgo | `object` or `false` | - | 见 [Options](https://github.com/svg/svgo/#what-it-can-do) | 97 | | gifsicle | `object` or `false` | - | 见 [Options](https://github.com/imagemin/imagemin-gifsicle) | 98 | | mozjpeg | `object` or `false` | - | 见 [Options](https://github.com/imagemin/imagemin-mozjpeg) | 99 | | optipng | `object` or `false` | - | 见 [Options](https://github.com/imagemin/imagemin-optipng) | 100 | | pngquant | `object` or `false` | - | 见 [Options](https://github.com/imagemin/imagemin-pngquant) | 101 | | webp | `object` or `false` | - | 见 [Options](https://github.com/imagemin/imagemin-webp) | 102 | 103 | ## 示例 104 | 105 | **运行示例** 106 | 107 | ```bash 108 | npm run dev:play 109 | npm run dev:build 110 | ``` 111 | 112 | ## 示例项目 113 | 114 | [Vben Admin](https://github.com/anncwb/vue-vben-admin) 115 | 116 | ## License 117 | 118 | MIT 119 | 120 | ## 灵感 121 | 122 | [vite-plugin-compress](https://github.com/alloc/vite-plugin-compress) 123 | 124 | [npm-img]: https://img.shields.io/npm/v/vite-plugin-style-import.svg 125 | [npm-url]: https://npmjs.com/package/vite-plugin-style-import 126 | [node-img]: https://img.shields.io/node/v/vite-plugin-style-import.svg 127 | [node-url]: https://nodejs.org/en/about/releases/ 128 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-plugin-imagemin-monorepo", 3 | "private": true, 4 | "version": "0.6.1", 5 | "description": "A vite plugin for compressing image assets", 6 | "license": "MIT", 7 | "author": "Vben", 8 | "scripts": { 9 | "dev:play": "pnpm run dev --filter playground-basic", 10 | "build:play": "pnpm run build --filter playground-basic", 11 | "stub": "pnpm run prepack --filter ./packages -- --stub", 12 | "postinstall": "pnpm run stub", 13 | "log": "conventional-changelog -p angular -i CHANGELOG.md -s", 14 | "lint:pretty": "pretty-quick --staged", 15 | "lint:eslint": "eslint \"packages/**/*.{ts,tsx}\" --fix", 16 | "prepare": "husky install", 17 | "preinstall": "npx only-allow pnpm", 18 | "test": "vitest" 19 | }, 20 | "keywords": [ 21 | "vite", 22 | "vite-plugin", 23 | "imagemin", 24 | "vben" 25 | ], 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/anncwb/vite-plugin-imagemin" 29 | }, 30 | "bugs": { 31 | "url": "https://github.com/anncwb/vite-plugin-imagemin/issues" 32 | }, 33 | "homepage": "https://github.com/anncwb/vite-plugin-imagemin/tree/master/#readme", 34 | "peerDependencies": { 35 | "vite": ">=2.0.0" 36 | }, 37 | "resolutions": { 38 | "bin-wrapper": "npm:bin-wrapper-china", 39 | "gifsicle": "5.2.0" 40 | }, 41 | "devDependencies": { 42 | "@commitlint/cli": "^16.1.0", 43 | "@commitlint/config-conventional": "^16.0.0", 44 | "@types/html-minifier-terser": "^6.1.0", 45 | "@types/jsdom": "^16.2.14", 46 | "@types/node": "^17.0.12", 47 | "@typescript-eslint/eslint-plugin": "^5.10.1", 48 | "@typescript-eslint/parser": "^5.10.1", 49 | "commitizen": "^4.2.4", 50 | "conventional-changelog-cli": "^2.2.2", 51 | "cross-env": "^7.0.3", 52 | "eslint": "^8.7.0", 53 | "eslint-config-prettier": "^8.3.0", 54 | "eslint-plugin-html": "^6.2.0", 55 | "husky": "^7.0.4", 56 | "lint-staged": "^12.3.2", 57 | "prettier": "^2.5.1", 58 | "rimraf": "^3.0.2", 59 | "tsup": "^5.11.11", 60 | "typescript": "^4.5.5", 61 | "unbuild": "^0.6.8", 62 | "vite": "^2.7.13", 63 | "vitest": "^0.2.4" 64 | }, 65 | "lint-staged": { 66 | "*": [ 67 | "prettier --write --ignore-unknown" 68 | ], 69 | "packages/*/{src,types}/**/*.ts": [ 70 | "eslint --ext .ts" 71 | ], 72 | "packages/**/*.d.ts": [ 73 | "eslint --ext .ts" 74 | ] 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /packages/core/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | clean: true, 5 | entries: ['./src/index'], 6 | declaration: true, 7 | rollup: { 8 | emitCJS: true, 9 | }, 10 | }) 11 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-plugin-imagemin", 3 | "version": "0.6.1", 4 | "description": "A vite plugin for compressing image assets", 5 | "main": "dist/index.cjs", 6 | "module": "dist/index.mjs", 7 | "types": "dist/index.d.ts", 8 | "exports": { 9 | ".": { 10 | "require": "./dist/index.cjs", 11 | "import": "./dist/index.mjs", 12 | "types": "./dist/index.d.ts" 13 | } 14 | }, 15 | "license": "MIT", 16 | "author": "Vben", 17 | "files": [ 18 | "dist" 19 | ], 20 | "scripts": { 21 | "dev": "pnpm unbuild --stub", 22 | "build": "pnpm unbuild", 23 | "prepublishOnly": "npm run build", 24 | "prepack": "pnpm unbuild" 25 | }, 26 | "keywords": [ 27 | "vite", 28 | "vite-plugin", 29 | "imagemin", 30 | "vben" 31 | ], 32 | "repository": { 33 | "type": "git", 34 | "url": "https://github.com/anncwb/vite-plugin-imagemin", 35 | "directory": "packages/core" 36 | }, 37 | "bugs": { 38 | "url": "https://github.com/anncwb/vite-plugin-imagemin/issues" 39 | }, 40 | "homepage": "https://github.com/anncwb/vite-plugin-imagemin/tree/master/#readme", 41 | "dependencies": { 42 | "@types/imagemin": "^7.0.1", 43 | "@types/imagemin-gifsicle": "^7.0.1", 44 | "@types/imagemin-jpegtran": "^5.0.1", 45 | "@types/imagemin-mozjpeg": "^8.0.1", 46 | "@types/imagemin-optipng": "^5.2.1", 47 | "@types/imagemin-svgo": "^10.0.0", 48 | "@types/imagemin-webp": "^7.0.0", 49 | "@types/svgo": "^2.6.1", 50 | "chalk": "^4.1.2", 51 | "debug": "^4.3.3", 52 | "esbuild": "^0.14.14", 53 | "fs-extra": "^10.0.0", 54 | "gifsicle": "5.2.0", 55 | "imagemin": "^7.0.1", 56 | "imagemin-gifsicle": "^7.0.0", 57 | "imagemin-jpegtran": "^7.0.0", 58 | "imagemin-mozjpeg": "^9.0.0", 59 | "imagemin-optipng": "^8.0.0", 60 | "imagemin-pngquant": "^9.0.2", 61 | "imagemin-svgo": "^9.0.0", 62 | "imagemin-webp": "^6.0.0", 63 | "jpegtran-bin": "^6.0.1", 64 | "pathe": "^0.2.0" 65 | }, 66 | "peerDependencies": { 67 | "vite": ">=2.0.0" 68 | }, 69 | "resolutions": { 70 | "bin-wrapper": "npm:bin-wrapper-china", 71 | "gifsicle": "5.2.0" 72 | }, 73 | "devDependencies": { 74 | "@types/chalk": "^2.2.0", 75 | "@types/debug": "^4.1.7", 76 | "@types/fs-extra": "^9.0.13", 77 | "@types/node": "^17.0.12", 78 | "vite": "^2.7.13" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { Plugin, ResolvedConfig } from 'vite' 2 | import type { VitePluginImageMin } from './types' 3 | import path from 'pathe' 4 | import fs from 'fs-extra' 5 | import { 6 | isNotFalse, 7 | isBoolean, 8 | isRegExp, 9 | isFunction, 10 | readAllFiles, 11 | } from '../src/utils' 12 | import chalk from 'chalk' 13 | import Debug from 'debug' 14 | 15 | import imagemin from 'imagemin' 16 | import imageminGif from 'imagemin-gifsicle' 17 | import imageminPng from 'imagemin-pngquant' 18 | import imageminOptPng from 'imagemin-optipng' 19 | import imageminJpeg from 'imagemin-mozjpeg' 20 | import imageminSvgo from 'imagemin-svgo' 21 | import imageminWebp from 'imagemin-webp' 22 | import imageminJpegTran from 'imagemin-jpegtran' 23 | 24 | const debug = Debug.debug('vite-plugin-imagemin') 25 | 26 | const extRE = /\.(png|jpeg|gif|jpg|bmp|svg)$/i 27 | 28 | export default function (options: VitePluginImageMin = {}) { 29 | let outputPath: string 30 | let publicDir: string 31 | let config: ResolvedConfig 32 | 33 | const { disable = false, filter = extRE, verbose = true } = options 34 | 35 | if (disable) { 36 | return {} as any 37 | } 38 | 39 | debug('plugin options:', options) 40 | 41 | const mtimeCache = new Map() 42 | let tinyMap = new Map< 43 | string, 44 | { size: number; oldSize: number; ratio: number } 45 | >() 46 | 47 | async function processFile(filePath: string, buffer: Buffer) { 48 | let content: Buffer 49 | 50 | try { 51 | content = await imagemin.buffer(buffer, { 52 | plugins: getImageminPlugins(options), 53 | }) 54 | 55 | const size = content.byteLength, 56 | oldSize = buffer.byteLength 57 | 58 | tinyMap.set(filePath, { 59 | size: size / 1024, 60 | oldSize: oldSize / 1024, 61 | ratio: size / oldSize - 1, 62 | }) 63 | 64 | return content 65 | } catch (error) { 66 | config.logger.error('imagemin error:' + filePath) 67 | } 68 | } 69 | 70 | return { 71 | name: 'vite:imagemin', 72 | apply: 'build', 73 | enforce: 'post', 74 | configResolved(resolvedConfig) { 75 | config = resolvedConfig 76 | outputPath = config.build.outDir 77 | 78 | // get public static assets directory: https://vitejs.dev/guide/assets.html#the-public-directory 79 | if (typeof config.publicDir === 'string') { 80 | publicDir = config.publicDir 81 | } 82 | 83 | debug('resolvedConfig:', resolvedConfig) 84 | }, 85 | async generateBundle(_, bundler) { 86 | tinyMap = new Map() 87 | const files: string[] = [] 88 | 89 | Object.keys(bundler).forEach((key) => { 90 | filterFile(path.resolve(outputPath, key), filter) && files.push(key) 91 | }) 92 | 93 | debug('files:', files) 94 | 95 | if (!files.length) { 96 | return 97 | } 98 | 99 | const handles = files.map(async (filePath: string) => { 100 | const source = (bundler[filePath] as any).source 101 | const content = await processFile(filePath, source) 102 | if (content) { 103 | ;(bundler[filePath] as any).source = content 104 | } 105 | }) 106 | 107 | await Promise.all(handles) 108 | }, 109 | async closeBundle() { 110 | if (publicDir) { 111 | const files: string[] = [] 112 | 113 | // try to find any static images in original static folder 114 | readAllFiles(publicDir).forEach((file) => { 115 | filterFile(file, filter) && files.push(file) 116 | }) 117 | 118 | if (files.length) { 119 | const handles = files.map(async (publicFilePath: string) => { 120 | // now convert the path to the output folder 121 | const filePath = publicFilePath.replace(publicDir + path.sep, '') 122 | const fullFilePath = path.join(outputPath, filePath) 123 | 124 | if (fs.existsSync(fullFilePath) === false) { 125 | return 126 | } 127 | 128 | const { mtimeMs } = await fs.stat(fullFilePath) 129 | if (mtimeMs <= (mtimeCache.get(filePath) || 0)) { 130 | return 131 | } 132 | 133 | const buffer = await fs.readFile(fullFilePath) 134 | const content = await processFile(filePath, buffer) 135 | 136 | if (content) { 137 | await fs.writeFile(fullFilePath, content) 138 | mtimeCache.set(filePath, Date.now()) 139 | } 140 | }) 141 | 142 | await Promise.all(handles) 143 | } 144 | } 145 | 146 | if (verbose) { 147 | handleOutputLogger(config, tinyMap) 148 | } 149 | }, 150 | } as Plugin 151 | } 152 | 153 | // Packed output logic 154 | function handleOutputLogger( 155 | config: ResolvedConfig, 156 | recordMap: Map, 157 | ) { 158 | config.logger.info( 159 | `\n${chalk.cyan('✨ [vite-plugin-imagemin]')}` + 160 | '- compressed image resource successfully: ', 161 | ) 162 | 163 | const keyLengths = Array.from(recordMap.keys(), (name) => name.length) 164 | const valueLengths = Array.from( 165 | recordMap.values(), 166 | (value) => `${Math.floor(100 * value.ratio)}`.length, 167 | ) 168 | 169 | const maxKeyLength = Math.max(...keyLengths) 170 | const valueKeyLength = Math.max(...valueLengths) 171 | recordMap.forEach((value, name) => { 172 | let { ratio } = value 173 | const { size, oldSize } = value 174 | ratio = Math.floor(100 * ratio) 175 | const fr = `${ratio}` 176 | 177 | const denseRatio = 178 | ratio > 0 ? chalk.red(`+${fr}%`) : ratio <= 0 ? chalk.green(`${fr}%`) : '' 179 | 180 | const sizeStr = `${oldSize.toFixed(2)}kb / tiny: ${size.toFixed(2)}kb` 181 | 182 | config.logger.info( 183 | chalk.dim(path.basename(config.build.outDir)) + 184 | '/' + 185 | chalk.blueBright(name) + 186 | ' '.repeat(2 + maxKeyLength - name.length) + 187 | chalk.gray(`${denseRatio} ${' '.repeat(valueKeyLength - fr.length)}`) + 188 | ' ' + 189 | chalk.dim(sizeStr), 190 | ) 191 | }) 192 | config.logger.info('\n') 193 | } 194 | 195 | function filterFile( 196 | file: string, 197 | filter: RegExp | ((file: string) => boolean), 198 | ) { 199 | if (filter) { 200 | const isRe = isRegExp(filter) 201 | const isFn = isFunction(filter) 202 | if (isRe) { 203 | return (filter as RegExp).test(file) 204 | } 205 | if (isFn) { 206 | return (filter as (file: any) => any)(file) 207 | } 208 | } 209 | return false 210 | } 211 | 212 | // imagemin compression plugin configuration 213 | function getImageminPlugins( 214 | options: VitePluginImageMin = {}, 215 | ): imagemin.Plugin[] { 216 | const { 217 | gifsicle = true, 218 | webp = false, 219 | mozjpeg = false, 220 | pngquant = false, 221 | optipng = true, 222 | svgo = true, 223 | jpegTran = true, 224 | } = options 225 | 226 | const plugins: imagemin.Plugin[] = [] 227 | 228 | if (isNotFalse(gifsicle)) { 229 | debug('gifsicle:', true) 230 | const opt = isBoolean(gifsicle) ? undefined : gifsicle 231 | plugins.push(imageminGif(opt)) 232 | } 233 | 234 | if (isNotFalse(mozjpeg)) { 235 | debug('mozjpeg:', true) 236 | const opt = isBoolean(mozjpeg) ? undefined : mozjpeg 237 | plugins.push(imageminJpeg(opt)) 238 | } 239 | 240 | if (isNotFalse(pngquant)) { 241 | debug('pngquant:', true) 242 | const opt = isBoolean(pngquant) ? undefined : pngquant 243 | plugins.push(imageminPng(opt)) 244 | } 245 | 246 | if (isNotFalse(optipng)) { 247 | debug('optipng:', true) 248 | const opt = isBoolean(optipng) ? undefined : optipng 249 | plugins.push(imageminOptPng(opt)) 250 | } 251 | 252 | if (isNotFalse(svgo)) { 253 | debug('svgo:', true) 254 | const opt = isBoolean(svgo) ? undefined : svgo 255 | 256 | // if (opt !== null && isObject(opt) && Reflect.has(opt, 'plugins')) { 257 | // (opt as any).plugins.push({ 258 | // name: 'preset-default', 259 | // }); 260 | // } 261 | plugins.push(imageminSvgo(opt)) 262 | } 263 | 264 | if (isNotFalse(webp)) { 265 | debug('webp:', true) 266 | const opt = isBoolean(webp) ? undefined : webp 267 | plugins.push(imageminWebp(opt)) 268 | } 269 | 270 | if (isNotFalse(jpegTran)) { 271 | debug('webp:', true) 272 | const opt = isBoolean(jpegTran) ? undefined : jpegTran 273 | plugins.push(imageminJpegTran(opt)) 274 | } 275 | return plugins 276 | } 277 | -------------------------------------------------------------------------------- /packages/core/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { Options as GifsicleOptions } from 'imagemin-gifsicle' 2 | import type { Options as SvgoOptions } from 'imagemin-svgo' 3 | import type { Options as MozjpegOptions } from 'imagemin-mozjpeg' 4 | import type { Options as OptipngOptions } from 'imagemin-optipng' 5 | import type { Options as PngquantOptions } from 'imagemin-pngquant' 6 | import type { Options as WebpOptions } from 'imagemin-webp' 7 | import type { Options as JpegOptions } from 'imagemin-jpegtran' 8 | 9 | type EnabledOptions = T | false 10 | 11 | export interface SvgOption extends SvgoOptions { 12 | plugins: any[] 13 | } 14 | 15 | export interface VitePluginImageMin { 16 | /** 17 | * Log compressed files and their compression ratios. 18 | * @default: true 19 | */ 20 | verbose?: boolean 21 | /** 22 | * Filter files that do not need to be compressed 23 | */ 24 | filter?: RegExp | ((file: string) => boolean) 25 | /** 26 | * Whether to enable compression 27 | * @default: false 28 | */ 29 | disable?: boolean 30 | /** 31 | * gif compression configuration 32 | * @default: {enabled:true} 33 | */ 34 | gifsicle?: EnabledOptions 35 | /** 36 | * svg compression configuration 37 | * @default: {enabled:true} 38 | */ 39 | svgo?: EnabledOptions 40 | /** 41 | * jpeg compression configuration 42 | * @default: {enabled:false} 43 | */ 44 | mozjpeg?: EnabledOptions 45 | /** 46 | * png compression configuration 47 | * @default: {enabled:true} 48 | */ 49 | optipng?: EnabledOptions 50 | /** 51 | * png compression configuration 52 | * @default: {enabled:false} 53 | */ 54 | pngquant?: EnabledOptions 55 | /** 56 | * webp compression configuration 57 | * @default: {enabled:false} 58 | */ 59 | webp?: EnabledOptions 60 | 61 | /** 62 | * jpeg compression configuration 63 | * @default: {enabled:true} 64 | */ 65 | jpegTran?: EnabledOptions 66 | } 67 | -------------------------------------------------------------------------------- /packages/core/src/utils.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs-extra' 2 | import path from 'path' 3 | 4 | export const isFunction = (arg: unknown): arg is (...args: any[]) => any => 5 | typeof arg === 'function' 6 | 7 | export const isBoolean = (arg: unknown): arg is boolean => { 8 | return typeof arg === 'boolean' 9 | } 10 | 11 | export const isObject = (arg: unknown): arg is boolean => { 12 | return typeof arg === 'object' 13 | } 14 | 15 | export const isNotFalse = (arg: unknown): arg is boolean => { 16 | return !(isBoolean(arg) && !arg) 17 | } 18 | 19 | export const isRegExp = (arg: unknown): arg is RegExp => 20 | Object.prototype.toString.call(arg) === '[object RegExp]' 21 | 22 | /* 23 | * Read all files in the specified folder, filter through regular rules, and return file path array 24 | * @param root Specify the folder path 25 | * [@param] reg Regular expression for filtering files, optional parameters 26 | * Note: It can also be deformed to check whether the file path conforms to regular rules. The path can be a folder or a file. The path that does not exist is also fault-tolerant. 27 | */ 28 | export function readAllFiles(root: string, reg?: RegExp) { 29 | let resultArr: string[] = [] 30 | try { 31 | if (fs.existsSync(root)) { 32 | const stat = fs.lstatSync(root) 33 | if (stat.isDirectory()) { 34 | // dir 35 | const files = fs.readdirSync(root) 36 | files.forEach(function (file) { 37 | const t = readAllFiles(path.join(root, '/', file), reg) 38 | resultArr = resultArr.concat(t) 39 | }) 40 | } else { 41 | if (reg !== undefined) { 42 | if (isFunction(reg.test) && reg.test(root)) { 43 | resultArr.push(root) 44 | } 45 | } else { 46 | resultArr.push(root) 47 | } 48 | } 49 | } 50 | } catch (error) { 51 | console.log(error) 52 | } 53 | 54 | return resultArr 55 | } 56 | -------------------------------------------------------------------------------- /packages/playground/basic/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | *.local -------------------------------------------------------------------------------- /packages/playground/basic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/playground/basic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "playground-basic", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build " 8 | }, 9 | "dependencies": { 10 | "fast-glob": "^3.2.11", 11 | "vue": "^3.2.29" 12 | }, 13 | "devDependencies": { 14 | "@vitejs/plugin-legacy": "^1.6.4", 15 | "@vitejs/plugin-vue": "^2.1.0", 16 | "@vitejs/plugin-vue-jsx": "^1.3.3", 17 | "@vue/compiler-sfc": "^3.2.29", 18 | "cross-env": "^7.0.3", 19 | "typescript": "^4.5.5", 20 | "vite": "^2.7.13", 21 | "vite-plugin-imagemin": "workspace:*" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/playground/basic/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbenjs/vite-plugin-imagemin/fcbe8aa9f0608da0c1800a51dfb108b5288f00f6/packages/playground/basic/public/favicon.ico -------------------------------------------------------------------------------- /packages/playground/basic/public/images/static-test.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbenjs/vite-plugin-imagemin/fcbe8aa9f0608da0c1800a51dfb108b5288f00f6/packages/playground/basic/public/images/static-test.gif -------------------------------------------------------------------------------- /packages/playground/basic/public/images/static-test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbenjs/vite-plugin-imagemin/fcbe8aa9f0608da0c1800a51dfb108b5288f00f6/packages/playground/basic/public/images/static-test.jpg -------------------------------------------------------------------------------- /packages/playground/basic/public/images/static-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbenjs/vite-plugin-imagemin/fcbe8aa9f0608da0c1800a51dfb108b5288f00f6/packages/playground/basic/public/images/static-test.png -------------------------------------------------------------------------------- /packages/playground/basic/shim-vue.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import { ComponentOptions } from 'vue' 3 | const component: ComponentOptions 4 | export default component 5 | } 6 | -------------------------------------------------------------------------------- /packages/playground/basic/src/App.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 42 | -------------------------------------------------------------------------------- /packages/playground/basic/src/assets/test.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbenjs/vite-plugin-imagemin/fcbe8aa9f0608da0c1800a51dfb108b5288f00f6/packages/playground/basic/src/assets/test.gif -------------------------------------------------------------------------------- /packages/playground/basic/src/assets/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbenjs/vite-plugin-imagemin/fcbe8aa9f0608da0c1800a51dfb108b5288f00f6/packages/playground/basic/src/assets/test.jpg -------------------------------------------------------------------------------- /packages/playground/basic/src/assets/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vbenjs/vite-plugin-imagemin/fcbe8aa9f0608da0c1800a51dfb108b5288f00f6/packages/playground/basic/src/assets/test.png -------------------------------------------------------------------------------- /packages/playground/basic/src/assets/test.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | digital-camera 9 | 10 | 11 | 12 | digital 13 | 14 | 11 15 | hardware 16 | photo 17 | digicam 18 | computer 19 | camera 20 | 21 | 22 | 23 | 24 | AJ Ashton 25 | 26 | 27 | 28 | 29 | AJ Ashton 30 | 31 | 32 | 33 | 34 | AJ Ashton 35 | 36 | 37 | 38 | image/svg+xml 39 | 40 | 41 | en 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /packages/playground/basic/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | 4 | const app = createApp(App) 5 | 6 | app.mount('#app') 7 | -------------------------------------------------------------------------------- /packages/playground/basic/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strictFunctionTypes": false, 10 | "jsx": "preserve", 11 | "baseUrl": ".", 12 | "allowJs": true, 13 | "sourceMap": true, 14 | "esModuleInterop": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "experimentalDecorators": true, 18 | "lib": ["dom", "esnext"], 19 | "incremental": true, 20 | "skipLibCheck": true 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/playground/basic/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { UserConfigExport } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import jsx from '@vitejs/plugin-vue-jsx' 4 | import viteImagemin from 'vite-plugin-imagemin' 5 | 6 | export default (): UserConfigExport => { 7 | return { 8 | build: { 9 | assetsInlineLimit: 0, 10 | }, 11 | plugins: [ 12 | vue(), 13 | jsx(), 14 | viteImagemin({ 15 | gifsicle: { 16 | optimizationLevel: 7, 17 | interlaced: false, 18 | }, 19 | optipng: { 20 | optimizationLevel: 7, 21 | }, 22 | mozjpeg: { 23 | quality: 20, 24 | }, 25 | pngquant: { 26 | quality: [0.8, 0.9], 27 | speed: 4, 28 | }, 29 | svgo: { 30 | plugins: [ 31 | { 32 | name: 'removeViewBox', 33 | }, 34 | { 35 | name: 'removeEmptyAttrs', 36 | active: false, 37 | }, 38 | ], 39 | }, 40 | }), 41 | ], 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - packages/* 3 | - packages/playground/* 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ESNext", 4 | "target": "es2017", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "declaration": true, 8 | "noUnusedLocals": true, 9 | "esModuleInterop": true, 10 | "outDir": "dist", 11 | "lib": ["ESNext"], 12 | "sourceMap": false, 13 | "noEmitOnError": true, 14 | "noImplicitAny": false 15 | }, 16 | "include": ["./packages"], 17 | "exclude": ["**/dist", "**/node_modules", "**/test"] 18 | } 19 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import { defineConfig } from 'vite' 4 | 5 | export default defineConfig({}) 6 | --------------------------------------------------------------------------------