vite-plugin-lib 1.5.0 → 2.0.1

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/README.md CHANGED
@@ -44,10 +44,11 @@ import { library } from 'vite-plugin-lib'
44
44
  export default defineConfig({
45
45
  plugins: [
46
46
  library({
47
- entry: 'src/index.ts', // file name determines output file names
48
- formats: ['es', 'umd'], // optional, default is ['es', 'umd']
49
- name: 'YourGlobalUMDName',
47
+ entry: 'src/index.ts', // file name determines output file names, default is 'src/index.ts'
48
+ formats: ['es'], // optional, default is ['es']
49
+ name: 'YourGlobalUMDName', // optional if format does not include 'umd' or 'iife'
50
50
  external: ['some-package'], // optional, default is all node_modules and builtin modules
51
+ manifest: 'package.json', // relative path to package.json, default is package.json
51
52
  }),
52
53
  ],
53
54
  })
package/dist/index.d.mts CHANGED
@@ -2,14 +2,24 @@ import { LibraryFormats, Plugin } from 'vite';
2
2
  import * as vitePluginDts from 'vite-plugin-dts';
3
3
  export { vitePluginDts as dts };
4
4
 
5
+ declare const coverage: {
6
+ enabled: boolean;
7
+ all: boolean;
8
+ include: string[];
9
+ provider: "v8";
10
+ };
5
11
  interface Options {
6
- name: string;
12
+ /** Defaults to 'src/index.ts' */
7
13
  entry: string;
8
- formats?: LibraryFormats[];
9
14
  externalPackages?: (string | RegExp)[];
15
+ /** Defaults to ['es'] */
16
+ formats?: LibraryFormats[];
17
+ /** Defaults to 'package.json' */
18
+ manifest: string;
19
+ name?: string;
10
20
  verbose?: boolean;
11
21
  }
12
- declare function tsconfigPaths({ verbose }?: Partial<Options>): Plugin;
13
- declare function library(options: Options): Plugin[];
22
+ declare function tsconfigPaths(options?: Partial<Options>): Plugin;
23
+ declare function library(options?: Partial<Options>): Plugin[];
14
24
 
15
- export { Options, library, tsconfigPaths };
25
+ export { type Options, coverage, library, tsconfigPaths };
package/dist/index.d.ts CHANGED
@@ -2,14 +2,24 @@ import { LibraryFormats, Plugin } from 'vite';
2
2
  import * as vitePluginDts from 'vite-plugin-dts';
3
3
  export { vitePluginDts as dts };
4
4
 
5
+ declare const coverage: {
6
+ enabled: boolean;
7
+ all: boolean;
8
+ include: string[];
9
+ provider: "v8";
10
+ };
5
11
  interface Options {
6
- name: string;
12
+ /** Defaults to 'src/index.ts' */
7
13
  entry: string;
8
- formats?: LibraryFormats[];
9
14
  externalPackages?: (string | RegExp)[];
15
+ /** Defaults to ['es'] */
16
+ formats?: LibraryFormats[];
17
+ /** Defaults to 'package.json' */
18
+ manifest: string;
19
+ name?: string;
10
20
  verbose?: boolean;
11
21
  }
12
- declare function tsconfigPaths({ verbose }?: Partial<Options>): Plugin;
13
- declare function library(options: Options): Plugin[];
22
+ declare function tsconfigPaths(options?: Partial<Options>): Plugin;
23
+ declare function library(options?: Partial<Options>): Plugin[];
14
24
 
15
- export { Options, library, tsconfigPaths };
25
+ export { type Options, coverage, library, tsconfigPaths };
package/dist/index.mjs CHANGED
@@ -1,7 +1,8 @@
1
- import { existsSync } from 'node:fs';
2
- import { readdir, readFile, writeFile } from 'node:fs/promises';
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { unlink, readdir, readFile, writeFile } from 'node:fs/promises';
3
3
  import { builtinModules } from 'node:module';
4
4
  import path from 'node:path';
5
+ import process from 'node:process';
5
6
  import c from 'picocolors';
6
7
  import ts from 'typescript';
7
8
  import dts__default from 'vite-plugin-dts';
@@ -19,10 +20,13 @@ function logError(text) {
19
20
  console.error(`${c.red("[vite:lib]")} ${text}`);
20
21
  }
21
22
 
22
- async function generateMTSDeclarations(typesDir) {
23
+ async function generateMTSDeclarations(typesDir, deleteSourceFiles) {
23
24
  const files = await collectFiles(typesDir);
24
25
  for (const file of files) {
25
26
  await createMTSImports(file);
27
+ if (deleteSourceFiles) {
28
+ unlink(file);
29
+ }
26
30
  }
27
31
  log(`Generated ${files.length} MTS declarations.`);
28
32
  }
@@ -41,30 +45,70 @@ async function collectFiles(dir) {
41
45
  async function createMTSImports(file) {
42
46
  const content = await readFile(file, "utf-8");
43
47
  const lines = content.split("\n");
44
- const modified = lines.map(transformLine);
48
+ const modified = lines.map((line) => transformLine(file, line));
45
49
  const targetFile = file.replace(".d.ts", ".d.mts");
46
50
  await writeFile(targetFile, modified.join("\n"));
47
51
  }
48
- function transformLine(line) {
49
- return transformStaticImport(line, "'") ?? transformStaticImport(line, '"') ?? transformExport(line, "'") ?? transformExport(line, '"') ?? line;
52
+ function transformLine(file, line) {
53
+ return transformStaticImport(file, line, "'") ?? transformStaticImport(file, line, '"') ?? transformExport(file, line, "'") ?? transformExport(file, line, '"') ?? line;
50
54
  }
51
- function transformStaticImport(line, quote) {
52
- const isStaticImport = line.includes("import ") && line.includes(`from ${quote}.`);
55
+ function transformStaticImport(file, line, quote) {
56
+ const importPathMarker = `from ${quote}`;
57
+ const isStaticImport = line.includes("import ") && line.includes(`${importPathMarker}.`);
53
58
  if (!isStaticImport) {
54
59
  return void 0;
55
60
  }
61
+ const importStartIndex = line.lastIndexOf(importPathMarker);
62
+ const importPath = line.substring(
63
+ importStartIndex + importPathMarker.length,
64
+ line.length - 2
65
+ );
66
+ const resolvedImport = path.resolve(path.dirname(file), importPath);
67
+ if (existsSync(resolvedImport)) {
68
+ log(`got index import ${resolvedImport}`);
69
+ return `${line.substring(0, line.length - 2)}/index.mjs${quote};`;
70
+ }
56
71
  return `${line.substring(0, line.length - 2)}.mjs${quote};`;
57
72
  }
58
- function transformExport(line, quote) {
59
- const isStaticExport = line.includes("export ") && line.includes(` from ${quote}.`);
73
+ function transformExport(file, line, quote) {
74
+ const exportPathMarker = ` from ${quote}`;
75
+ const isStaticExport = line.includes("export ") && line.includes(`${exportPathMarker}.`);
60
76
  if (!isStaticExport) {
61
77
  return void 0;
62
78
  }
79
+ const exportStartIndex = line.lastIndexOf(exportPathMarker);
80
+ const exportPath = line.substring(
81
+ exportStartIndex + exportPathMarker.length,
82
+ line.length - 2
83
+ );
84
+ const resolvedExport = path.resolve(path.dirname(file), exportPath);
85
+ if (existsSync(resolvedExport)) {
86
+ log(`got index export ${resolvedExport}`);
87
+ return `${line.substring(0, line.length - 2)}/index.mjs${quote};`;
88
+ }
63
89
  return `${line.substring(0, line.length - 2)}.mjs${quote};`;
64
90
  }
65
91
 
66
92
  const typesDir = "dist/types";
67
- function tsconfigPaths({ verbose } = {}) {
93
+ const coverage = {
94
+ enabled: !!process.env.COVERAGE,
95
+ all: true,
96
+ include: ["src/**/*.*"],
97
+ provider: "v8"
98
+ };
99
+ const defaults = {
100
+ entry: "src/index.ts",
101
+ formats: ["es"],
102
+ manifest: "package.json"
103
+ };
104
+ function mergeWithDefaults(options) {
105
+ return {
106
+ ...defaults,
107
+ ...options
108
+ };
109
+ }
110
+ function tsconfigPaths(options = {}) {
111
+ const { verbose } = mergeWithDefaults(options);
68
112
  return {
69
113
  name: "vite-plugin-lib:alias",
70
114
  enforce: "pre",
@@ -94,6 +138,7 @@ function tsconfigPaths({ verbose } = {}) {
94
138
  function buildConfig({
95
139
  entry,
96
140
  formats,
141
+ manifest,
97
142
  name,
98
143
  externalPackages
99
144
  }) {
@@ -116,13 +161,29 @@ function buildConfig({
116
161
  fileName: (format) => formatToFileName(entry, format)
117
162
  },
118
163
  rollupOptions: {
119
- external: externalPackages ?? [/node_modules/, ...builtinModules]
164
+ external: externalPackages ?? [
165
+ /node_modules/,
166
+ ...builtinModules,
167
+ /node:/,
168
+ ...getDependencies(manifest)
169
+ ]
120
170
  }
121
171
  }
122
172
  };
123
173
  }
124
174
  };
125
175
  }
176
+ function getDependencies(manifest) {
177
+ try {
178
+ const content = readFileSync(manifest, { encoding: "utf-8" });
179
+ const { dependencies = {} } = JSON.parse(content);
180
+ return Object.keys(dependencies);
181
+ } catch (error) {
182
+ const message = getErrorMessage(error);
183
+ logError(`Could not read ${c.green(manifest)}: ${message}`);
184
+ throw error;
185
+ }
186
+ }
126
187
  function logInjectedAliases(aliasOptions, config, verbose) {
127
188
  log(`Injected ${c.green(aliasOptions.length)} aliases.`);
128
189
  if (!verbose) {
@@ -194,17 +255,21 @@ function formatToFileName(entry, format) {
194
255
  }
195
256
  return `${entryFileName}.${format}.js`;
196
257
  }
197
- function library(options) {
258
+ function library(options = {}) {
259
+ const mergedOptions = mergeWithDefaults(options);
198
260
  return [
199
261
  tsconfigPaths(),
200
- buildConfig(options),
262
+ buildConfig(mergedOptions),
201
263
  dts__default({
202
264
  cleanVueFileName: true,
203
265
  copyDtsFiles: true,
204
- include: `${path.resolve(options.entry, "..")}/**`,
266
+ include: `${path.resolve(mergedOptions.entry, "..")}/**`,
205
267
  outDir: typesDir,
206
268
  staticImport: true,
207
- afterBuild: includesESFormat(options.formats) ? () => generateMTSDeclarations(typesDir) : void 0
269
+ afterBuild: includesESFormat(mergedOptions.formats) ? () => generateMTSDeclarations(
270
+ typesDir,
271
+ mergedOptions.formats?.length === 1
272
+ ) : void 0
208
273
  })
209
274
  ];
210
275
  }
@@ -248,4 +313,4 @@ function getErrorMessage(error) {
248
313
  return isObject ? error.message : String(error);
249
314
  }
250
315
 
251
- export { library, tsconfigPaths };
316
+ export { coverage, library, tsconfigPaths };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-lib",
3
- "version": "1.5.0",
3
+ "version": "2.0.1",
4
4
  "description": "Vite plugin for build configuration, automatic aliases, and type declarations.",
5
5
  "author": "Jan Müller <janmueller3698@gmail.com>",
6
6
  "license": "MIT",
@@ -18,19 +18,13 @@
18
18
  ],
19
19
  "exports": {
20
20
  ".": {
21
- "require": {
22
- "types": "./dist/index.d.ts",
23
- "default": "./dist/index.cjs"
24
- },
25
21
  "import": {
26
22
  "types": "./dist/index.d.mts",
27
23
  "default": "./dist/index.mjs"
28
24
  }
29
25
  }
30
26
  },
31
- "main": "dist/index.cjs",
32
- "module": "dist/index.mjs",
33
- "types": "dist/index.d.ts",
27
+ "types": "dist/index.d.mts",
34
28
  "files": [
35
29
  "dist",
36
30
  "LICENSE"
@@ -41,14 +35,14 @@
41
35
  },
42
36
  "dependencies": {
43
37
  "picocolors": "1.0.0",
44
- "vite-plugin-dts": "3.3.1"
38
+ "vite-plugin-dts": "3.5.2"
45
39
  },
46
40
  "devDependencies": {
47
- "@types/node": "18.17.1",
48
- "typescript": "5.1.6",
49
- "unbuild": "v2.0.0-rc.0",
50
- "vite": "4.4.7",
51
- "@yeger/tsconfig": "1.1.2"
41
+ "@types/node": "18.17.11",
42
+ "typescript": "5.2.2",
43
+ "unbuild": "2.0.0",
44
+ "vite": "4.4.9",
45
+ "@yeger/tsconfig": "2.0.0"
52
46
  },
53
47
  "publishConfig": {
54
48
  "access": "public"
package/dist/index.cjs DELETED
@@ -1,273 +0,0 @@
1
- 'use strict';
2
-
3
- const node_fs = require('node:fs');
4
- const promises = require('node:fs/promises');
5
- const node_module = require('node:module');
6
- const path = require('node:path');
7
- const c = require('picocolors');
8
- const ts = require('typescript');
9
- const dts = require('vite-plugin-dts');
10
- const vite = require('vite');
11
-
12
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
13
-
14
- function _interopNamespaceCompat(e) {
15
- if (e && typeof e === 'object' && 'default' in e) return e;
16
- const n = Object.create(null);
17
- if (e) {
18
- for (const k in e) {
19
- n[k] = e[k];
20
- }
21
- }
22
- n.default = e;
23
- return n;
24
- }
25
-
26
- const path__default = /*#__PURE__*/_interopDefaultCompat(path);
27
- const c__default = /*#__PURE__*/_interopDefaultCompat(c);
28
- const ts__default = /*#__PURE__*/_interopDefaultCompat(ts);
29
- const dts__default = /*#__PURE__*/_interopDefaultCompat(dts);
30
- const dts__namespace = /*#__PURE__*/_interopNamespaceCompat(dts);
31
-
32
- function log(text) {
33
- console.log(`${c__default.cyan("[vite:lib]")} ${text}`);
34
- }
35
- function logWarn(text) {
36
- console.warn(`${c__default.yellow("[vite:lib]")} ${text}`);
37
- }
38
- function logError(text) {
39
- console.error(`${c__default.red("[vite:lib]")} ${text}`);
40
- }
41
-
42
- async function generateMTSDeclarations(typesDir) {
43
- const files = await collectFiles(typesDir);
44
- for (const file of files) {
45
- await createMTSImports(file);
46
- }
47
- log(`Generated ${files.length} MTS declarations.`);
48
- }
49
- async function collectFiles(dir) {
50
- const entries = await promises.readdir(dir, {
51
- recursive: false,
52
- // does not provide full path to nested files
53
- withFileTypes: true
54
- });
55
- const files = entries.filter((entry) => entry.isFile());
56
- const nestedFiles = await Promise.all(
57
- entries.filter((entry) => entry.isDirectory()).map((entry) => collectFiles(vite.normalizePath(path__default.join(dir, entry.name))))
58
- );
59
- return files.map((file) => vite.normalizePath(path__default.join(dir, file.name))).concat(...nestedFiles);
60
- }
61
- async function createMTSImports(file) {
62
- const content = await promises.readFile(file, "utf-8");
63
- const lines = content.split("\n");
64
- const modified = lines.map(transformLine);
65
- const targetFile = file.replace(".d.ts", ".d.mts");
66
- await promises.writeFile(targetFile, modified.join("\n"));
67
- }
68
- function transformLine(line) {
69
- return transformStaticImport(line, "'") ?? transformStaticImport(line, '"') ?? transformExport(line, "'") ?? transformExport(line, '"') ?? line;
70
- }
71
- function transformStaticImport(line, quote) {
72
- const isStaticImport = line.includes("import ") && line.includes(`from ${quote}.`);
73
- if (!isStaticImport) {
74
- return void 0;
75
- }
76
- return `${line.substring(0, line.length - 2)}.mjs${quote};`;
77
- }
78
- function transformExport(line, quote) {
79
- const isStaticExport = line.includes("export ") && line.includes(` from ${quote}.`);
80
- if (!isStaticExport) {
81
- return void 0;
82
- }
83
- return `${line.substring(0, line.length - 2)}.mjs${quote};`;
84
- }
85
-
86
- const typesDir = "dist/types";
87
- function tsconfigPaths({ verbose } = {}) {
88
- return {
89
- name: "vite-plugin-lib:alias",
90
- enforce: "pre",
91
- config: async (config) => {
92
- const tsconfigPath = path__default.resolve(config.root ?? ".", "tsconfig.json");
93
- const { baseUrl, paths } = await readConfig(tsconfigPath);
94
- if (!baseUrl || !paths) {
95
- log("No paths found in tsconfig.json.");
96
- return config;
97
- }
98
- const pathToAlias = pathToAliasFactory(tsconfigPath, baseUrl, verbose);
99
- const aliasOptions = Object.entries(paths).map(pathToAlias).filter(Boolean);
100
- if (aliasOptions.length > 0) {
101
- logInjectedAliases(aliasOptions, config, verbose);
102
- }
103
- const existingAlias = transformExistingAlias(config.resolve?.alias);
104
- return {
105
- ...config,
106
- resolve: {
107
- ...config.resolve,
108
- alias: [...existingAlias, ...aliasOptions]
109
- }
110
- };
111
- }
112
- };
113
- }
114
- function buildConfig({
115
- entry,
116
- formats,
117
- name,
118
- externalPackages
119
- }) {
120
- if (!externalPackages) {
121
- log("Externalized all packages.");
122
- }
123
- return {
124
- name: "vite-plugin-lib:build",
125
- enforce: "pre",
126
- config: async (config) => {
127
- return {
128
- ...config,
129
- build: {
130
- ...config.build,
131
- lib: {
132
- ...config.build?.lib,
133
- entry: path__default.resolve(config.root ?? ".", entry),
134
- formats,
135
- name,
136
- fileName: (format) => formatToFileName(entry, format)
137
- },
138
- rollupOptions: {
139
- external: externalPackages ?? [/node_modules/, ...node_module.builtinModules]
140
- }
141
- }
142
- };
143
- }
144
- };
145
- }
146
- function logInjectedAliases(aliasOptions, config, verbose) {
147
- log(`Injected ${c__default.green(aliasOptions.length)} aliases.`);
148
- if (!verbose) {
149
- return;
150
- }
151
- const base = `${path__default.resolve(config.root ?? ".")}/`;
152
- aliasOptions.map(
153
- ({ find, replacement }) => `${c__default.gray(">")} ${c__default.green(find.toString())} ${c__default.gray(
154
- c__default.bold("->")
155
- )} ${c__default.green(replacement.replace(base, ""))}`
156
- ).forEach(log);
157
- }
158
- function pathToAliasFactory(tsconfigPath, baseUrl, verbose) {
159
- return ([alias, replacements]) => {
160
- if (replacements.length === 0) {
161
- if (verbose) {
162
- logWarn(`No replacements for alias ${c__default.green(alias)}.`);
163
- }
164
- return void 0;
165
- }
166
- if (verbose && replacements.length > 1) {
167
- logWarn(`Found more than one replacement for alias ${c__default.green(alias)}.`);
168
- logWarn("Using the first existing replacement.");
169
- }
170
- const find = alias.replace("/*", "");
171
- const replacement = getFirstExistingReplacement(
172
- tsconfigPath,
173
- baseUrl,
174
- replacements,
175
- find
176
- );
177
- if (!replacement) {
178
- if (verbose) {
179
- logWarn(`No replacement found for alias ${c__default.green(alias)}.`);
180
- }
181
- return void 0;
182
- }
183
- return {
184
- find,
185
- replacement
186
- };
187
- };
188
- }
189
- function getFirstExistingReplacement(tsconfigPath, baseUrl, replacements, find, verbose) {
190
- for (const replacement of replacements) {
191
- const resolvedReplacement = path__default.resolve(
192
- tsconfigPath,
193
- baseUrl,
194
- replacement.replace("/*", "") ?? find
195
- );
196
- if (node_fs.existsSync(resolvedReplacement)) {
197
- return resolvedReplacement;
198
- } else if (verbose) {
199
- logWarn(`Path ${c__default.green(replacement)} does not exist.`);
200
- }
201
- }
202
- return void 0;
203
- }
204
- function formatToFileName(entry, format) {
205
- const entryFileName = entry.substring(
206
- entry.lastIndexOf("/") + 1,
207
- entry.lastIndexOf(".")
208
- );
209
- if (format === "es") {
210
- return `${entryFileName}.mjs`;
211
- }
212
- if (format === "cjs") {
213
- return `${entryFileName}.cjs`;
214
- }
215
- return `${entryFileName}.${format}.js`;
216
- }
217
- function library(options) {
218
- return [
219
- tsconfigPaths(),
220
- buildConfig(options),
221
- dts__default({
222
- cleanVueFileName: true,
223
- copyDtsFiles: true,
224
- include: `${path__default.resolve(options.entry, "..")}/**`,
225
- outDir: typesDir,
226
- staticImport: true,
227
- afterBuild: includesESFormat(options.formats) ? () => generateMTSDeclarations(typesDir) : void 0
228
- })
229
- ];
230
- }
231
- function transformExistingAlias(alias) {
232
- if (!alias) {
233
- return [];
234
- }
235
- if (Array.isArray(alias)) {
236
- return alias;
237
- }
238
- return Object.entries(alias).map(([find, replacement]) => ({
239
- find,
240
- replacement
241
- }));
242
- }
243
- async function readConfig(configPath) {
244
- try {
245
- const configFileText = await promises.readFile(configPath, { encoding: "utf-8" });
246
- const { config } = ts__default.parseConfigFileTextToJson(configPath, configFileText);
247
- if (!("baseUrl" in config?.compilerOptions)) {
248
- throw new Error("No baseUrl provided in tsconfig.json.");
249
- }
250
- const { options } = ts__default.parseJsonConfigFileContent(
251
- config,
252
- // eslint-disable-next-line import/no-named-as-default-member
253
- ts__default.sys,
254
- path__default.dirname(configPath)
255
- );
256
- return options;
257
- } catch (error) {
258
- const message = getErrorMessage(error);
259
- logError(`Could not read tsconfig.json: ${message}`);
260
- throw error;
261
- }
262
- }
263
- function includesESFormat(formats) {
264
- return formats?.includes("es") ?? true;
265
- }
266
- function getErrorMessage(error) {
267
- const isObject = typeof error === "object" && error !== null && "message" in error;
268
- return isObject ? error.message : String(error);
269
- }
270
-
271
- exports.dts = dts__namespace;
272
- exports.library = library;
273
- exports.tsconfigPaths = tsconfigPaths;
package/dist/index.d.cts DELETED
@@ -1,15 +0,0 @@
1
- import { LibraryFormats, Plugin } from 'vite';
2
- import * as vitePluginDts from 'vite-plugin-dts';
3
- export { vitePluginDts as dts };
4
-
5
- interface Options {
6
- name: string;
7
- entry: string;
8
- formats?: LibraryFormats[];
9
- externalPackages?: (string | RegExp)[];
10
- verbose?: boolean;
11
- }
12
- declare function tsconfigPaths({ verbose }?: Partial<Options>): Plugin;
13
- declare function library(options: Options): Plugin[];
14
-
15
- export { Options, library, tsconfigPaths };