UNPKG

vite-plugin-cjs-interop

Version:

Vite plugin to unwrap default imports from CJS dependencies during SSR

81 lines (59 loc) 2.43 kB
# `vite-plugin-cjs-interop` Vite plugin to unwrap default imports from CJS dependencies during SSR. ## Problem In Node.js, when a CJS module that contains both a default export and named exports is imported from an ESM module, the default export has to be accessed via the `default` property of the imported module. Prior to version 5, Vite had some logic to handle this during development, but it didn't apply to SSR builds with `external` CJS dependencies. Since Vite 5, the problem happens in development as well. You don't get any indication that it won't work in production. TypeScript doesn't complain either. ## Solution This plugin will automatically unwrap the default export from CJS dependencies that you specify during SSR builds. In other words, the following code: ```js import foo, { named, named2 as renamed } from "foo"; ``` will be transformed into: ```js const { default: foo = __cjsInterop1__, named, named2: renamed, } = __cjsInterop1__?.default?.__esModule ? __cjsInterop1__.default : __cjsInterop1__; import __cjsInterop1__ from "foo"; ``` which takes care of unwrapping the default export and creating a synthetic default export if necessary. The change for dynamic imports is more complicated, but allows the `import()` function to resolve to an object that not only resembles the standard ES6 namespace as expected, but also a CommonJS export: ```js const foo = await import("foo"); // ES6 namespace, with default export foo.default.bar(); // Works // CommonJS Module (some libraries expect this to work because webpack allows it) foo.bar(); // Also works ``` ## Installation ```sh npm install -D vite-plugin-cjs-interop ``` ## Usage ```js // vite.config.js import { cjsInterop } from "vite-plugin-cjs-interop"; export default { plugins: [ cjsInterop({ // List of CJS dependencies that require interop dependencies: [ "some-package", // Deep imports should be specified separately "some-package/deep/import", // But globs are supported "some-package/foo/*", // Even deep globs for scoped packages "@some-scope/**", // If you want to skip a specific package, you can use negative globs "!@donottransformme/**", ], }), ], }; ``` The matcher uses [minimatch](https://github.com/isaacs/minimatch) underneath, for more details on supported syntax. ## License [MIT](LICENSE)