nonzzz / vite-plugin-compression

vite plugin. compress your bundle file.
MIT License
171 stars 10 forks source link

The product obtained by using gzip to compress element-plus is wrong and cannot be used #54

Closed StarCoderLn closed 3 months ago

StarCoderLn commented 4 months ago

Bug report 🐞

When I used this tool to gzip the element-plus package, the compressed file I got was wrong and could not be used.

Version & Environment

vue3 + vite project

Expection

I hope the compressed product can be used normally.

Actual results (or Errors)

This is how I use it: image The results obtained: image

nonzzz commented 4 months ago

vite's version?

nonzzz commented 4 months ago

Can you share your full vite's config or create a minimal reproduction

StarCoderLn commented 4 months ago

vite's version?

"vite": "4.0.0"

nonzzz commented 4 months ago

I created a simple scene and it works fine. image Here is my config.

import { defineConfig } from "vite";

import vue from "@vitejs/plugin-vue";
import compression from "vite-plugin-compression2";

export default defineConfig({
  plugins: [vue(), compression({ deleteOriginalAssets: true })],
});
StarCoderLn commented 4 months ago

I created a simple scene and it works fine. image Here is my config.

import { defineConfig } from "vite";

import vue from "@vitejs/plugin-vue";
import compression from "vite-plugin-compression2";

export default defineConfig({
  plugins: [vue(), compression({ deleteOriginalAssets: true })],
});

You can try to import element-plus as needed. I got an error after compressing element-plus.

nonzzz commented 4 months ago

My entry point


import { createApp } from "vue";
import Ele from "element-plus";
import App from "./app.vue";
import "element-plus/dist/index.css";

createApp(App).use(Ele).mount("#app");

<template>
    <div>
        <el-button>1</el-button>
    </div>
</template>
StarCoderLn commented 4 months ago

I created a simple scene and it works fine. image Here is my config.

import { defineConfig } from "vite";

import vue from "@vitejs/plugin-vue";
import compression from "vite-plugin-compression2";

export default defineConfig({
  plugins: [vue(), compression({ deleteOriginalAssets: true })],
});

This is how I use element-plus

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import compression from 'vite-plugin-compression2';

export default defineConfig({
  plugins: [
    vue({
        template: {
          compilerOptions: {
            isCustomElement: (tag) => tag.includes('swiper-'),
          }
        }
    }),
    AutoImport({
        resolvers: [ElementPlusResolver()],
    }),
    Components({
        resolvers: [ElementPlusResolver()],
    }),
    compression({
        threshold: 500 * 1024,
        filename: '[path][base]',
        deleteOriginalAssets: true
    }),
  ]
});
nonzzz commented 4 months ago

Ok, Let me guess. The filename is [path][base] So the original javaScript file has been replace as an compressed module. But you haven't using the cloud server like amazon s3. See #31 . I need to explain that compression isn't terser or other code compressor. If you're using it you should use it with Nginx or tomcat or other etc together.

nonzzz commented 4 months ago

image Anything works well. I think you can try using the follow script to do a simple validate.


const http = require('http')
const path = require('path')
const fs = require('fs')
const sirv = require('sirv')

const defaultWD = process.cwd()

const publicPath = path.join(defaultWD, 'dist')

const assets = sirv(publicPath, { gzip: true })

function createServer() {
  const server = http.createServer()

  server.on('request', (req, res) => {
    assets(req, res, () => {
      res.statusCode = 404
      res.end('File not found')
    })
  })

  server.listen(0, () => {
    const { port } = server.address()
    console.log(`server run on http://localhost:${port}`)
  })
}

function main() {
  if (!fs.existsSync(publicPath)) throw new Error("Please check your're already run 'npm run build'")
  createServer()
}

main()

Step:

nonzzz commented 4 months ago

AFAIK, filename Option, usually for the needs of amazon S3.

StarCoderLn commented 4 months ago

image Anything works well. I think you can try using the follow script to do a simple validate.

const http = require('http')
const path = require('path')
const fs = require('fs')
const sirv = require('sirv')

const defaultWD = process.cwd()

const publicPath = path.join(defaultWD, 'dist')

const assets = sirv(publicPath, { gzip: true })

function createServer() {
  const server = http.createServer()

  server.on('request', (req, res) => {
    assets(req, res, () => {
      res.statusCode = 404
      res.end('File not found')
    })
  })

  server.listen(0, () => {
    const { port } = server.address()
    console.log(`server run on http://localhost:${port}`)
  })
}

function main() {
  if (!fs.existsSync(publicPath)) throw new Error("Please check your're already run 'npm run build'")
  createServer()
}

main()

Step:

  • Remove filename option in plugin. and set the include: 'include: [/.(js)$/, /.(css)$/]'
  • npm run build (ensure your output is dist)
  • run this script and view the result in your browser.

ok,thanks for your help.

nonzzz commented 4 months ago

So it not a bug. Just some missing in document?

StarCoderLn commented 3 months ago

So it not a bug. Just some missing in document?

@nonzzz

After the compression is successful, I found that the resources in the dist directory have been reduced to 274k image

But when the web page is loaded, the displayed resource size is still the uncompressed size. Why is this? image

nonzzz commented 3 months ago

I'm afraid you're not set the response header in your server. For Nginx you can refer document. Or view question. This plugin compression on the client to reduce the pressure of the server side. If you're using like vercel or other's free cloud server. You might not need this plugin.

StarCoderLn commented 3 months ago

I'm afraid you're not set the response header in your server. For Nginx you can refer document. Or view question. This plugin compression on the client to reduce the pressure of the server side. If you're using like vercel or other's free cloud server. You might not need this plugin.

I started a local server and tested it using the server script you provided last time.

image

nonzzz commented 3 months ago

:) AFAIK. you can try set Content-Encoding visible in your local chrome devtool network tab. Or check your compressed source response header has the Content-Encoding If it has in, It means is work well. Here is the document for the compression doc