Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/vite-plugin/vite-plugin-dynamic-import

Enhance Vite builtin dynamic import
https://github.com/vite-plugin/vite-plugin-dynamic-import

dyanmic import plugin vite

Last synced: about 1 month ago
JSON representation

Enhance Vite builtin dynamic import

Lists

README

        

# vite-plugin-dynamic-import

Enhance Vite builtin dynamic import

[![NPM version](https://img.shields.io/npm/v/vite-plugin-dynamic-import.svg)](https://npmjs.org/package/vite-plugin-dynamic-import)
[![NPM Downloads](https://img.shields.io/npm/dm/vite-plugin-dynamic-import.svg)](https://npmjs.org/package/vite-plugin-dynamic-import)
[![awesome-vite](https://awesome.re/badge.svg)](https://github.com/vitejs/awesome-vite)

English | [简体中文](https://github.com/vite-plugin/vite-plugin-dynamic-import/blob/main/README.zh-CN.md)

✅ Alias
✅ Bare module(node_modules)
✅ Compatible `@rollup/plugin-dynamic-import-vars` [limitations](https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations)
✅ Webpack-like behavior

## Install

```bash
npm i vite-plugin-dynamic-import -D
```

## Usage

```javascript
import dynamicImport from 'vite-plugin-dynamic-import'

export default {
plugins: [
dynamicImport(/* options */)
]
}
```

cases 👉 [vite-plugin-dynamic-import/test](https://github.com/vite-plugin/vite-plugin-dynamic-import/blob/main/test)

#### node_modules

```js
dynamicImport({
filter(id) {
// `node_modules` is exclude by default, so we need to include it explicitly
// https://github.com/vite-plugin/vite-plugin-dynamic-import/blob/v1.3.0/src/index.ts#L133-L135
if (id.includes('/node_modules/foo')) {
return true
}
}
})
```

## API

dynamicImport([options])

```ts
export interface Options {
filter?: (id: string) => boolean | void
/**
* ```
* 1. `true` - Match all possibilities as much as possible, more like `webpack`
* see https://webpack.js.org/guides/dependency-management/#require-with-expression
*
* 2. `false` - It behaves more like `@rollup/plugin-dynamic-import-vars`
* see https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#how-it-works
* ```
*
* @defaultValue true
*/
loose?: boolean
/**
* If you want to exclude some files
* e.g `type.d.ts`, `interface.ts`
*/
onFiles?: (files: string[], id: string) => typeof files | void
/**
* Custom importee
*
* e.g. - append `\/*@vite-ignore*\/` in front of importee to bypass to Vite
*/
onResolve?: (rawImportee: string, id: string) => typeof rawImportee | void
}
```

## How and why?

*We assume that the project structure is as follows*

```tree
├─┬ src
│ ├─┬ views
│ │ ├─┬ foo
│ │ │ └── index.js
│ │ └── bar.js
│ └── router.js
└── vite.config.js
```

```js
// vite.config.js
export default {
resolve: {
alias: {
// "@" -> "/User/project-root/src/views"
'@': path.join(__dirname, 'src/views'),
},
},
}
```

*Dynamic import is not well supported in Vite, such as*

- Alias are not supported

```js
// router.js
❌ import(`@/views/${variable}.js`)
```

- Must be relative

```js
// router.js
❌ import(`/User/project-root/src/views/${variable}.js`)
```

- Must have extension

```js
// router.js
❌ import(`./views/${variable}`)
```

*We try to fix these problems*

For the alias in `import()`, we can calculate the relative path according to `importer`

```js
// router.js
✅ import(`./views/${variable}.js`)
```

If the import path has no suffix, we use **[glob](https://www.npmjs.com/package/fast-glob)** to find the file according to `UserConfig.resolve.extensions` and supplement the suffix of the import path.
So we need to list all the possibilities

1. transpire dynamic import variable, you can see [@rollup/plugin-dynamic-import-vars](https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#how-it-works)

`./views/${variable}` -> `./views/*`

2. generate runtime code

```diff
- // import(`./views/${variable}`)
+ __variableDynamicImportRuntime(`./views/${variable}`)

+ function __variableDynamicImportRuntime(path) {
+ switch (path) {
+ case 'foo':
+ case 'foo/index':
+ case 'foo/index.js':
+ return import('./views/foo/index.js');
+
+ case 'bar':
+ case 'bar.js':
+ return import('./views/bar.js');
+ }
```