vite-plugin-fast-external
Advanced tools
Comparing version 1.4.3 to 1.4.4
@@ -0,27 +1,61 @@ | ||
import { Plugin, UserConfig } from 'vite'; | ||
export type External = Record<string, string | (() => string | Promise<string>)>; | ||
export interface VitePluginFastExternal { | ||
( | ||
external: External, | ||
options?: { | ||
/** | ||
* @default 'esm' | ||
* esm will generate code -> const vue = window['Vue']; export { vue as default } | ||
* cjs will generate code -> const vue = window['Vue']; module.exports = vue; | ||
*/ | ||
format: 'esm' | 'cjs'; | ||
/** | ||
* @default true | ||
* Whether to insert the external module into "optimizeDeps.exclude" | ||
*/ | ||
optimize: boolean; | ||
}, | ||
): Plugin; | ||
} | ||
/** | ||
* @example | ||
* export default defineConfig({ | ||
* plugins: [ | ||
* fastExternal({ | ||
* // will generate code `const vue = window['Vue']; export { vue as default }` | ||
* vue: 'Vue', | ||
* // custom external code by function | ||
* '@scope/name': () => `const Lib = window.LibraryName; export default Lib;`, | ||
* }) | ||
* ] | ||
* ```js | ||
* fastExternal({ | ||
* // Simple example | ||
* vue: 'Vue', | ||
* | ||
* // Custom external code by function | ||
* '@scope/name': () => `const Lib = window.ScopeName.Member; export default Lib;`, | ||
* | ||
* // Read a template file and return Promise<string> | ||
* externalId: async () => await require('fs').promises.readFile('path', 'utf-8'), | ||
* }) | ||
* ``` | ||
*/ | ||
declare function fastExternal( | ||
externals: Record<string, string | (() => string)>, | ||
options?: { | ||
/** | ||
* @default 'esm' | ||
* esm will generate code -> const vue = window['Vue']; export { vue as default } | ||
* cjs will generate code -> const vue = window['Vue']; module.exports = vue; | ||
*/ | ||
format: 'esm' | 'cjs' | ||
} | ||
): import('vite').Plugin | ||
declare const fastExternal: VitePluginFastExternal; | ||
export default fastExternal | ||
export default fastExternal; | ||
// --------- utils --------- | ||
export interface GenerateExternalFile { | ||
( | ||
externalDir: string, | ||
external: External, | ||
format: Parameters<VitePluginFastExternal>[1]['format'], | ||
): Promise<void>; | ||
} | ||
export interface ModifyAlias { | ||
( | ||
config: UserConfig, | ||
aliaList: { [external: string]: string; }[], | ||
): void; | ||
} | ||
export interface ModifyOptimizeDepsExclude { | ||
(config: UserConfig, exclude: string[]): void; | ||
} |
115
index.js
const fs = require('fs'); | ||
const path = require('path'); | ||
/** | ||
* @type {import('.').VitePluginFastExternal} | ||
*/ | ||
module.exports = function external( | ||
externals, | ||
external, | ||
options = {}, | ||
@@ -10,6 +13,7 @@ ) { | ||
let externalDir = '.vite-plugin-fast-external'; | ||
const { format = 'esm', optimize = true } = options; | ||
return { | ||
name: 'vite-plugin-fast-external', | ||
config(config) { | ||
async config(config) { | ||
// init root path | ||
@@ -24,11 +28,13 @@ if (config.root && path.isAbsolute(config.root)) { | ||
rewriteAlias( | ||
if (optimize) modifyOptimizeDepsExclude(config, Object.keys(external)); | ||
modifyAlias( | ||
config, | ||
externals, | ||
externalDir, | ||
Object.keys(external).map(moduleId => ({ [moduleId]: path.join(externalDir, moduleId) })), | ||
); | ||
generateExternalFile( | ||
externals, | ||
await generateExternalFile( | ||
externalDir, | ||
options?.format || 'esm', | ||
external, | ||
format, | ||
); | ||
@@ -39,30 +45,12 @@ } | ||
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); | ||
} | ||
function generateExternalFile( | ||
externals, | ||
/** | ||
* @type {import('.').GenerateExternalFile} | ||
*/ | ||
async function generateExternalFile( | ||
externalDir, | ||
external, | ||
format, | ||
) { | ||
// generate external module file | ||
for (const [module, strOrFn] of Object.entries(externals)) { | ||
for (const [module, strOrFn] of Object.entries(external)) { | ||
const moduleId = path.join(externalDir, `${module}.js`); | ||
@@ -76,6 +64,7 @@ let moduleContent; | ||
} else { | ||
moduleContent = strOrFn(); | ||
const content = strOrFn(); | ||
moduleContent = content instanceof Promise ? await content : content; | ||
} | ||
// for '@scope/name' package | ||
// supported nest moduleId ('@scope/name') | ||
ensureDir(path.parse(moduleId).dir); | ||
@@ -86,12 +75,9 @@ fs.writeFileSync(moduleId, moduleContent); | ||
function rewriteAlias( | ||
config, | ||
externals, | ||
externalDir, | ||
) { | ||
if (!config.resolve) { | ||
config.resolve = {}; | ||
} | ||
/** | ||
* @type {import('.').ModifyAlias} | ||
*/ | ||
function modifyAlias(config, aliaList) { | ||
if (!config.resolve) config.resolve = {}; | ||
let alias = config.resolve.alias || {}; | ||
let alias = config.resolve.alias || []; | ||
if (!Array.isArray(alias)) { | ||
@@ -101,9 +87,42 @@ // keep the the original alias | ||
} | ||
// redirect resolve-module to `node_modules/.vite-plugin-resolve` | ||
alias.push(...aliaList.map(item => { | ||
const [find, replacement] = Object.entries(item)[0]; | ||
return { find, replacement }; | ||
})); | ||
Object.keys(externals).forEach(k => { | ||
// redirect external-module to `node_modules/.vite-plugin-fast-external` | ||
alias.push({ find: k, replacement: path.join(externalDir, k) }); | ||
}) | ||
config.resolve.alias = alias; | ||
} | ||
/** | ||
* @type {import('.').ModifyOptimizeDepsExclude} | ||
*/ | ||
function modifyOptimizeDepsExclude(config, exclude) { | ||
if (!config.optimizeDeps) config.optimizeDeps = {}; | ||
if (!config.optimizeDeps.exclude) config.optimizeDeps.exclude = []; | ||
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-fast-external", | ||
"version": "1.4.3", | ||
"description": "An tiny and fast external plugin for vite.", | ||
"version": "1.4.4", | ||
"description": "Without lexical transform, support custom external code.", | ||
"main": "index.js", | ||
@@ -6,0 +6,0 @@ "repository": "https://github.com/caoxiemeihao/vite-plugins/tree/main/packages/fast-external", |
@@ -5,9 +5,27 @@ # vite-plugin-fast-external | ||
> Tiny and fast vite external plugin, without lexical transform. | ||
[![NPM version](https://img.shields.io/npm/v/vite-plugin-fast-external.svg?style=flat)](https://npmjs.org/package/vite-plugin-fast-external) | ||
[![NPM Downloads](https://img.shields.io/npm/dm/vite-plugin-fast-external.svg?style=flat)](https://npmjs.org/package/vite-plugin-fast-external) | ||
### Installation | ||
> Without lexical transform, support custom external code | ||
- Like Webpack externals, support browser, Node.js and Electron -- without environment | ||
- It's actually implemented by modify `resolve.alias` | ||
- By default `window` is used as the environment object, you can also customize the code snippets by return string from function -- Very flexible 🎉 | ||
**eg:** | ||
```js | ||
fastExternal({ | ||
// By default will generated code -> const Vue = window['Vue']; export { Vue as default } | ||
vue: 'Vue', | ||
// Custom external code snippets used in Node.js | ||
nodeJsModule: () => `module.exports = require('moduleId');`, | ||
}) | ||
``` | ||
## Install | ||
```bash | ||
@@ -25,6 +43,10 @@ npm i -D vite-plugin-fast-external | ||
fastExternal({ | ||
// will generate code `const vue = window['Vue']; export { vue as default }` | ||
// Simple example | ||
vue: 'Vue', | ||
// custom external code by function | ||
'@scope/name': () => `const Lib = window.LibraryName; export default Lib;`, | ||
// Custom external code by function | ||
'@scope/name': () => `const Lib = window.ScopeName.Member; export default Lib;`, | ||
// Read a template file and return Promise<string> | ||
externalId: async () => await require('fs').promises.readFile('path', 'utf-8'), | ||
}) | ||
@@ -35,7 +57,7 @@ ] | ||
## Options define | ||
## Type define | ||
```typescript | ||
```ts | ||
export type fastExternal = ( | ||
externals: Record<string, string | (() => string)>, | ||
external: Record<string, string | (() => string | Promise<string>)>, | ||
options?: { | ||
@@ -48,2 +70,7 @@ /** | ||
format: 'esm' | 'cjs' | ||
/** | ||
* @default true | ||
* Whether to insert the external module into "optimizeDeps.exclude" | ||
*/ | ||
optimize: boolean | ||
} | ||
@@ -50,0 +77,0 @@ ) => VitePlugin |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10508
5
160
93