@esmx/import 3.0.0-rc.18 → 3.0.0-rc.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Vanelink
3
+ Copyright (c) 2020 Esmx Team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ <div align="center">
2
+ <img src="https://www.esmnext.com/logo.svg?t=2025" width="120" alt="Esmx Logo" />
3
+ <h1>@esmx/import</h1>
4
+
5
+ <div>
6
+ <a href="https://www.npmjs.com/package/@esmx/import">
7
+ <img src="https://img.shields.io/npm/v/@esmx/import.svg" alt="npm version" />
8
+ </a>
9
+ <a href="https://github.com/esmnext/esmx/actions/workflows/build.yml">
10
+ <img src="https://github.com/esmnext/esmx/actions/workflows/build.yml/badge.svg" alt="Build" />
11
+ </a>
12
+ <a href="https://www.esmnext.com/coverage/">
13
+ <img src="https://img.shields.io/badge/coverage-live%20report-brightgreen" alt="Coverage Report" />
14
+ </a>
15
+ <a href="https://nodejs.org/">
16
+ <img src="https://img.shields.io/node/v/@esmx/import.svg" alt="node version" />
17
+ </a>
18
+ <a href="https://bundlephobia.com/package/@esmx/import">
19
+ <img src="https://img.shields.io/bundlephobia/minzip/@esmx/import" alt="size" />
20
+ </a>
21
+ </div>
22
+
23
+ <p>Node.js server-side implementation of Import Maps for the Esmx framework</p>
24
+
25
+ <p>
26
+ English | <a href="https://github.com/esmnext/esmx/blob/master/packages/import/README.zh-CN.md">中文</a>
27
+ </p>
28
+ </div>
29
+
30
+ ## 🚀 Features
31
+
32
+ - **Dual Implementation** - VM mode for development and Loader mode for production
33
+ - **Hot Reload Support** - VM mode supports multiple creation for development flexibility
34
+ - **High Performance** - Loader mode optimized for production deployment
35
+ - **Node.js Focused** - Specifically designed for Node.js server-side environments
36
+ - **TypeScript Ready** - Full TypeScript support with excellent type safety
37
+ - **ESM Standards** - Fully compliant with Import Maps specification
38
+
39
+ ## 📦 Installation
40
+
41
+ ```bash
42
+ npm install @esmx/import
43
+ ```
44
+
45
+ ## 🚀 Quick Start
46
+
47
+ ```typescript
48
+ import { createVmImport } from '@esmx/import';
49
+ import { pathToFileURL } from 'node:url';
50
+
51
+ const vmImport = createVmImport(baseURL, importMap);
52
+ const module = await vmImport('my-app/src/utils', import.meta.url);
53
+ ```
54
+
55
+ ## 📖 Mode Comparison
56
+
57
+ `@esmx/import` provides two different Import Maps implementation approaches:
58
+
59
+ | Feature | VM Mode | Loader Mode |
60
+ |---------|---------|-------------|
61
+ | **Function** | `createVmImport()` | `createLoaderImport()` |
62
+ | **Environment** | Development | Production |
63
+ | **Hot Reload** | ✅ Supports multiple creation | ❌ Can only be created once |
64
+ | **Performance** | Relatively slower | High performance |
65
+ | **Isolation** | Fully isolated VM environment | Uses Node.js native Loader |
66
+ | **Debugging** | Easy for development debugging | Suitable for production deployment |
67
+
68
+ ## 🔧 Usage Examples
69
+
70
+ ### VM Mode (Development)
71
+
72
+ ```typescript
73
+ import { createVmImport } from '@esmx/import';
74
+ import { pathToFileURL } from 'node:url';
75
+
76
+ const baseURL = pathToFileURL('/project');
77
+ const importMap = {
78
+ imports: {
79
+ 'my-app/src/utils': '/project/src/utils.mjs'
80
+ }
81
+ };
82
+
83
+ const vmImport = createVmImport(baseURL, importMap);
84
+ const module = await vmImport('my-app/src/utils', import.meta.url);
85
+ ```
86
+
87
+ ### Loader Mode (Production)
88
+
89
+ ```typescript
90
+ import { createLoaderImport } from '@esmx/import';
91
+ import { pathToFileURL } from 'node:url';
92
+
93
+ const baseURL = pathToFileURL('/app/dist/server');
94
+ const importMap = {
95
+ imports: {
96
+ 'my-app/src/utils': '/app/dist/server/my-app/src/utils.mjs'
97
+ }
98
+ };
99
+
100
+ const loaderImport = createLoaderImport(baseURL, importMap);
101
+ const module = await loaderImport('my-app/src/utils');
102
+ ```
103
+
104
+ ## 📚 API Reference
105
+
106
+ ### createVmImport(baseURL, importMap?)
107
+ Creates a VM-based import function with hot reload support.
108
+ ```typescript
109
+ const vmImport = createVmImport(baseURL, importMap);
110
+ const module = await vmImport(specifier, parent, sandbox?, options?);
111
+ ```
112
+
113
+ ### createLoaderImport(baseURL, importMap?)
114
+ Creates a Loader-based import function with high performance, can only be created once.
115
+ ```typescript
116
+ const loaderImport = createLoaderImport(baseURL, importMap);
117
+ const module = await loaderImport(specifier);
118
+ ```
119
+
120
+ ### ImportMap Format
121
+ ```typescript
122
+ interface ImportMap {
123
+ imports?: Record<string, string>;
124
+ scopes?: Record<string, Record<string, string>>;
125
+ }
126
+ ```
127
+
128
+ **Important Notes:**
129
+ - Only supports Node.js environment, not browser
130
+ - Paths must be absolute paths or complete URLs
131
+
132
+ ## 📄 License
133
+
134
+ MIT © [Esmx Team](https://github.com/esmnext/esmx)
@@ -0,0 +1,134 @@
1
+ <div align="center">
2
+ <img src="https://www.esmnext.com/logo.svg?t=2025" width="120" alt="Esmx Logo" />
3
+ <h1>@esmx/import</h1>
4
+
5
+ <div>
6
+ <a href="https://www.npmjs.com/package/@esmx/import">
7
+ <img src="https://img.shields.io/npm/v/@esmx/import.svg" alt="npm version" />
8
+ </a>
9
+ <a href="https://github.com/esmnext/esmx/actions/workflows/build.yml">
10
+ <img src="https://github.com/esmnext/esmx/actions/workflows/build.yml/badge.svg" alt="Build" />
11
+ </a>
12
+ <a href="https://www.esmnext.com/coverage/">
13
+ <img src="https://img.shields.io/badge/coverage-live%20report-brightgreen" alt="Coverage Report" />
14
+ </a>
15
+ <a href="https://nodejs.org/">
16
+ <img src="https://img.shields.io/node/v/@esmx/import.svg" alt="node version" />
17
+ </a>
18
+ <a href="https://bundlephobia.com/package/@esmx/import">
19
+ <img src="https://img.shields.io/bundlephobia/minzip/@esmx/import" alt="size" />
20
+ </a>
21
+ </div>
22
+
23
+ <p>为 Esmx 框架提供 Import Maps 的 Node.js 服务端实现</p>
24
+
25
+ <p>
26
+ <a href="https://github.com/esmnext/esmx/blob/master/packages/import/README.md">English</a> | 中文
27
+ </p>
28
+ </div>
29
+
30
+ ## 🚀 特性
31
+
32
+ - **双重实现** - 开发环境使用 VM 模式,生产环境使用 Loader 模式
33
+ - **热重载支持** - VM 模式支持多次创建,提供开发灵活性
34
+ - **高性能** - Loader 模式为生产部署优化
35
+ - **Node.js 专注** - 专为 Node.js 服务端环境设计
36
+ - **TypeScript 就绪** - 完整的 TypeScript 支持,出色的类型安全
37
+ - **ESM 标准** - 完全符合 Import Maps 规范
38
+
39
+ ## 📦 安装
40
+
41
+ ```bash
42
+ npm install @esmx/import
43
+ ```
44
+
45
+ ## 🚀 快速开始
46
+
47
+ ```typescript
48
+ import { createVmImport } from '@esmx/import';
49
+ import { pathToFileURL } from 'node:url';
50
+
51
+ const vmImport = createVmImport(baseURL, importMap);
52
+ const module = await vmImport('my-app/src/utils', import.meta.url);
53
+ ```
54
+
55
+ ## 📖 模式对比
56
+
57
+ `@esmx/import` 提供两种不同的 Import Maps 实现方式:
58
+
59
+ | 特性 | VM 模式 | Loader 模式 |
60
+ |------|---------|-------------|
61
+ | **函数** | `createVmImport()` | `createLoaderImport()` |
62
+ | **适用环境** | 开发环境 | 生产环境 |
63
+ | **热重载** | ✅ 支持多次创建 | ❌ 只能创建一次 |
64
+ | **性能** | 相对较慢 | 高性能 |
65
+ | **隔离性** | 完全隔离的 VM 环境 | 使用 Node.js 原生 Loader |
66
+ | **调试** | 便于开发调试 | 适合生产部署 |
67
+
68
+ ## 🔧 使用示例
69
+
70
+ ### VM 模式 (开发环境)
71
+
72
+ ```typescript
73
+ import { createVmImport } from '@esmx/import';
74
+ import { pathToFileURL } from 'node:url';
75
+
76
+ const baseURL = pathToFileURL('/project');
77
+ const importMap = {
78
+ imports: {
79
+ 'my-app/src/utils': '/project/src/utils.mjs'
80
+ }
81
+ };
82
+
83
+ const vmImport = createVmImport(baseURL, importMap);
84
+ const module = await vmImport('my-app/src/utils', import.meta.url);
85
+ ```
86
+
87
+ ### Loader 模式 (生产环境)
88
+
89
+ ```typescript
90
+ import { createLoaderImport } from '@esmx/import';
91
+ import { pathToFileURL } from 'node:url';
92
+
93
+ const baseURL = pathToFileURL('/app/dist/server');
94
+ const importMap = {
95
+ imports: {
96
+ 'my-app/src/utils': '/app/dist/server/my-app/src/utils.mjs'
97
+ }
98
+ };
99
+
100
+ const loaderImport = createLoaderImport(baseURL, importMap);
101
+ const module = await loaderImport('my-app/src/utils');
102
+ ```
103
+
104
+ ## 📚 API 参考
105
+
106
+ ### createVmImport(baseURL, importMap?)
107
+ 创建基于 VM 的导入函数,支持热重载。
108
+ ```typescript
109
+ const vmImport = createVmImport(baseURL, importMap);
110
+ const module = await vmImport(specifier, parent, sandbox?, options?);
111
+ ```
112
+
113
+ ### createLoaderImport(baseURL, importMap?)
114
+ 创建基于 Loader 的导入函数,高性能,只能创建一次。
115
+ ```typescript
116
+ const loaderImport = createLoaderImport(baseURL, importMap);
117
+ const module = await loaderImport(specifier);
118
+ ```
119
+
120
+ ### ImportMap 格式
121
+ ```typescript
122
+ interface ImportMap {
123
+ imports?: Record<string, string>;
124
+ scopes?: Record<string, Record<string, string>>;
125
+ }
126
+ ```
127
+
128
+ **注意事项:**
129
+ - 仅支持 Node.js 环境,不支持浏览器
130
+ - 路径必须为绝对路径或完整 URL
131
+
132
+ ## 📄 许可证
133
+
134
+ MIT © [Esmx Team](https://github.com/esmnext/esmx)
@@ -3,9 +3,6 @@ interface Data {
3
3
  baseURL: string;
4
4
  importMap: ImportMap;
5
5
  }
6
- /**
7
- * 创建一个使用 loader 实现的 importmap 的 import 函数,只能创建一次,无热更新,适合生产使用。
8
- */
9
6
  export declare function createLoaderImport(baseURL: URL, importMap?: ImportMap): (specifier: string) => Promise<Record<string, any>>;
10
7
  export declare function initialize(data: Data): void;
11
8
  export declare function resolve(specifier: string, context: Record<string, any>, nextResolve: Function): any;
@@ -18,7 +18,11 @@ export function createLoaderImport(baseURL, importMap = {}) {
18
18
  );
19
19
  }
20
20
  return (specifier) => {
21
- return import(specifier);
21
+ try {
22
+ return import(specifier);
23
+ } catch (e) {
24
+ throw new Error(`Failed to import '${specifier}'`);
25
+ }
22
26
  };
23
27
  }
24
28
  let loaderBaseURL = new URL("file:");
@@ -1,6 +1,3 @@
1
1
  import vm from 'node:vm';
2
2
  import type { ImportMap } from './types';
3
- /**
4
- * 创建一个使用 vm 实现的 importmap 的 import 函数,可以创建多次来实现热更新效果,适合开发使用。
5
- */
6
3
  export declare function createVmImport(baseURL: URL, importMap?: ImportMap): (specifier: string, parent: string, sandbox?: vm.Context, options?: vm.CreateContextOptions) => Promise<Record<string, any>>;
@@ -82,12 +82,10 @@ export function createVmImport(baseURL, importMap = {}) {
82
82
  },
83
83
  identifier: specifier,
84
84
  context,
85
- // @ts-ignore
86
85
  importModuleDynamically: (specifier2, referrer) => {
87
86
  return moduleLinker(
88
87
  specifier2,
89
88
  parsed.filename,
90
- // @ts-ignore
91
89
  referrer.context,
92
90
  cache,
93
91
  [...moduleIds, parsed.pathname]
package/package.json CHANGED
@@ -33,16 +33,15 @@
33
33
  },
34
34
  "devDependencies": {
35
35
  "@biomejs/biome": "1.9.4",
36
- "@esmx/lint": "3.0.0-rc.18",
37
- "@gez/lint": "3.0.0-rc.9",
38
- "@types/node": "22.13.10",
39
- "@vitest/coverage-v8": "3.0.8",
40
- "stylelint": "16.15.0",
36
+ "@esmx/lint": "3.0.0-rc.19",
37
+ "@types/node": "22.15.18",
38
+ "@vitest/coverage-v8": "3.1.3",
39
+ "stylelint": "16.19.1",
41
40
  "typescript": "5.8.2",
42
- "unbuild": "2.0.0",
43
- "vitest": "3.0.8"
41
+ "unbuild": "3.5.0",
42
+ "vitest": "3.1.3"
44
43
  },
45
- "version": "3.0.0-rc.18",
44
+ "version": "3.0.0-rc.19",
46
45
  "type": "module",
47
46
  "private": false,
48
47
  "exports": {
@@ -61,5 +60,5 @@
61
60
  "template",
62
61
  "public"
63
62
  ],
64
- "gitHead": "79ceb323f985dd88dbd7f1349f61f341b6d522c4"
63
+ "gitHead": "83a9cfac4a91b2b54ac576e120bb4541f4cce9d6"
65
64
  }
@@ -9,9 +9,7 @@ interface Data {
9
9
  }
10
10
 
11
11
  let registered = '';
12
- /**
13
- * 创建一个使用 loader 实现的 importmap 的 import 函数,只能创建一次,无热更新,适合生产使用。
14
- */
12
+
15
13
  export function createLoaderImport(baseURL: URL, importMap: ImportMap = {}) {
16
14
  if (!registered) {
17
15
  module.register<Data>(fileURLToPath(import.meta.url), {
@@ -28,11 +26,14 @@ export function createLoaderImport(baseURL: URL, importMap: ImportMap = {}) {
28
26
  );
29
27
  }
30
28
  return (specifier: string): Promise<Record<string, any>> => {
31
- return import(specifier);
29
+ try {
30
+ return import(specifier);
31
+ } catch (e) {
32
+ throw new Error(`Failed to import '${specifier}'`);
33
+ }
32
34
  };
33
35
  }
34
36
 
35
- // loader 线程时的处理逻辑
36
37
  let loaderBaseURL: URL = new URL('file:');
37
38
  let loaderParsedImportMap: IM.ParsedImportMap = {};
38
39
 
package/src/import-vm.ts CHANGED
@@ -27,9 +27,6 @@ async function importBuiltinModule(specifier: string, context: vm.Context) {
27
27
  return module;
28
28
  }
29
29
 
30
- /**
31
- * 创建一个使用 vm 实现的 importmap 的 import 函数,可以创建多次来实现热更新效果,适合开发使用。
32
- */
33
30
  export function createVmImport(baseURL: URL, importMap: ImportMap = {}) {
34
31
  const parsedImportMap = IM.parse(importMap, baseURL);
35
32
  const parse = (specifier: string, parent: string) => {
@@ -101,12 +98,10 @@ export function createVmImport(baseURL: URL, importMap: ImportMap = {}) {
101
98
  },
102
99
  identifier: specifier,
103
100
  context: context,
104
- // @ts-ignore
105
101
  importModuleDynamically: (specifier, referrer) => {
106
102
  return moduleLinker(
107
103
  specifier,
108
104
  parsed.filename,
109
- // @ts-ignore
110
105
  referrer.context,
111
106
  cache,
112
107
  [...moduleIds, parsed.pathname]