Socket
Socket
Sign inDemoInstall

vite-plugin-fast-external

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vite-plugin-fast-external - npm Package Compare versions

Comparing version 1.2.0 to 1.3.0

32

dist/index.d.ts
import { Plugin as VitePlugin } from 'vite';
export declare function external(externals: Record<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;
*/
export declare type Externals = Record<string, string | (() => string)>;
export interface ExternalOptions {
format: 'esm' | 'cjs';
}): VitePlugin;
}
export declare function external(
/**
* @example
* export default defineConfig({
* plugins: [
* fastExternal({
* // use string
* vue: 'Vue',
* // custom external code by function
* '@scope/name': () => `const Lib = window.LibraryName; export default Lib;`,
* })
* ]
* })
*/
externals: Externals,
/**
* @default 'esm'
* @example
* esm will generate code -> const vue = window['Vue']; export { vue as default };
* cjs will generate code -> const vue = window['Vue']; module.exports = vue;
*/
options?: ExternalOptions): VitePlugin;
export default external;

@@ -9,6 +9,25 @@ "use strict";

const path_1 = __importDefault(require("path"));
function external(externals, options) {
const modCache = {};
const root = process.cwd();
const node_modules = path_1.default.join(root, 'node_modules');
function external(
/**
* @example
* export default defineConfig({
* plugins: [
* fastExternal({
* // use string
* vue: 'Vue',
* // custom external code by function
* '@scope/name': () => `const Lib = window.LibraryName; export default Lib;`,
* })
* ]
* })
*/
externals,
/**
* @default 'esm'
* @example
* esm will generate code -> const vue = window['Vue']; export { vue as default };
* cjs will generate code -> const vue = window['Vue']; module.exports = vue;
*/
options) {
let root = process.cwd();
const viteExternalId = '.vite-plugin-fast-external';

@@ -18,27 +37,12 @@ return {

config(config) {
// ensure viteExternal exist
const externalDir = path_1.default.join(node_modules, viteExternalId);
fs_1.default.existsSync(externalDir) || fs_1.default.mkdirSync(externalDir);
// generate external module file.
for (const [mod, iifeName] of Object.entries(externals)) {
const modFilename = path_1.default.join(node_modules, viteExternalId, `${mod}.js`);
if (!fs_1.default.existsSync(modFilename)) {
// for '@scope/name' package
ensureDir(path_1.default.parse(modFilename).dir);
const modContent = (options === null || options === void 0 ? void 0 : options.format) === 'cjs'
? `const ${iifeName} = window['${iifeName}']; module.exports = ${iifeName};`
: `const ${iifeName} = window['${iifeName}']; export { ${iifeName} as default }`;
fs_1.default.writeFileSync(modFilename, modContent);
}
// init root path
if (config.root && path_1.default.isAbsolute(config.root)) {
// TODO: config.root is relative path
root = config.root;
}
},
load(id) {
const url = cleanUrl(id);
const parsed = path_1.default.parse(url);
const external = Object.entries(externals).find(([name]) => url.includes('node_modules') && parsed.name === name);
if (external) {
const modFilename = path_1.default.join(node_modules, viteExternalId, parsed.base);
return modCache[modFilename] || (modCache[modFilename] = fs_1.default.readFileSync(modFilename, 'utf8'));
}
},
// Step 1
generateExternalFile(root, externals, viteExternalId, (options === null || options === void 0 ? void 0 : options.format) || 'esm');
// Step 2
rewriteAlias(root, config, externals, viteExternalId);
}
};

@@ -56,7 +60,50 @@ }

}
function cleanUrl(url) {
const queryRE = /\?.*$/s;
const hashRE = /#.*$/s;
return url.replace(hashRE, '').replace(queryRE, '');
function node_modules(root, count = 0) {
const p = path_1.default.join(root, 'node_modules');
if (fs_1.default.existsSync(p)) {
return p;
}
if (count >= 19) {
throw new Error('Can not found node_modules directory.');
}
return node_modules(path_1.default.join(root, '..'), count + 1);
}
function generateExternalFile(root, externals, viteExternalId, format) {
// ensure {viteExternal} directory existed
const externalDir = path_1.default.join(node_modules(root), viteExternalId);
fs_1.default.existsSync(externalDir) || fs_1.default.mkdirSync(externalDir);
// generate external module file.
for (const [module, strOrFn] of Object.entries(externals)) {
const modFilename = path_1.default.join(node_modules(root), viteExternalId, `${module}.js`);
if (!fs_1.default.existsSync(modFilename)) {
// for '@scope/name' package
ensureDir(path_1.default.parse(modFilename).dir);
let moduleContent;
if (typeof strOrFn === 'string') {
const iifeName = strOrFn;
moduleContent = format === 'cjs'
? `const ${iifeName} = window['${iifeName}']; module.exports = ${iifeName};`
: `const ${iifeName} = window['${iifeName}']; export { ${iifeName} as default }`;
}
else {
moduleContent = strOrFn();
}
fs_1.default.writeFileSync(modFilename, moduleContent);
}
}
}
function rewriteAlias(root, config, external, viteExternalId) {
if (!config.resolve) {
config.resolve = {};
}
let alias = config.resolve.alias || {};
if (!Array.isArray(alias)) {
alias = Object.entries(alias).map(([k, v]) => ({ find: k, replacement: v }));
}
Object.keys(external).forEach(k => {
// redirect external module to `node_modules/.vite-plugin-fast-external` directory
alias.push({ find: k, replacement: path_1.default.join(node_modules(root), viteExternalId, k) });
});
config.resolve.alias = alias;
}
exports.default = external;
{
"name": "vite-plugin-fast-external",
"version": "1.2.0",
"version": "1.3.0",
"description": "An tiny and fast external plugin for vite.",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -13,3 +13,3 @@ # vite-plugin-fast-external

```bash
npm install vite-plugin-fast-external --save-dev
npm i -D vite-plugin-fast-external
```

@@ -25,13 +25,16 @@

fastExternal({
// use string
vue: 'Vue',
// custom external code by function
'@scope/name': () => `const Lib = window.LibraryName; export default Lib;`,
})
]
});
})
```
## Definition
## Options define
```typescript
export type fastExternal = (
externals: Record<string, string>,
externals: Record<string, string | (() => string)>,
options?: {

@@ -50,26 +53,16 @@ /**

- Generate ESModule code into `node_modules/.vite-plugin-fast-external/xxxx.js` - eg:
1. External-module will be generated code into `node_modules/.vite-plugin-fast-external/xxxx.js`
2. Append an external-module alias
```js
// source code
import Vue from 'vue'
// transformed
const vue = window['Vue']; export { vue as default }
```
- `node_modules/.vite-plugin-fast-external/xxxx.js` will be return when vite load hooks - eg:
```js
{
name: 'vite-plugin-fast-external',
load(id) {
if (id.includes('node_modules/.vite-plugin-fast-external')) {
return fs.readFileSync(externalFilename, 'utf8')
}
resolve: {
alias: [
{
find: 'vue',
replacement: 'User/work-directory/node_modules/.vite-plugin-fast-external/vue.js',
},
],
},
},
}
```
## TODO
- [ ] Support multiple member import, such as `import { ref, watch } from '@vue/composition-api'`
import fs from 'fs'
import path from 'path'
import { Plugin as VitePlugin } from 'vite'
import { Plugin as VitePlugin, UserConfig, Alias } from 'vite'
export type Externals = Record<string, string | (() => string)>
export interface ExternalOptions {
format: 'esm' | 'cjs'
}
export function external(
externals: Record<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'
},
/**
* @example
* export default defineConfig({
* plugins: [
* fastExternal({
* // use string
* vue: 'Vue',
* // custom external code by function
* '@scope/name': () => `const Lib = window.LibraryName; export default Lib;`,
* })
* ]
* })
*/
externals: Externals,
/**
* @default 'esm'
* @example
* esm will generate code -> const vue = window['Vue']; export { vue as default };
* cjs will generate code -> const vue = window['Vue']; module.exports = vue;
*/
options?: ExternalOptions,
): VitePlugin {
const modCache: Record<string, string> = {}
const root = process.cwd()
const node_modules = path.join(root, 'node_modules')
let root = process.cwd()
const viteExternalId = '.vite-plugin-fast-external'

@@ -24,31 +39,14 @@

config(config) {
// ensure viteExternal exist
const externalDir = path.join(node_modules, viteExternalId)
fs.existsSync(externalDir) || fs.mkdirSync(externalDir)
// init root path
if (config.root && path.isAbsolute(config.root)) {
// TODO: config.root is relative path
root = config.root
}
// generate external module file.
for (const [mod, iifeName] of Object.entries(externals)) {
const modFilename = path.join(node_modules, viteExternalId, `${mod}.js`)
if (!fs.existsSync(modFilename)) {
// for '@scope/name' package
ensureDir(path.parse(modFilename).dir)
// Step 1
generateExternalFile(root, externals, viteExternalId, options?.format || 'esm')
const modContent = options?.format === 'cjs'
? `const ${iifeName} = window['${iifeName}']; module.exports = ${iifeName};`
: `const ${iifeName} = window['${iifeName}']; export { ${iifeName} as default }`
fs.writeFileSync(modFilename, modContent)
}
}
},
load(id) {
const url = cleanUrl(id)
const parsed = path.parse(url)
const external = Object.entries(externals).find(([name]) => url.includes('node_modules') && parsed.name === name)
if (external) {
const modFilename = path.join(node_modules, viteExternalId, parsed.base)
return modCache[modFilename] || (modCache[modFilename] = fs.readFileSync(modFilename, 'utf8'))
}
},
// Step 2
rewriteAlias(root, config, externals, viteExternalId)
}
}

@@ -66,8 +64,69 @@ }

function cleanUrl(url: string) {
const queryRE = /\?.*$/s
const hashRE = /#.*$/s
return url.replace(hashRE, '').replace(queryRE, '')
function node_modules(root: string, count = 0) {
const p = path.join(root, 'node_modules')
if (fs.existsSync(p)) {
return p
}
if (count >= 19) {
throw new Error('Can not found node_modules directory.')
}
return node_modules(path.join(root, '..'), count + 1)
}
function generateExternalFile(
root: string,
externals: Externals,
viteExternalId: string,
format: ExternalOptions['format']
) {
// ensure {viteExternal} directory existed
const externalDir = path.join(node_modules(root), viteExternalId)
fs.existsSync(externalDir) || fs.mkdirSync(externalDir)
// generate external module file.
for (const [module, strOrFn] of Object.entries(externals)) {
const modFilename = path.join(node_modules(root), viteExternalId, `${module}.js`)
if (!fs.existsSync(modFilename)) {
// for '@scope/name' package
ensureDir(path.parse(modFilename).dir)
let moduleContent: string
if (typeof strOrFn === 'string') {
const iifeName = strOrFn
moduleContent = format === 'cjs'
? `const ${iifeName} = window['${iifeName}']; module.exports = ${iifeName};`
: `const ${iifeName} = window['${iifeName}']; export { ${iifeName} as default }`
} else {
moduleContent = strOrFn()
}
fs.writeFileSync(modFilename, moduleContent)
}
}
}
function rewriteAlias(
root: string,
config: UserConfig,
external: Externals,
viteExternalId: string
) {
if (!config.resolve) {
config.resolve = {}
}
let alias = config.resolve.alias || {}
if (!Array.isArray(alias)) {
alias = Object.entries(alias).map(([k, v]) => ({ find: k, replacement: v }))
}
Object.keys(external).forEach(k => {
// redirect external module to `node_modules/.vite-plugin-fast-external` directory
(alias as Alias[]).push({ find: k, replacement: path.join(node_modules(root), viteExternalId, k) })
})
config.resolve.alias = alias
}
export default external
SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc