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 ability to tell Vite to ignore the transformation of an import-statement #6393

Closed
4 tasks done
MathiasWP opened this issue Jan 5, 2022 · 4 comments
Closed
4 tasks done

Comments

@MathiasWP
Copy link

Clear and concise description of the problem

I use Vite for almost all of my frontend-projects nowadays, and i love how easy it is to setup and configure with the underlying rollup bundler. I am currently working on a large enterprise project that relies on the usage of an importmap to combine different microfrontends together on a root-application. Vite's transformation of import-statements during development makes this very difficult for our architecture, because we have cases where we want all of our projects to map a specific import to the path that is declared in our importmap.

I've read through the documentation, and the closest thing I've found is the optimizeDeps.exclude configuration, which still transforms the import-statement.

I want the ability to tell Vite to not transform this

import module from "my-module";

into this

 import module from "/node_modules/.vite/my-module.js?v=53c2a64b";

because the module has to get the source from the path mapped to "my-module" in our importmap, instead of locally from the projects node_modules folder.

Suggested solution

Looking through the source code i've seen the usage of a @vite-ignore comment to tell the transformator to suppress a dynamic import warning. It would be very beneficial for us to use something like this to tell Vite to not transform an import-statement.

Doing something like this

// @vite-ignore
import module from "my-module";

so that the import-statement is excluded from the import-transformation, would be a lifesaver!

Alternative

I have tried for almost a week now to find a way around the transformation of import-statements, but i have not found anything that would not be considered "hacky" or unstable. I love Vite, but it has become essential for us to have the ability to avoid the transformation of specific import-statements. I hope that this is an okay proposal, because i would hate having to go back to a slower alternative just to be able to do this.

Thank you for reading!

Additional context

No response

Validations

@MathiasWP MathiasWP changed the title Ability to tell Vite to ignore transformation of an import-statement Ability to tell Vite to ignore the transformation of an import-statement Jan 5, 2022
@MathiasWP MathiasWP changed the title Ability to tell Vite to ignore the transformation of an import-statement Add ability to tell Vite to ignore the transformation of an import-statement Jan 6, 2022
@toSayNothing
Copy link
Contributor

toSayNothing commented Jan 6, 2022

@MathiasWP i write a hacky code plugin here: hope it can help u. 🤣
https://stackblitz.com/edit/vitejs-vite-yj3max?file=vite.config.js

// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    viteImportmapPlugin({
      vue: 'https://cdn.jsdelivr.net/npm/vue@3.2.26/dist/vue.esm-browser.js',
      'lodash-es/isUndefined':
        'https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/isUndefined.js',
    }),
  ],
});

function viteImportmapPlugin(importmapObj) {
  const keys = Object.keys(importmapObj);
  return {
    name: 'vite-plugin-importmap',
    enforce: 'pre',
    // 1. insert to optimizeDeps.exclude to prevent pre-transform
    config(config) {
      config.optimizeDeps = {
        ...(config.optimizeDeps ?? {}),
        exclude: [...(config.optimizeDeps?.exclude ?? []), ...keys],
      };
    },
    // 2. push a plugin to rewrite the 'vite:import-analysis' prefix
    configResolved(resolvedConfig) {
      const VALID_ID_PREFIX = `/@id/`;
      const reg = new RegExp(`${VALID_ID_PREFIX}(${keys.join('|')})`, 'g');
      resolvedConfig.plugins.push({
        name: 'vite-plugin-importmap-replace-idprefix',
        transform: (code) =>
          reg.test(code) ? code.replace(reg, (m, s1) => s1) : code,
      });
    },
    // 3. rewrite the id before 'vite:resolve' plugin transform to 'node_modules/...'
    resolveId: (id) => importmapObj[id] && { id, external: true },
    // 4. inject importmap script to head-prepend before '@vite/client' scripts tag
    transformIndexHtml: {
      enforce: 'pre',
      transform: (html) => ({
        html,
        tags: [
          {
            tag: 'script',
            attrs: { type: 'importmap' },
            injectTo: 'head-prepend',
            children: JSON.stringify({ imports: importmapObj }, null, 2),
          },
        ],
      }),
    },
  };
}

@MathiasWP
Copy link
Author

MathiasWP commented Jan 6, 2022

That is very nice of you @toSayNothing! Unfortunately we have a more advanced setup where the importmap is present on a different localhost, so we need the possibility to simply tell Vite to not transform the import at all during development.

I don't have an issue with using a plugin to solve this issue - but i could not make the plugin you provided work. Is it possible to solve this issue legitimately with a plugin?

@toSayNothing
Copy link
Contributor

@MathiasWP what about this ? https://stackblitz.com/edit/vitejs-vite-yj3max?file=vite.config.js

// vite.config.js
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [viteIgnoreStaticImport(["vue", "lodash-es"])],
});

function viteIgnoreStaticImport(importKeys) {
  return {
    name: "vite-plugin-ignore-static-import",
    enforce: "pre",
    // 1. insert to optimizeDeps.exclude to prevent pre-transform
    config(config) {
      config.optimizeDeps = {
        ...(config.optimizeDeps ?? {}),
        exclude: [...(config.optimizeDeps?.exclude ?? []), ...importKeys],
      };
    },
    // 2. push a plugin to rewrite the 'vite:import-analysis' prefix
    configResolved(resolvedConfig) {
      const VALID_ID_PREFIX = `/@id/`;
      const reg = new RegExp(
        `${VALID_ID_PREFIX}(${importKeys.join("|")})`,
        "g"
      );
      resolvedConfig.plugins.push({
        name: "vite-plugin-ignore-static-import-replace-idprefix",
        transform: (code) =>
          reg.test(code) ? code.replace(reg, (m, s1) => s1) : code,
      });
    },
    // 3. rewrite the id before 'vite:resolve' plugin transform to 'node_modules/...'
    resolveId: (id) => {
      if (importKeys.includes(id)) {
        return { id, external: true };
      }
    },
  };
}

in this demo , if u run the dev or build command, u can see the main.js(or bundled file : dist/assets/index.[hash].js) the import code won't be transform by vite,

// dev mode, before apply this plugin , request main.js , the response:
import { createApp } from "/node_modules/.vite/vue.js?v=82b46e8a";
import { isUndefined } from "/node_modules/.vite/lodash-es.js?v=82b46e8a";

console.log(createApp);
console.log(isUndefined(undefined));
// dev mode, after applied this plugin , request main.js , the response:
import { createApp } from 'vue';
import { isUndefined } from 'lodash-es';

console.log(createApp);
console.log(isUndefined(undefined));

Is it possible to solve this issue legitimately with a plugin?

for now, i think we can solve this issue in a hacky way(use plugin).
if this still not works , maybe u can provide a online demo , so i can help u better 😅
maybe in the future vite can provide the config like config.ignoreStaticImport

@bluwy
Copy link
Member

bluwy commented Jun 23, 2022

I think the correct feature would be having an external API, or lending rollupOptions.external, so that the imports are left as-is when matched. Currently Vite will transform the imports in import-analysis regardless of the value, except for builds. I'll close this in favour of #6582 as it aligns closer to the internal goal, but I'll forward the workaround here.

@bluwy bluwy closed this as not planned Won't fix, can't repro, duplicate, stale Jun 23, 2022
@bluwy bluwy mentioned this issue Jun 23, 2022
4 tasks
@github-actions github-actions bot locked and limited conversation to collaborators Jul 8, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants