Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to disable esbuild plugin in vite #456

Closed
haoleanh opened this issue Jun 25, 2020 · 5 comments · Fixed by #475
Closed

Add option to disable esbuild plugin in vite #456

haoleanh opened this issue Jun 25, 2020 · 5 comments · Fixed by #475
Labels
enhancement New feature or request

Comments

@haoleanh
Copy link

haoleanh commented Jun 25, 2020

Is your feature request related to a problem? Please describe.
We managed to make Vite works with Vue 2 tsx (via babel plugin using @babel/preset-typescript and @vue/babel-preset-jsx). The problem is that Vite esbuild plugin always transform the code before it goes to our custom transformation.

Describe the solution you'd like
A setting in vite config or cli flag to disable esbuild plugin

Describe alternatives you've considered
We modified vite server source code to disable esbuild plugin and it works well for us

Additional context
Disable esbuild plugin
image

And here is the result :)
image

@underfin
Copy link
Member

In theory, the esbuild is already do same thing with @babel/preset-typescript and @vue/babel-preset-jsx, so you don't rely on them.I don't konw the reason which you use them instead of esbuild, can you explain it in detail?

@haoleanh
Copy link
Author

@underfin it's related to render function. In Vue 3 the render function has different format to props data (https://github.com/vuejs/rfcs/blob/master/active-rfcs/0008-render-function-api-change.md). I think esbuild by default will transform jsx syntax to similar react format which vue 2's render function isnt compatible with.
The main reason why we need Vue 2 render function format is to reuse Vue 2 library (in this case is Vuetify 2)

@yyx990803 yyx990803 added the enhancement New feature or request label Jun 25, 2020
underfin added a commit to rolldown/vite that referenced this issue Jun 28, 2020
yyx990803 pushed a commit that referenced this issue Jul 2, 2020
underfin added a commit to rolldown/vite that referenced this issue Jul 4, 2020
@Aaron-Pool
Copy link

@haoleanh just coming across this and I was curious if the frontend build pipeline you mentioned was open sourced anywhere? I'm interested in using vite for my team's vue 2 app, but I'm running into the tsx roadblock as well.

@haoleanh
Copy link
Author

haoleanh commented Oct 2, 2020

@Aaron-Pool we wrote a custom build based on babel and vite pipeline. The idea is to disable default Esbuild in Vite and use existing babel plugins to transform tsx to Vue 2 render format. Here is our code, its been a while since I used Vite (its more like experiment for us to try esm build) so Im not sure if this still works in latest Vite version.

Custom transformer

import path from "path";
import * as babel from "@babel/core";
import { Transform } from "vite";

export const vue2TsxTransformer: Transform = {
    test: (ctx) => path.basename(ctx.path).endsWith(".tsx") || path.basename(ctx.path).endsWith(".ts"),
    transform: async (ctx) => {
        try {
            const fileName = path.basename(ctx.path);
            const isTsx = fileName.endsWith(".tsx");
            const result = await babel.transformAsync(ctx.code, {
                filename: fileName,
                presets: isTsx ?
                    [
                        "vca-jsx",
                        "@vue/babel-preset-jsx",
                        ["@babel/preset-typescript", {
                            allowNamespaces: true
                        }]
                    ] :
                    [
                        ["@babel/preset-typescript", {
                            allowNamespaces: true
                        }]
                    ]
            });

            return result.code;
        }
        catch (ex) {
            console.log("ERROR: " + ex);
        }
    }
}

Custom resolver

import { Resolver } from "vite";

export const vue2Resolver: Resolver = {
    alias: {
        "vue": "vue/dist/vue.runtime.esm.js",
        "@vue/composition-api": "@vue/composition-api/dist/vue-composition-api.esm.js"
    }
}

Custom server plugin

import { ServerPlugin } from "vite";

export const vue2ServerPlugin: ServerPlugin = (ctx) => {
    ctx.app.use(async (ctx, next) => {
        await next();
        if (ctx.path.includes('/@modules/vue/dist/vue.runtime.esm.js')) {
            ctx.body = `
            // <<HMR Hack Start>>
            window.process = { env: { NODE_ENV: 'development' }};
            // <<HMR Hack End>>\n\n` + ctx.body;
        }
    });
}

Serve config (build config is similar)

function createServerConfig(projectConfig): ServerConfig {
    return {
        enableEsbuild: false,
        transforms: [
            Transformers.vue2TsxTransformer
        ],
        resolvers: [
            Resolvers.vue2Resolver,
        ],
        configureServer: [
            ServerPlugins.vue2ServerPlugin
        ],
        ...projectConfig,
    }
}

@Aaron-Pool
Copy link

@haoleanh Great! Thanks! 👍

@github-actions github-actions bot locked and limited conversation to collaborators Jul 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants