Socket
Socket
Sign inDemoInstall

vite-plugin-resolve

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vite-plugin-resolve - npm Package Compare versions

Comparing version 1.8.0 to 2.0.0

49

index.d.ts

@@ -1,47 +0,12 @@

import { Plugin, UserConfig } from 'vite';
import { Plugin } from 'vite';
export default resolve;
declare const resolve: VitePluginResolve;
export default resolve;
export interface ResolveArgs {
/** Generated file cache directory */
dir: string;
}
export interface Resolves {
[moduleId: string]:
| string
| ((args: ResolveArgs) =>
| string
| Promise<string | void>
| void)
| void;
}
export interface ResolveOptions {
/**
* Absolute path or relative path
* @default ".vite-plugin-resolve"
*/
dir?: string;
}
export interface VitePluginResolve {
(resolves: Resolves, options?: ResolveOptions): Plugin;
(entries: {
[moduleId: string]:
| ReturnType<Plugin['load']>
| ((...args: Parameters<Plugin['load']>) => ReturnType<Plugin['load']>)
}): Plugin[];
}
// --------- utils ---------
export interface GenerateESModule {
(dir: string, resolves: Resolves): Promise<void>;
}
export interface ModifyAlias {
(
config: UserConfig,
aliaList: { [moduleId: string]: string; }[],
): void;
}
export interface ModifyOptimizeDepsExclude {
(config: UserConfig, exclude: string[]): void;
}

129

index.js

@@ -1,99 +0,44 @@

const fs = require('fs');
const path = require('path');
/**
* @type {import('.').VitePluginResolve}
*/
module.exports = function resolve(resolves = {}, options = {}) {
let { dir = '.vite-plugin-resolve' } = options;
let root = process.cwd();
module.exports = function resolve(resolves) {
const prefix = '\0';
const resolveKeys = Object.keys(resolves);
const resolveKeysWithPrefix = resolveKeys.map(key => prefix + key);
return {
name: 'vite-plugin-resolve',
async config(config) {
if (!path.isAbsolute(dir)) dir = path.join(node_modules(root), dir);
if (config.root) root = path.resolve(config.root);
return [
{
name: 'vite-plugin-resolve:resolveId',
// run before the builtin 'vite:resolve' of Vite
enforce: 'pre',
resolveId(source) {
if (resolveKeys.includes(source)) {
// https://vitejs.dev/guide/api-plugin.html#virtual-modules-convention
return prefix + source;
}
},
},
{
name: 'vite-plugin-resolve',
config(config) {
if (!config.optimizeDeps) config.optimizeDeps = {};
if (!config.optimizeDeps.exclude) config.optimizeDeps.exclude = [];
modifyOptimizeDepsExclude(config, Object.keys(resolves));
modifyAlias(
config,
Object.keys(resolves).map(moduleId => ({ [moduleId]: path.join(dir, moduleId) })),
);
let keys = resolveKeys;
if (config.optimizeDeps.include) {
keys = resolveKeys.filter(key => !config.optimizeDeps.include.includes(key));
}
await generateESModule(dir, resolves);
config.optimizeDeps.exclude.push(...keys);
},
async load(id, opts) {
if (resolveKeysWithPrefix.includes(id)) {
const stringOrFunction = resolves[id.replace(prefix, '')];
return typeof stringOrFunction === 'function'
? await stringOrFunction(id, opts)
: stringOrFunction;
}
},
},
}
}
/**
* @type {import('.').GenerateESModule}
*/
async function generateESModule(dir, resolves) {
// generate custom-resolve module file
for (const [module, strOrFn] of Object.entries(resolves)) {
const moduleId = path.join(dir, module + '.js');
const moduleContent = await (typeof strOrFn === 'function' ? strOrFn({ dir }) : strOrFn);
if (moduleContent == null) continue;
// supported nest moduleId ('@scope/name')
ensureDir(path.parse(moduleId).dir);
// write custom-resolve
fs.writeFileSync(moduleId, moduleContent);
}
}
/**
* @type {import('.').ModifyAlias}
*/
function modifyAlias(config, aliaList) {
if (!config.resolve) config.resolve = {};
let alias = config.resolve.alias || [];
if (!Array.isArray(alias)) {
// keep the the original alias
alias = Object.entries(alias).map(([k, v]) => ({ find: k, replacement: v }));
}
// redirect resolve-module to `node_modules/.vite-plugin-resolve`
alias.push(...aliaList.map(item => {
const [find, replacement] = Object.entries(item)[0];
return { find, replacement };
}));
config.resolve.alias = alias;
}
/**
* @type {import('.').ModifyOptimizeDepsExclude}
*/
function modifyOptimizeDepsExclude(config, exclude) {
if (!config.optimizeDeps) config.optimizeDeps = {};
if (!config.optimizeDeps.exclude) config.optimizeDeps.exclude = [];
if (config.optimizeDeps.include) {
exclude = exclude.filter(e => !config.optimizeDeps.include.includes(e));
}
config.optimizeDeps.exclude.push(...exclude);
}
// --------- utils ---------
function ensureDir(dir) {
if (!(fs.existsSync(dir) && fs.statSync(dir).isDirectory())) {
fs.mkdirSync(dir, { recursive: true });
}
return dir;
}
function node_modules(root, count = 0) {
if (node_modules.p) {
return node_modules.p;
}
const p = path.join(root, 'node_modules');
if (fs.existsSync(p)) {
return node_modules.p = p;
}
if (count >= 19) {
throw new Error('Can not found node_modules directory.');
}
return node_modules(path.join(root, '..'), count + 1);
}
];
};
{
"name": "vite-plugin-resolve",
"version": "1.8.0",
"version": "2.0.0",
"description": "Custom resolve module content.",

@@ -11,3 +11,3 @@ "main": "index.js",

"devDependencies": {
"vite": "^2.6.13"
"vite": "^2.x"
},

@@ -14,0 +14,0 @@ "keywords": [

@@ -8,4 +8,3 @@ # vite-plugin-resolve [![NPM version](https://img.shields.io/npm/v/vite-plugin-resolve.svg)](https://npmjs.org/package/vite-plugin-resolve) [![awesome-vite](https://awesome.re/badge.svg)](https://github.com/vitejs/awesome-vite)

- Compatible Browser, Node.js and Electron
- You can think of it as an enhanced Vite external plugin
- You can think of it as manually [Pre-Bundling](https://vitejs.dev/guide/dep-pre-bundling.html)
- You can think of this as the implementation of the official tutorial 👉 [Virtual Modules Convention](https://vitejs.dev/guide/api-plugin.html#virtual-modules-convention)

@@ -41,3 +40,3 @@ ## Install

// Support return Promise
'@scope/name': async () => await require('fs').promises.readFile('path', 'utf-8'),
'@scope/name': () => require('fs').promises.readFile('path', 'utf-8'),
})

@@ -55,131 +54,23 @@ ```

#### Resolve an ES module as an CommonJs module for Node.js
Such as [execa](https://www.npmjs.com/package/execa), [node-fetch](https://www.npmjs.com/package/node-fetch)
Here, Vite is used as the build tool
You can also choose other tools, such as [rollup](https://rollupjs.org), [webpack](https://webpack.js.org), [esbuild](https://esbuild.github.io), [swc](https://swc.rs) and so on
```ts
import { builtinModules } from 'module'
import { defineConfig, build } from 'vite'
import resolve from 'vite-plugin-resolve'
export default defineConfig({
plugins: [
resolve({
async execa(args) {
// Transpile execa as an CommonJs module
await build({
plugins: [
{
name: 'vite-plugin[node:mod-to-mod]',
enforce: 'pre',
// Replace `import fs from "node:fs"` with `import fs from "fs"`
resolveId(source) {
if (source.startsWith('node:')) {
return source.replace('node:', '')
}
},
}
],
// Build execa.js into cache directory
build: {
outDir: args.dir,
minify: false,
emptyOutDir: false,
lib: {
entry: require.resolve('execa'),
formats: ['cjs'],
fileName: () => `execa.js`,
},
rollupOptions: {
external: [
...builtinModules,
],
},
},
})
},
})
]
})
```
## API
### resolve(resolves[, options])
#### resolve(entries)
##### resolves
**entries**
```ts
export interface Resolves {
{
[moduleId: string]:
| string
| ((args: ResolveArgs) =>
| string
| Promise<string | void>
| void)
| void;
| ReturnType<Plugin['load']>
| ((...args: Parameters<Plugin['load']>) => ReturnType<Plugin['load']>)
}
export interface ResolveArgs {
/** Generated file cache directory */
dir: string;
}
```
##### options
You can see the return value type definition here [rollup/types.d.ts#L272](https://github.com/rollup/rollup/blob/b8315e03f9790d610a413316fbf6d565f9340cab/src/rollup/types.d.ts#L272)
```ts
export interface ResolveOptions {
/**
* Absolute path or relative path
* @default ".vite-plugin-resolve"
*/
dir: string;
}
```
## What's different from the official Demo?
## How to work
There are two main differences
#### Let's use Vue as an example
```js
resolve({
vue: `const vue = window.Vue; export { vue as default }`,
})
```
1. Create `node_modules/.vite-plugin-resolve/vue.js` and contains the following code
```js
const vue = window.Vue; export { vue as default }
```
2. Create a `vue` alias item and add it to `resolve.alias`
```js
{
resolve: {
alias: [
{
find: 'vue',
replacement: 'User/work-directory/node_modules/.vite-plugin-resolve/vue.js',
},
],
},
}
```
3. Add `vue` to the `optimizeDeps.exclude` by default.
You can avoid it through `optimizeDeps.include`
```js
export default {
optimizeDeps: {
exclude: ['vue'],
},
}
```
1. Bypass the builtin `vite:resolve` plugin
2. Reasonably avoid [Pre-Bundling](https://vitejs.dev/guide/dep-pre-bundling.html) treatment

@@ -8,4 +8,3 @@ # vite-plugin-resolve [![NPM version](https://img.shields.io/npm/v/vite-plugin-resolve.svg)](https://npmjs.org/package/vite-plugin-resolve) [![awesome-vite](https://awesome.re/badge.svg)](https://github.com/vitejs/awesome-vite)

- 兼容 Browser, Node.js and Electron
- 你可以认为它是一个加强版的 Vite external 插件
- 你可以认为它是手动版的 Vite 预构建 [Pre-Bundling](https://vitejs.dev/guide/dep-pre-bundling.html)
- 你可以认为它是官方教程的一个实现 👉 [Virtual Modules Convention](https://vitejs.dev/guide/api-plugin.html#virtual-modules-convention)

@@ -54,131 +53,23 @@ ## 安装

#### 将 ES 模块转换成 CommonJs 模块供 Node.js 使用
例如 [execa](https://www.npmjs.com/package/execa), [node-fetch](https://www.npmjs.com/package/node-fetch)
这里使用 "vite" 作为构建工具
你也可以选用其他的工具,比如 [rollup](https://rollupjs.org), [webpack](https://webpack.js.org), [esbuild](https://esbuild.github.io), [swc](https://swc.rs) 等等
```ts
import { builtinModules } from 'module'
import { defineConfig, build } from 'vite'
import resolve from 'vite-plugin-resolve'
export default defineConfig({
plugins: [
resolve({
async execa(args) {
// 将 execa 构建成 CommonJs 模块
await build({
plugins: [
{
name: 'vite-plugin[node:mod-to-mod]',
enforce: 'pre',
// 将 import fs from "node:fs" 替换为 import fs from "fs"
resolveId(source) {
if (source.startsWith('node:')) {
return source.replace('node:', '')
}
},
}
],
// 将 execa.js 写入到缓存目录
build: {
outDir: args.dir,
minify: false,
emptyOutDir: false,
lib: {
entry: require.resolve('execa'),
formats: ['cjs'],
fileName: () => `execa.js`,
},
rollupOptions: {
external: [
...builtinModules,
],
},
},
})
},
})
]
})
```
## API
### resolve(resolves[, options])
#### resolve(entries)
##### resolves
**entries**
```ts
export interface Resolves {
{
[moduleId: string]:
| string
| ((args: ResolveArgs) =>
| string
| Promise<string | void>
| void)
| void;
| ReturnType<Plugin['load']>
| ((...args: Parameters<Plugin['load']>) => ReturnType<Plugin['load']>)
}
export interface ResolveArgs {
/** 生成缓存文件夹 */
dir: string;
}
```
##### options
详细的返回值类型看这里 [rollup/types.d.ts#L272](https://github.com/rollup/rollup/blob/b8315e03f9790d610a413316fbf6d565f9340cab/src/rollup/types.d.ts#L272)
```ts
export interface ResolveOptions {
/**
* 相对或绝对路径
* @default ".vite-plugin-resolve"
*/
dir: string;
}
```
## 这与官方的 Demo 有何异同?
## 工作原理
主要有两点不一样
#### 用 Vue 来举个 🌰
```js
viteResolve({
vue: `const vue = window.Vue; export { vue as default }`,
})
```
1. 创建 `node_modules/.vite-plugin-resolve/vue.js` 文件并包含下面的代码
```js
const vue = window.Vue; export { vue as default }
```
2. 创建一个 `vue` 的别名项,并且添加到 `resolve.alias`
```js
{
resolve: {
alias: [
{
find: 'vue',
replacement: 'User/work-directory/node_modules/.vite-plugin-resolve/vue.js',
},
],
},
}
```
3. 默认会将 `vue` 添加到 `optimizeDeps.exclude` 中
你可以通过 `optimizeDeps.include` 绕开
```js
export default {
optimizeDeps: {
exclude: ['vue'],
},
}
```
1. 绕过内置的 `vite:resolve` 插件
2. 合理的避开 [Pre-Bundling](https://vitejs.dev/guide/dep-pre-bundling.html)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc