vitejs / vite

Next generation frontend tooling. It's fast!
http://vite.dev
MIT License
68.55k stars 6.19k forks source link

build.rollupOptions.external doesn't work. #1528

Closed leiyue closed 3 years ago

leiyue commented 3 years ago

⚠️ IMPORTANT ⚠️ Please check the following list before proceeding. If you ignore this issue template, your issue will be directly closed.

Describtion

The Vite configuration file specifies the option build.rollupOptions.external setting, but it has no effect.

When running the vite command, the following error still appears:

Rollup failed to resolve import "react" from "node_modules/@apollo/client/react/context/ApolloConsumer.js".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`

Reproduction

Please provide a link to a repo that can reproduce the problem you ran into.

A reproduction is required unless you are absolutely sure that the the problem is obvious and the information you provided is enough for us to understand what the problem is. If a report has only vague description (e.g. just a generic error message) and has no reproduction, it will be closed immediately.

vite.config.ts

import vueJsx from "@vitejs/plugin-vue-jsx";
import { resolve } from "path";
import { defineConfig } from "vite";

export default defineConfig({
  alias: {
    "@": resolve(__dirname, "src"),
  },
  plugins: [vueJsx()],
  build: {
    rollupOptions: {
      external: [
        "react", // ignore react stuff
        "react-dom",
      ],
    },
  },
  optimizeDeps: {
    include: ["@apollo/client/core", "@apollo/client/link/error"],
  },
});

System Info

Logs (Optional if provided reproduction)

  1. Run vite or vite build with the --debug flag.
  2. Provide the error log here.
npx vite --debug
  vite:config bundled config file loaded in 239ms +0ms
[dotenv][DEBUG] did not match key and value when parsing line 2:
  vite:config using resolved config: {
  vite:config   alias: [
  vite:config     {
  vite:config       find: /^\/@vite\//,
  vite:config       replacement: '/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/node_modules/vite/dist/client/'
  vite:config     },
  vite:config     {
  vite:config       find: '@',
  vite:config       replacement: '/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/src'
  vite:config     }
  vite:config   ],
  vite:config   plugins: [
  vite:config     'alias',
  vite:config     'vite:dynamic-import-polyfill',
  vite:config     'vite:resolve',
  vite:config     'vite:html',
  vite:config     'vite:css',
  vite:config     'vite:esbuild',
  vite:config     'vite:json',
  vite:config     'vite:wasm',
  vite:config     'vite:worker',
  vite:config     'vite:asset',
  vite:config     'vue-jsx',
  vite:config     'vite:css-post',
  vite:config     'vite:client-inject',
  vite:config     'vite:import-analysis'
  vite:config   ],
  vite:config   build: {
  vite:config     base: '/',
  vite:config     target: [ 'es2019', 'edge16', 'firefox60', 'chrome61', 'safari11' ],
  vite:config     polyfillDynamicImport: true,
  vite:config     outDir: 'dist',
  vite:config     assetsDir: 'assets',
  vite:config     assetsInlineLimit: 4096,
  vite:config     cssCodeSplit: true,
  vite:config     sourcemap: false,
  vite:config     rollupOptions: { external: [Array] },
  vite:config     commonjsOptions: { include: [Array], extensions: [Array] },
  vite:config     minify: 'terser',
  vite:config     terserOptions: {},
  vite:config     cleanCssOptions: {},
  vite:config     write: true,
  vite:config     emptyOutDir: null,
  vite:config     manifest: false,
  vite:config     lib: false,
  vite:config     ssr: false
  vite:config   },
  vite:config   optimizeDeps: { include: [ '@apollo/client/core', '@apollo/client/link/error' ] },
  vite:config   server: {},
  vite:config   esbuild: { include: /\.ts$/ },
  vite:config   define: { __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false },
  vite:config   configFile: '/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/vite.config.ts',
  vite:config   inlineConfig: {
  vite:config     root: undefined,
  vite:config     mode: undefined,
  vite:config     configFile: undefined,
  vite:config     logLevel: undefined,
  vite:config     server: {}
  vite:config   },
  vite:config   root: '/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example',
  vite:config   command: 'serve',
  vite:config   mode: 'development',
  vite:config   isProduction: false,
  vite:config   optimizeCacheDir: '/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/node_modules/.vite',
  vite:config   env: {
  vite:config     VITE_BASE_URL: '/',
  vite:config     BASE_URL: '/',
  vite:config     MODE: 'development',
  vite:config     DEV: true,
  vite:config     PROD: false
  vite:config   },
  vite:config   assetsInclude: [Function: assetsInclude],
  vite:config   logger: {
  vite:config     info: [Function: info],
  vite:config     warn: [Function: warn],
  vite:config     error: [Function: error],
  vite:config     clearScreen: [Function: clearScreen]
  vite:config   }
  vite:config } +4ms
  vite:resolve 1ms   ./core/index.js -> null +0ms
  vite:optimize optimizing @apollo/client (contains relative imports) +0ms
  vite:optimize skipping @apollo/client (single esm file, doesn't need optimization) +0ms
  vite:resolve 0ms   ./useQuery -> null +1ms
  vite:optimize optimizing @vue/apollo-composable (contains relative imports) +1ms
  vite:optimize skipping @vue/apollo-composable (single esm file, doesn't need optimization) +0ms
  vite:optimize optimizing aws-appsync-auth-link (no exports, likely commonjs) +1ms
  vite:resolve 0ms   ./version.mjs -> null +2ms
  vite:optimize optimizing graphql (contains relative imports) +2ms
  vite:optimize skipping graphql (single esm file, doesn't need optimization) +0ms
  vite:optimize optimizing graphql-tag (no exports, likely commonjs) +1ms
  vite:optimize optimizing lodash (no exports, likely commonjs) +18ms
  vite:optimize optimizing subscriptions-transport-ws (no exports, likely commonjs) +4ms
  vite:resolve 0ms   @vue/runtime-dom -> null +25ms
  vite:optimize optimizing vue (imports sub dependencies) +1ms
  vite:optimize skipping vue (single esm file, doesn't need optimization) +0ms
  vite:resolve 0ms   graphql-tag -> null +2ms
  vite:optimize skipping vue-apollo (single esm file, doesn't need optimization) +2ms
  vite:resolve 1ms   vue -> null +3ms
  vite:optimize skipping vue-router (single esm file, doesn't need optimization) +3ms
  vite:resolve 0ms   vue-router -> null +0ms
Optimizable dependencies detected:
@apollo/client, @vue/apollo-composable, aws-appsync-auth-link, graphql, graphql-tag, lodash, subscriptions-transport-ws, vue, @apollo/client/core, @apollo/client/link/error
Pre-bundling them to speed up dev server page load...
(this will be run only when your dependencies or config have changed)

Dep optimization failed with error:
/Users/XXXXX/PlayGround/vite-appsync-graphql-todo-example/node_modules/vite/dist/node/chunks/dep-055fc131.js:39568
            throw new Error(`[vite]: Rollup failed to resolve import "${id}" from "${importer}".\n` +
                  ^

Error: [vite]: Rollup failed to resolve import "react" from "node_modules/@apollo/client/react/context/ApolloConsumer.js".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
    at onRollupWarning (/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/node_modules/vite/dist/node/chunks/dep-055fc131.js:39568:19)
    at Object.onwarn (/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/node_modules/vite/dist/node/chunks/dep-055fc131.js:65031:17)
    at Object.onwarn (/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/node_modules/rollup/dist/shared/rollup.js:19541:20)
    at ModuleLoader.handleResolveId (/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/node_modules/rollup/dist/shared/rollup.js:18451:26)
    at /Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/node_modules/rollup/dist/shared/rollup.js:18418:22
    at async Promise.all (index 0)
    at async ModuleLoader.fetchStaticDependencies (/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/node_modules/rollup/dist/shared/rollup.js:18416:34)
    at async Promise.all (index 0)
    at async ModuleLoader.fetchModule (/Users/leiyue/PlayGround/vite-appsync-graphql-todo-example/node_modules/rollup/dist/shared/rollup.js:18393:9)
    at async Promise.all (index 0)
bpeschier commented 3 years ago

I am experiencing the same during testing of vite2.

Initial review indicates that rollup's external is not populated during optimisation of the dependencies in resolveQualifiedDeps, only during build (which makes the error incorrect, since it states you need to add it to the build-config, not the optimizeDeps-config, which has no such option).

Opening the erroring chunk and adding react to external manually fixes it (just search for external.push and insert it).

Maybe moving the external-option to the shared options will make it more understandable and makes it possible to use it during optimisation?

yyx990803 commented 3 years ago

Note: this is because @apollo/client's main entry transitively imports React. Although technically Vite should respect externals during pre-bundling, the actual correct config here is to exclude @apollo/client from pre-bundling because you obviously do not intend to import it (and if you do, even with React externalized, it will still error because react is not a valid import specifier in the browser).

The even better fix is to ask Apollo client to fix its default import so that it doesn't transitively import React when it claims to be framework agnostic.

bpeschier commented 3 years ago

I agree with the "even better" fix, completely missed the transitive react import on the main @apollo/client package.

Proposed solution works like a charm, thanks for the quick reply!

leonardoks16 commented 3 years ago

Maybe this will work with you, Its good alternative for who is having problems with apollo Astrid-Client