modular-library 0.0.1 → 0.0.3
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 +21 -0
- package/README.md +53 -3
- package/dist/chunks/createEntries.js +1 -0
- package/dist/createEntries.d.ts +10 -0
- package/dist/rolldown/index.cjs.js +1 -0
- package/dist/rolldown/index.d.ts +2 -0
- package/dist/rolldown/index.es.js +15 -0
- package/dist/rolldown/plugin.d.ts +9 -0
- package/dist/rollup/index.cjs.js +1 -0
- package/dist/rollup/index.d.ts +2 -0
- package/dist/rollup/index.es.js +16 -0
- package/dist/rollup/plugin.d.ts +9 -0
- package/dist/vite/index.cjs.js +1 -0
- package/dist/vite/index.d.ts +2 -0
- package/dist/vite/index.es.js +13 -0
- package/dist/vite/plugin.d.ts +9 -0
- package/package.json +4 -1
- package/.github/FUNDING.yml +0 -12
- package/.github/dependabot.yml +0 -9
- package/.github/workflows/ci.yml +0 -32
- package/AGENTS.md +0 -58
- package/biome.json +0 -40
- package/src/createEntries.ts +0 -59
- package/src/rolldown/index.ts +0 -2
- package/src/rolldown/plugin.test.ts +0 -129
- package/src/rolldown/plugin.ts +0 -34
- package/src/rollup/index.ts +0 -2
- package/src/rollup/plugin.test.ts +0 -114
- package/src/rollup/plugin.ts +0 -34
- package/src/vite/index.ts +0 -2
- package/src/vite/plugin.test.ts +0 -192
- package/src/vite/plugin.ts +0 -40
- package/test/fixture/input1.js +0 -2
- package/test/fixture/input2.js +0 -2
- package/tsconfig.json +0 -19
- package/vite.config.ts +0 -36
- package/vitest.config.ts +0 -18
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 alfredo salzillo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
# modular-library
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
3
7
|
`modular-library` is a utility library for generating modular libraries.
|
|
4
8
|
|
|
9
|
+
## Why
|
|
10
|
+
|
|
11
|
+
Building a modular library manually is usually tedious and error-prone:
|
|
12
|
+
|
|
13
|
+
- keeping `package.json` `exports` in sync with your generated files,
|
|
14
|
+
- wiring and maintaining complex glob-based inputs,
|
|
15
|
+
- avoiding output path mistakes when your source tree grows.
|
|
16
|
+
|
|
17
|
+
`modular-library` is a **zero-config** way to generate modular outputs for `vite`, `rollup`, and `rolldown` with predictable structure.
|
|
18
|
+
|
|
5
19
|
## What is a modular library?
|
|
6
20
|
|
|
7
21
|
A **modular library** is a library split into small, focused modules instead of one large, monolithic package.
|
|
@@ -23,6 +37,28 @@ Typical examples of modular libraries include:
|
|
|
23
37
|
|
|
24
38
|
With `modular-library`, the goal is to make the creation of this kind of modular architecture faster and more consistent.
|
|
25
39
|
|
|
40
|
+
### Why this is different from standard library mode
|
|
41
|
+
|
|
42
|
+
| Approach | Example import | What happens |
|
|
43
|
+
| --- | --- | --- |
|
|
44
|
+
| Standard library mode | `import { button } from "my-lib";` | Requires evaluating the full package entry. |
|
|
45
|
+
| Modular library (`modular-library`) | `import button from "my-lib/button";` | Loads only the `button` module code. |
|
|
46
|
+
|
|
47
|
+
### Before vs. After output
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
# Before (standard single-entry build)
|
|
51
|
+
dist/
|
|
52
|
+
index.js
|
|
53
|
+
|
|
54
|
+
# After (modular output with modular-library)
|
|
55
|
+
dist/
|
|
56
|
+
button.js
|
|
57
|
+
modal.js
|
|
58
|
+
utils/
|
|
59
|
+
formatDate.js
|
|
60
|
+
```
|
|
61
|
+
|
|
26
62
|
## Installation
|
|
27
63
|
|
|
28
64
|
> **Node.js requirement:** This library supports only Node.js `22` or newer.
|
|
@@ -89,9 +125,11 @@ export default {
|
|
|
89
125
|
|
|
90
126
|
All plugin variants support the same options:
|
|
91
127
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
128
|
+
| Option | Type | Default | Description |
|
|
129
|
+
| --- | --- | --- | --- |
|
|
130
|
+
| `relative` | `string` | `"src/"` | Base path removed from generated output keys. |
|
|
131
|
+
| `glob` | [`GlobOptions`](https://nodejs.org/api/fs.html#fsglobsyncpattern-options) | `undefined` | Options forwarded to `fs.globSync`. |
|
|
132
|
+
| `transformOutputPath` | `(outputPath: string, inputPath: string) => string` | `undefined` | Customize each generated output path. |
|
|
95
133
|
|
|
96
134
|
Example with options:
|
|
97
135
|
|
|
@@ -113,6 +151,18 @@ export default {
|
|
|
113
151
|
};
|
|
114
152
|
```
|
|
115
153
|
|
|
154
|
+
### Exports tip
|
|
155
|
+
|
|
156
|
+
To make your package consumable with subpath imports, add an `exports` map in your `package.json`:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"exports": {
|
|
161
|
+
"./*": "./dist/*.js"
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
116
166
|
## Development
|
|
117
167
|
|
|
118
168
|
```bash
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`node:fs`),l=require(`node:path`);l=s(l);var u=e=>typeof e==`string`,d=e=>e.replace(/\.[^/.]+$/,``).replace(/\\/g,`/`),f={relative:`src/`},p=(e,t)=>{let n=[e].flat(),r=n.filter(e=>u(e)),i=n.filter(e=>!u(e)),a=(0,c.globSync)(r.map(e=>e.replace(/\\/g,`/`)),{...t?.glob,withFileTypes:!1}).map(e=>{let n=l.default.relative(t?.relative??f.relative,e),r=n.startsWith(`../`)?l.default.relative(`./`,e):n;return[d(t?.transformOutputPath?t.transformOutputPath(r,e):r),e]});return Object.assign({},Object.fromEntries(a),...i)};Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return p}});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GlobOptionsWithoutFileTypes } from 'node:fs';
|
|
2
|
+
export type CreateEntryInput = string | string[] | Record<string, string>;
|
|
3
|
+
type CreateEntriesGlobOptions = GlobOptionsWithoutFileTypes;
|
|
4
|
+
export type CreateEntriesOptions = {
|
|
5
|
+
glob?: CreateEntriesGlobOptions;
|
|
6
|
+
relative?: string;
|
|
7
|
+
transformOutputPath?: (path: string, fileName: string) => string;
|
|
8
|
+
};
|
|
9
|
+
declare const createEntries: (input: CreateEntryInput, options?: CreateEntriesOptions) => any;
|
|
10
|
+
export default createEntries;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require(`../chunks/createEntries.js`);var t=`modular-library/rolldown`,n=n=>({name:t,options(t){if(!t.input)return this.warn&&this.warn(`At least one input is required`),t;let r=e.t(t.input,n);return{...t,input:r}}});module.exports=n;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { t as e } from "../chunks/createEntries.js";
|
|
2
|
+
//#region src/rolldown/plugin.ts
|
|
3
|
+
var t = "modular-library/rolldown", n = (n) => ({
|
|
4
|
+
name: t,
|
|
5
|
+
options(t) {
|
|
6
|
+
if (!t.input) return this.warn && this.warn("At least one input is required"), t;
|
|
7
|
+
let r = e(t.input, n);
|
|
8
|
+
return {
|
|
9
|
+
...t,
|
|
10
|
+
input: r
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { n as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Plugin } from 'rolldown';
|
|
2
|
+
import { CreateEntriesOptions } from '../createEntries';
|
|
3
|
+
export type RolldownModularLibraryOptions = CreateEntriesOptions;
|
|
4
|
+
/**
|
|
5
|
+
* rolldownModularLibrary is a rolldown plugin to use multiple entry points and preserve the directory
|
|
6
|
+
* structure in the dist folder
|
|
7
|
+
*/
|
|
8
|
+
declare const rolldownModularLibrary: (options?: RolldownModularLibraryOptions) => Plugin;
|
|
9
|
+
export default rolldownModularLibrary;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require(`../chunks/createEntries.js`);var t=`modular-library/rollup`,n=n=>({name:t,buildStart(){},options(t){if(!t.input)return this.warn&&this.warn(`At least one input is required`),t;let r=e.t(t.input,n);return{...t,input:r}}});module.exports=n;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { t as e } from "../chunks/createEntries.js";
|
|
2
|
+
//#region src/rollup/plugin.ts
|
|
3
|
+
var t = "modular-library/rollup", n = (n) => ({
|
|
4
|
+
name: t,
|
|
5
|
+
buildStart() {},
|
|
6
|
+
options(t) {
|
|
7
|
+
if (!t.input) return this.warn && this.warn("At least one input is required"), t;
|
|
8
|
+
let r = e(t.input, n);
|
|
9
|
+
return {
|
|
10
|
+
...t,
|
|
11
|
+
input: r
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
//#endregion
|
|
16
|
+
export { n as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Plugin } from 'rollup';
|
|
2
|
+
import { CreateEntriesOptions } from '../createEntries';
|
|
3
|
+
export type RollupModularLibraryOptions = CreateEntriesOptions;
|
|
4
|
+
/**
|
|
5
|
+
* modularLibrary is a rollup plugin to use multiple entry point and preserve the directory
|
|
6
|
+
* structure in the dist folder
|
|
7
|
+
* */
|
|
8
|
+
declare const rollupModularLibrary: (options?: RollupModularLibraryOptions) => Plugin;
|
|
9
|
+
export default rollupModularLibrary;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require(`../chunks/createEntries.js`);var t=`modular-library/vite`,n=n=>({name:t,apply:`build`,config(t){if(!t.build?.lib)return this.warn&&this.warn(`The build.lib option is required`),t;let r=t.build?.lib?.entry;return r?(t.build.lib.entry=e.t(r,n),t):(this.warn&&this.warn(`At least one entry is required`),t)}});module.exports=n;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { t as e } from "../chunks/createEntries.js";
|
|
2
|
+
//#region src/vite/plugin.ts
|
|
3
|
+
var t = "modular-library/vite", n = (n) => ({
|
|
4
|
+
name: t,
|
|
5
|
+
apply: "build",
|
|
6
|
+
config(t) {
|
|
7
|
+
if (!t.build?.lib) return this.warn && this.warn("The build.lib option is required"), t;
|
|
8
|
+
let r = t.build?.lib?.entry;
|
|
9
|
+
return r ? (t.build.lib.entry = e(r, n), t) : (this.warn && this.warn("At least one entry is required"), t);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
//#endregion
|
|
13
|
+
export { n as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
import { CreateEntriesOptions } from '../createEntries';
|
|
3
|
+
export type ViteModularLibraryOptions = CreateEntriesOptions;
|
|
4
|
+
/**
|
|
5
|
+
* viteModularLibrary is a vite plugin to use multiple entry points and preserve the directory
|
|
6
|
+
* structure in the dist folder
|
|
7
|
+
*/
|
|
8
|
+
declare const viteModularLibrary: (options?: ViteModularLibraryOptions) => Plugin;
|
|
9
|
+
export default viteModularLibrary;
|
package/package.json
CHANGED
package/.github/FUNDING.yml
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# These are supported funding model platforms
|
|
2
|
-
|
|
3
|
-
github: [alfredosalzillo]
|
|
4
|
-
patreon: # Replace with a single Patreon username
|
|
5
|
-
open_collective: # Replace with a single Open Collective username
|
|
6
|
-
ko_fi: # Replace with a single Ko-fi username
|
|
7
|
-
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
8
|
-
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
9
|
-
liberapay: # Replace with a single Liberapay username
|
|
10
|
-
issuehunt: # Replace with a single IssueHunt username
|
|
11
|
-
otechie: # Replace with a single Otechie username
|
|
12
|
-
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
package/.github/dependabot.yml
DELETED
package/.github/workflows/ci.yml
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
pull_request:
|
|
6
|
-
|
|
7
|
-
jobs:
|
|
8
|
-
test:
|
|
9
|
-
runs-on: ubuntu-latest
|
|
10
|
-
strategy:
|
|
11
|
-
fail-fast: false
|
|
12
|
-
matrix:
|
|
13
|
-
node-version: [22, 23, 24, 25]
|
|
14
|
-
|
|
15
|
-
steps:
|
|
16
|
-
- name: Checkout repository
|
|
17
|
-
uses: actions/checkout@v4
|
|
18
|
-
|
|
19
|
-
- name: Setup Node.js
|
|
20
|
-
uses: actions/setup-node@v4
|
|
21
|
-
with:
|
|
22
|
-
node-version: ${{ matrix.node-version }}
|
|
23
|
-
cache: npm
|
|
24
|
-
|
|
25
|
-
- name: Install dependencies
|
|
26
|
-
run: npm ci
|
|
27
|
-
|
|
28
|
-
- name: Build
|
|
29
|
-
run: npm run build
|
|
30
|
-
|
|
31
|
-
- name: Test
|
|
32
|
-
run: npm test
|
package/AGENTS.md
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# AGENTS.md
|
|
2
|
-
|
|
3
|
-
This file provides context and instructions for AI coding agents working on this project.
|
|
4
|
-
|
|
5
|
-
## Setup Commands
|
|
6
|
-
|
|
7
|
-
- Install dependencies: `npm install`
|
|
8
|
-
- Build the project: `npm run build`
|
|
9
|
-
- Run tests: `npm test`
|
|
10
|
-
- Run lint checks: `npm run lint`
|
|
11
|
-
|
|
12
|
-
## Technology Stack
|
|
13
|
-
|
|
14
|
-
- **TypeScript**: Use TypeScript for all code changes. Follow the existing configuration in `tsconfig.json`.
|
|
15
|
-
- Keep this `AGENTS.md` technology stack section up to date whenever the project tech stack changes.
|
|
16
|
-
|
|
17
|
-
## Development Workflow
|
|
18
|
-
|
|
19
|
-
1. **Keep changes minimal**: Implement the smallest safe change that resolves the issue.
|
|
20
|
-
2. **Build**: Before submitting, ensure the project compiles by running `npm run build`.
|
|
21
|
-
3. **Validate**: Run relevant tests with `npm test` when behavior changes.
|
|
22
|
-
4. **Code Style**: Follow the existing style and naming patterns in the codebase.
|
|
23
|
-
5. **GitHub Workflows**: To test workflows locally, use [`act`](https://nektosact.com/).
|
|
24
|
-
|
|
25
|
-
## Temporary Files
|
|
26
|
-
|
|
27
|
-
- **Temporary Directory**: Always place temporary files in the `.ai-tmp` directory.
|
|
28
|
-
|
|
29
|
-
## Commit Message Guidelines
|
|
30
|
-
|
|
31
|
-
When creating commits, use **Conventional Commits**.
|
|
32
|
-
|
|
33
|
-
### Format
|
|
34
|
-
|
|
35
|
-
```text
|
|
36
|
-
<type>(<scope>): <description>
|
|
37
|
-
|
|
38
|
-
[optional body]
|
|
39
|
-
|
|
40
|
-
[optional footer(s)]
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Types
|
|
44
|
-
|
|
45
|
-
- `feat`: A new feature (minor version update).
|
|
46
|
-
- `fix`: A bug fix (patch version update).
|
|
47
|
-
- `docs`: Documentation changes only.
|
|
48
|
-
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, etc).
|
|
49
|
-
- `refactor`: A code change that neither fixes a bug nor adds a feature.
|
|
50
|
-
- `perf`: A code change that improves performance.
|
|
51
|
-
- `test`: Adding missing tests or correcting existing tests.
|
|
52
|
-
- `build`: Changes that affect the build system or external dependencies.
|
|
53
|
-
- `ci`: Changes to CI configuration files and scripts.
|
|
54
|
-
- `chore`: Other changes that don't modify src or test files.
|
|
55
|
-
|
|
56
|
-
### Breaking Changes
|
|
57
|
-
|
|
58
|
-
Breaking changes must be indicated by a `!` after the type/scope or by including `BREAKING CHANGE:` in the footer.
|
package/biome.json
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
|
|
3
|
-
"vcs": {
|
|
4
|
-
"enabled": true,
|
|
5
|
-
"clientKind": "git",
|
|
6
|
-
"useIgnoreFile": true
|
|
7
|
-
},
|
|
8
|
-
"files": {
|
|
9
|
-
"ignoreUnknown": true,
|
|
10
|
-
"includes": ["**", "!node_modules", "!.next", "!dist", "!build"]
|
|
11
|
-
},
|
|
12
|
-
"formatter": {
|
|
13
|
-
"enabled": true,
|
|
14
|
-
"indentStyle": "space",
|
|
15
|
-
"indentWidth": 2
|
|
16
|
-
},
|
|
17
|
-
"javascript": {
|
|
18
|
-
"formatter": {
|
|
19
|
-
"quoteStyle": "double"
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
"linter": {
|
|
23
|
-
"enabled": true,
|
|
24
|
-
"rules": {
|
|
25
|
-
"recommended": true
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"assist": {
|
|
29
|
-
"actions": {
|
|
30
|
-
"source": {
|
|
31
|
-
"organizeImports": {
|
|
32
|
-
"level": "on",
|
|
33
|
-
"options": {
|
|
34
|
-
"groups": [":PACKAGE:", ":PATH:"]
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
package/src/createEntries.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { globSync, type GlobOptionsWithoutFileTypes } from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
|
|
4
|
-
const isString = (value: unknown): value is string => typeof value === "string";
|
|
5
|
-
const outputFileName = (filePath: string) =>
|
|
6
|
-
filePath.replace(/\.[^/.]+$/, "").replace(/\\/g, "/");
|
|
7
|
-
|
|
8
|
-
export type CreateEntryInput = string | string[] | Record<string, string>;
|
|
9
|
-
type CreateEntriesGlobOptions = GlobOptionsWithoutFileTypes;
|
|
10
|
-
|
|
11
|
-
export type CreateEntriesOptions = {
|
|
12
|
-
glob?: CreateEntriesGlobOptions;
|
|
13
|
-
relative?: string;
|
|
14
|
-
transformOutputPath?: (path: string, fileName: string) => string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const defaultOptions = {
|
|
18
|
-
relative: `src/`,
|
|
19
|
-
};
|
|
20
|
-
const createEntries = (
|
|
21
|
-
input: CreateEntryInput,
|
|
22
|
-
options?: CreateEntriesOptions,
|
|
23
|
-
) => {
|
|
24
|
-
// flat to enable input to be a string or an array
|
|
25
|
-
const inputs = [input].flat();
|
|
26
|
-
// separate globs inputs string from others to enable input to be a mixed array too
|
|
27
|
-
const globs = inputs.filter((value) => isString(value));
|
|
28
|
-
const others = inputs.filter((value) => !isString(value));
|
|
29
|
-
const normalizedGlobs = globs.map((glob) => glob.replace(/\\/g, "/"));
|
|
30
|
-
|
|
31
|
-
// get files from the strings and return as entries Object
|
|
32
|
-
const entries = globSync(normalizedGlobs, {
|
|
33
|
-
...options?.glob,
|
|
34
|
-
withFileTypes: false,
|
|
35
|
-
}).map((name) => {
|
|
36
|
-
const filePath = path.relative(
|
|
37
|
-
options?.relative ?? defaultOptions.relative,
|
|
38
|
-
name,
|
|
39
|
-
);
|
|
40
|
-
const isRelative = !filePath.startsWith(`../`);
|
|
41
|
-
const relativeFilePath = isRelative ? filePath : path.relative(`./`, name);
|
|
42
|
-
return [
|
|
43
|
-
outputFileName(
|
|
44
|
-
options?.transformOutputPath
|
|
45
|
-
? options.transformOutputPath(relativeFilePath, name)
|
|
46
|
-
: relativeFilePath,
|
|
47
|
-
),
|
|
48
|
-
name,
|
|
49
|
-
];
|
|
50
|
-
});
|
|
51
|
-
return Object.assign(
|
|
52
|
-
{},
|
|
53
|
-
Object.fromEntries(entries),
|
|
54
|
-
// add no globs input to the result
|
|
55
|
-
...others,
|
|
56
|
-
);
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
export default createEntries;
|
package/src/rolldown/index.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import type { InputOptions } from "rolldown";
|
|
2
|
-
import modularLibrary from "./plugin";
|
|
3
|
-
|
|
4
|
-
const expectedOutput = ["fixture/input1", "fixture/input2"].sort();
|
|
5
|
-
|
|
6
|
-
const applyOptions = (
|
|
7
|
-
options: InputOptions,
|
|
8
|
-
pluginOptions?: Parameters<typeof modularLibrary>[0],
|
|
9
|
-
) => {
|
|
10
|
-
const plugin = modularLibrary(pluginOptions);
|
|
11
|
-
if (!plugin.options) {
|
|
12
|
-
throw new Error("options hook is required");
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const context = {
|
|
16
|
-
warn: vi.fn(),
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const result = plugin.options.call(context as never, options);
|
|
20
|
-
return {
|
|
21
|
-
result,
|
|
22
|
-
warn: context.warn,
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
describe("modular-library/rolldown", () => {
|
|
27
|
-
it("should have name modular-library/rolldown", () => {
|
|
28
|
-
const plugin = modularLibrary({ relative: "./test" });
|
|
29
|
-
expect(plugin.name).toBe("modular-library/rolldown");
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it("should resolve glob", () => {
|
|
33
|
-
const { result } = applyOptions(
|
|
34
|
-
{
|
|
35
|
-
input: ["test/fixture/**/*.js"],
|
|
36
|
-
},
|
|
37
|
-
{ relative: "./test" },
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
expect(Object.keys(result.input as Record<string, string>).sort()).toEqual(
|
|
41
|
-
expectedOutput,
|
|
42
|
-
);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it("should accept a simple string as input", () => {
|
|
46
|
-
const { result } = applyOptions(
|
|
47
|
-
{
|
|
48
|
-
input: "test/fixture/**/*.js",
|
|
49
|
-
},
|
|
50
|
-
{ relative: "./test" },
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
expect(Object.keys(result.input as Record<string, string>).sort()).toEqual(
|
|
54
|
-
expectedOutput,
|
|
55
|
-
);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it("should accept an array of strings as input", () => {
|
|
59
|
-
const { result } = applyOptions(
|
|
60
|
-
{
|
|
61
|
-
input: ["test/fixture/**/*.js"],
|
|
62
|
-
},
|
|
63
|
-
{ relative: "./test" },
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
expect(Object.keys(result.input as Record<string, string>).sort()).toEqual(
|
|
67
|
-
expectedOutput,
|
|
68
|
-
);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it("should remove unresolved glob", () => {
|
|
72
|
-
const { result } = applyOptions(
|
|
73
|
-
{
|
|
74
|
-
input: ["test/fixture/**/*.js", "/not-found/file.js"],
|
|
75
|
-
},
|
|
76
|
-
{ relative: "./test" },
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
expect(Object.keys(result.input as Record<string, string>).sort()).toEqual(
|
|
80
|
-
expectedOutput,
|
|
81
|
-
);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it("should resolve relative to src as default", () => {
|
|
85
|
-
const { result: outputFilesWithNoOptions } = applyOptions({
|
|
86
|
-
input: ["test/fixture/**/*.js"],
|
|
87
|
-
});
|
|
88
|
-
const { result: outputFilesWithNoRelativeOption } = applyOptions(
|
|
89
|
-
{
|
|
90
|
-
input: ["./test/fixture/**/*.js"],
|
|
91
|
-
},
|
|
92
|
-
{},
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
expect(
|
|
96
|
-
Object.keys(
|
|
97
|
-
outputFilesWithNoOptions.input as Record<string, string>,
|
|
98
|
-
).sort(),
|
|
99
|
-
).toEqual(["test/fixture/input1", "test/fixture/input2"]);
|
|
100
|
-
expect(
|
|
101
|
-
Object.keys(
|
|
102
|
-
outputFilesWithNoRelativeOption.input as Record<string, string>,
|
|
103
|
-
).sort(),
|
|
104
|
-
).toEqual(["test/fixture/input1", "test/fixture/input2"]);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("should resolve output with transformOutputPath option", () => {
|
|
108
|
-
const { result } = applyOptions(
|
|
109
|
-
{
|
|
110
|
-
input: ["test/fixture/**/*.js"],
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
transformOutputPath: (output) => `dest/${output.split("/").at(-1)}`,
|
|
114
|
-
},
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
expect(Object.keys(result.input as Record<string, string>).sort()).toEqual([
|
|
118
|
-
"dest/input1",
|
|
119
|
-
"dest/input2",
|
|
120
|
-
]);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it("should warn when input is missing", () => {
|
|
124
|
-
const { result, warn } = applyOptions({}, { relative: "./test" });
|
|
125
|
-
|
|
126
|
-
expect(warn).toHaveBeenCalledWith("At least one input is required");
|
|
127
|
-
expect(result).toEqual({});
|
|
128
|
-
});
|
|
129
|
-
});
|
package/src/rolldown/plugin.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "rolldown";
|
|
2
|
-
import createEntries, { type CreateEntriesOptions } from "@/createEntries";
|
|
3
|
-
|
|
4
|
-
const pluginName = "modular-library/rolldown";
|
|
5
|
-
|
|
6
|
-
export type RolldownModularLibraryOptions = CreateEntriesOptions;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* rolldownModularLibrary is a rolldown plugin to use multiple entry points and preserve the directory
|
|
10
|
-
* structure in the dist folder
|
|
11
|
-
*/
|
|
12
|
-
const rolldownModularLibrary = (
|
|
13
|
-
options?: RolldownModularLibraryOptions,
|
|
14
|
-
): Plugin => {
|
|
15
|
-
return {
|
|
16
|
-
name: pluginName,
|
|
17
|
-
options(conf) {
|
|
18
|
-
if (!conf.input) {
|
|
19
|
-
if (this.warn) {
|
|
20
|
-
this.warn("At least one input is required");
|
|
21
|
-
}
|
|
22
|
-
return conf;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const input = createEntries(conf.input, options);
|
|
26
|
-
return {
|
|
27
|
-
...conf,
|
|
28
|
-
input,
|
|
29
|
-
};
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export default rolldownModularLibrary;
|
package/src/rollup/index.ts
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { rollup, RollupOptions } from "rollup";
|
|
2
|
-
import importJson from "@rollup/plugin-json";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import modularLibrary from "./plugin";
|
|
5
|
-
|
|
6
|
-
const expectedOutput = ["fixture/input1.js", "fixture/input2.js"].sort();
|
|
7
|
-
|
|
8
|
-
const externalDependencies = ["node:fs", "path"];
|
|
9
|
-
|
|
10
|
-
describe.each([
|
|
11
|
-
["rollup 4", rollup],
|
|
12
|
-
])("modular-library/rollup using %s", (_, rollup) => {
|
|
13
|
-
const generateBundle = (options: RollupOptions) =>
|
|
14
|
-
rollup(options).then((bundle) =>
|
|
15
|
-
bundle.generate({
|
|
16
|
-
format: "cjs",
|
|
17
|
-
}),
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
const generateOutputFileNames = (options: RollupOptions) =>
|
|
21
|
-
generateBundle(options).then(({ output }) =>
|
|
22
|
-
output.map((module) => module.fileName).sort(),
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
it("should have name modular-library/rollup", async () => {
|
|
26
|
-
const plugin = modularLibrary({ relative: "./test" });
|
|
27
|
-
expect("name" in plugin).toBeTruthy();
|
|
28
|
-
expect(plugin.name).toBe("modular-library/rollup");
|
|
29
|
-
});
|
|
30
|
-
it("should resolve glob", async () => {
|
|
31
|
-
const outputFiles = await generateOutputFileNames({
|
|
32
|
-
input: ["test/fixture/**/*.js"],
|
|
33
|
-
plugins: [modularLibrary({ relative: "./test" })],
|
|
34
|
-
});
|
|
35
|
-
expect(outputFiles).toEqual(expectedOutput);
|
|
36
|
-
});
|
|
37
|
-
it("should accept a simple string as input", async () => {
|
|
38
|
-
const outputFiles = await generateOutputFileNames({
|
|
39
|
-
input: "test/fixture/**/*.js",
|
|
40
|
-
plugins: [modularLibrary({ relative: "./test" })],
|
|
41
|
-
});
|
|
42
|
-
expect(outputFiles).toEqual(expectedOutput);
|
|
43
|
-
});
|
|
44
|
-
it("should accept an array of strings as input", async () => {
|
|
45
|
-
const outputFiles = await generateOutputFileNames({
|
|
46
|
-
input: ["test/fixture/**/*.js"],
|
|
47
|
-
plugins: [modularLibrary({ relative: "./test" })],
|
|
48
|
-
});
|
|
49
|
-
expect(outputFiles).toEqual(expectedOutput);
|
|
50
|
-
});
|
|
51
|
-
it("should remove unresolved glob", async () => {
|
|
52
|
-
const outputFiles = await generateOutputFileNames({
|
|
53
|
-
input: ["test/fixture/**/*.js", "/not-found/file.js"],
|
|
54
|
-
plugins: [modularLibrary({ relative: "./test" })],
|
|
55
|
-
});
|
|
56
|
-
expect(outputFiles).toEqual(expectedOutput);
|
|
57
|
-
});
|
|
58
|
-
it("should preserve no string entries", async () => {
|
|
59
|
-
const bundle = generateBundle({
|
|
60
|
-
// @ts-expect-error
|
|
61
|
-
input: [
|
|
62
|
-
"test/fixture/**/*.js",
|
|
63
|
-
{
|
|
64
|
-
test: "path/to/test.js",
|
|
65
|
-
},
|
|
66
|
-
],
|
|
67
|
-
plugins: [modularLibrary({ relative: "./test" })],
|
|
68
|
-
});
|
|
69
|
-
await expect(bundle).rejects.toThrow(/^Could not resolve entry module/);
|
|
70
|
-
});
|
|
71
|
-
it('should resolve relative to "src" as default', async () => {
|
|
72
|
-
const outputFilesWithNoOptions = await generateOutputFileNames({
|
|
73
|
-
input: ["test/fixture/**/*.js"],
|
|
74
|
-
plugins: [modularLibrary(), importJson()],
|
|
75
|
-
external: externalDependencies,
|
|
76
|
-
});
|
|
77
|
-
const outputFilesWithNoRelativeOption = await generateOutputFileNames({
|
|
78
|
-
input: ["./test/fixture/**/*.js"],
|
|
79
|
-
plugins: [modularLibrary({}), importJson()],
|
|
80
|
-
external: externalDependencies,
|
|
81
|
-
});
|
|
82
|
-
expect(outputFilesWithNoOptions).toEqual([
|
|
83
|
-
"test/fixture/input1.js",
|
|
84
|
-
"test/fixture/input2.js",
|
|
85
|
-
]);
|
|
86
|
-
expect(outputFilesWithNoRelativeOption).toEqual([
|
|
87
|
-
"test/fixture/input1.js",
|
|
88
|
-
"test/fixture/input2.js",
|
|
89
|
-
]);
|
|
90
|
-
});
|
|
91
|
-
it('should resolve non relative to "relative" options path to root', async () => {
|
|
92
|
-
const outputFiles = await generateOutputFileNames({
|
|
93
|
-
input: ["test/fixture/**/*.js"],
|
|
94
|
-
plugins: [modularLibrary(), importJson()],
|
|
95
|
-
external: ["node:fs", "path"],
|
|
96
|
-
});
|
|
97
|
-
expect(outputFiles).toEqual([
|
|
98
|
-
"test/fixture/input1.js",
|
|
99
|
-
"test/fixture/input2.js",
|
|
100
|
-
]);
|
|
101
|
-
});
|
|
102
|
-
it('should resolve output to "dist" directory', async () => {
|
|
103
|
-
const outputFiles = await generateOutputFileNames({
|
|
104
|
-
input: ["test/fixture/**/*.js"],
|
|
105
|
-
plugins: [
|
|
106
|
-
modularLibrary({
|
|
107
|
-
transformOutputPath: (output) => `dest/${path.basename(output)}`,
|
|
108
|
-
}),
|
|
109
|
-
],
|
|
110
|
-
external: ["node:fs", "path"],
|
|
111
|
-
});
|
|
112
|
-
expect(outputFiles).toEqual(["dest/input1.js", "dest/input2.js"]);
|
|
113
|
-
});
|
|
114
|
-
});
|
package/src/rollup/plugin.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "rollup";
|
|
2
|
-
import createEntries, { CreateEntriesOptions } from "@/createEntries";
|
|
3
|
-
|
|
4
|
-
const pluginName = "modular-library/rollup";
|
|
5
|
-
|
|
6
|
-
export type RollupModularLibraryOptions = CreateEntriesOptions;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* modularLibrary is a rollup plugin to use multiple entry point and preserve the directory
|
|
10
|
-
* structure in the dist folder
|
|
11
|
-
* */
|
|
12
|
-
const rollupModularLibrary = (
|
|
13
|
-
options?: RollupModularLibraryOptions,
|
|
14
|
-
): Plugin => {
|
|
15
|
-
return {
|
|
16
|
-
name: pluginName,
|
|
17
|
-
buildStart() {},
|
|
18
|
-
options(conf) {
|
|
19
|
-
if (!conf.input) {
|
|
20
|
-
if (this.warn) {
|
|
21
|
-
this.warn("At least one input is required");
|
|
22
|
-
}
|
|
23
|
-
return conf;
|
|
24
|
-
}
|
|
25
|
-
const input = createEntries(conf.input, options);
|
|
26
|
-
return {
|
|
27
|
-
...conf,
|
|
28
|
-
input,
|
|
29
|
-
};
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export default rollupModularLibrary;
|
package/src/vite/index.ts
DELETED
package/src/vite/plugin.test.ts
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import type { UserConfig } from "vite";
|
|
2
|
-
import modularLibrary from "./plugin";
|
|
3
|
-
|
|
4
|
-
const expectedOutput = ["fixture/input1", "fixture/input2"].sort();
|
|
5
|
-
|
|
6
|
-
const applyConfig = (
|
|
7
|
-
config: UserConfig,
|
|
8
|
-
pluginOptions?: Parameters<typeof modularLibrary>[0],
|
|
9
|
-
) => {
|
|
10
|
-
const plugin = modularLibrary(pluginOptions);
|
|
11
|
-
if (!plugin.config) {
|
|
12
|
-
throw new Error("config hook is required");
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const context = {
|
|
16
|
-
warn: vi.fn(),
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
// @ts-expect-error
|
|
20
|
-
const result = plugin.config.call(context as never, config);
|
|
21
|
-
return {
|
|
22
|
-
result,
|
|
23
|
-
warn: context.warn,
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
describe("modular-library/vite", () => {
|
|
28
|
-
it("should have name modular-library/vite", () => {
|
|
29
|
-
const plugin = modularLibrary({ relative: "./test" });
|
|
30
|
-
expect(plugin.name).toBe("modular-library/vite");
|
|
31
|
-
expect(plugin.apply).toBe("build");
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("should warn when build.lib is missing", () => {
|
|
35
|
-
const { result, warn } = applyConfig({});
|
|
36
|
-
|
|
37
|
-
expect(warn).toHaveBeenCalledWith("The build.lib option is required");
|
|
38
|
-
expect(result).toEqual({});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("should warn when build.lib.entry is missing", () => {
|
|
42
|
-
const { result, warn } = applyConfig({
|
|
43
|
-
build: {
|
|
44
|
-
// @ts-expect-error
|
|
45
|
-
lib: {},
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
expect(warn).toHaveBeenCalledWith("At least one entry is required");
|
|
50
|
-
expect(result).toEqual({
|
|
51
|
-
build: {
|
|
52
|
-
lib: {},
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("should resolve glob", () => {
|
|
58
|
-
const { result } = applyConfig(
|
|
59
|
-
{
|
|
60
|
-
build: {
|
|
61
|
-
lib: {
|
|
62
|
-
entry: ["test/fixture/**/*.js"],
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
{ relative: "./test" },
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
expect(
|
|
70
|
-
Object.keys(
|
|
71
|
-
(result.build?.lib as { entry: Record<string, string> }).entry,
|
|
72
|
-
).sort(),
|
|
73
|
-
).toEqual(expectedOutput);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("should accept a simple string as input", () => {
|
|
77
|
-
const { result } = applyConfig(
|
|
78
|
-
{
|
|
79
|
-
build: {
|
|
80
|
-
lib: {
|
|
81
|
-
entry: "test/fixture/**/*.js",
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
{ relative: "./test" },
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
expect(
|
|
89
|
-
Object.keys(
|
|
90
|
-
(result.build?.lib as { entry: Record<string, string> }).entry,
|
|
91
|
-
).sort(),
|
|
92
|
-
).toEqual(expectedOutput);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("should accept an array of strings as input", () => {
|
|
96
|
-
const { result } = applyConfig(
|
|
97
|
-
{
|
|
98
|
-
build: {
|
|
99
|
-
lib: {
|
|
100
|
-
entry: ["test/fixture/**/*.js"],
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
{ relative: "./test" },
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
expect(
|
|
108
|
-
Object.keys(
|
|
109
|
-
(result.build?.lib as { entry: Record<string, string> }).entry,
|
|
110
|
-
).sort(),
|
|
111
|
-
).toEqual(expectedOutput);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("should remove unresolved glob", () => {
|
|
115
|
-
const { result } = applyConfig(
|
|
116
|
-
{
|
|
117
|
-
build: {
|
|
118
|
-
lib: {
|
|
119
|
-
entry: ["test/fixture/**/*.js", "/not-found/file.js"],
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
{ relative: "./test" },
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
expect(
|
|
127
|
-
Object.keys(
|
|
128
|
-
(result.build?.lib as { entry: Record<string, string> }).entry,
|
|
129
|
-
).sort(),
|
|
130
|
-
).toEqual(expectedOutput);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it("should resolve relative to src as default", () => {
|
|
134
|
-
const { result: outputFilesWithNoOptions } = applyConfig({
|
|
135
|
-
build: {
|
|
136
|
-
lib: {
|
|
137
|
-
entry: ["test/fixture/**/*.js"],
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
const { result: outputFilesWithNoRelativeOption } = applyConfig(
|
|
142
|
-
{
|
|
143
|
-
build: {
|
|
144
|
-
lib: {
|
|
145
|
-
entry: ["./test/fixture/**/*.js"],
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
{},
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
expect(
|
|
153
|
-
Object.keys(
|
|
154
|
-
(
|
|
155
|
-
outputFilesWithNoOptions.build?.lib as {
|
|
156
|
-
entry: Record<string, string>;
|
|
157
|
-
}
|
|
158
|
-
).entry,
|
|
159
|
-
).sort(),
|
|
160
|
-
).toEqual(["test/fixture/input1", "test/fixture/input2"]);
|
|
161
|
-
expect(
|
|
162
|
-
Object.keys(
|
|
163
|
-
(
|
|
164
|
-
outputFilesWithNoRelativeOption.build?.lib as {
|
|
165
|
-
entry: Record<string, string>;
|
|
166
|
-
}
|
|
167
|
-
).entry,
|
|
168
|
-
).sort(),
|
|
169
|
-
).toEqual(["test/fixture/input1", "test/fixture/input2"]);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it("should resolve output with transformOutputPath option", () => {
|
|
173
|
-
const { result } = applyConfig(
|
|
174
|
-
{
|
|
175
|
-
build: {
|
|
176
|
-
lib: {
|
|
177
|
-
entry: ["test/fixture/**/*.js"],
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
transformOutputPath: (output) => `dest/${output.split("/").at(-1)}`,
|
|
183
|
-
},
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
expect(
|
|
187
|
-
Object.keys(
|
|
188
|
-
(result.build?.lib as { entry: Record<string, string> }).entry,
|
|
189
|
-
).sort(),
|
|
190
|
-
).toEqual(["dest/input1", "dest/input2"]);
|
|
191
|
-
});
|
|
192
|
-
});
|
package/src/vite/plugin.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
2
|
-
import createEntries, { type CreateEntriesOptions } from "@/createEntries";
|
|
3
|
-
|
|
4
|
-
const pluginName = "modular-library/vite";
|
|
5
|
-
|
|
6
|
-
export type ViteModularLibraryOptions = CreateEntriesOptions;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* viteModularLibrary is a vite plugin to use multiple entry points and preserve the directory
|
|
10
|
-
* structure in the dist folder
|
|
11
|
-
*/
|
|
12
|
-
const viteModularLibrary = (options?: ViteModularLibraryOptions): Plugin => {
|
|
13
|
-
return {
|
|
14
|
-
name: pluginName,
|
|
15
|
-
apply: "build",
|
|
16
|
-
config(config) {
|
|
17
|
-
if (!config.build?.lib) {
|
|
18
|
-
if (this.warn) {
|
|
19
|
-
this.warn("The build.lib option is required");
|
|
20
|
-
}
|
|
21
|
-
return config;
|
|
22
|
-
}
|
|
23
|
-
const entry = config.build?.lib?.entry;
|
|
24
|
-
|
|
25
|
-
if (!entry) {
|
|
26
|
-
if (this.warn) {
|
|
27
|
-
this.warn("At least one entry is required");
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return config;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
config.build.lib.entry = createEntries(entry, options);
|
|
34
|
-
|
|
35
|
-
return config;
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export default viteModularLibrary;
|
package/test/fixture/input1.js
DELETED
package/test/fixture/input2.js
DELETED
package/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "CommonJS",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"declaration": true,
|
|
7
|
-
"outDir": "dist",
|
|
8
|
-
"rootDir": "src",
|
|
9
|
-
"strict": true,
|
|
10
|
-
"esModuleInterop": true,
|
|
11
|
-
"forceConsistentCasingInFileNames": true,
|
|
12
|
-
"skipLibCheck": true,
|
|
13
|
-
"baseUrl": ".",
|
|
14
|
-
"paths": {
|
|
15
|
-
"@/*": ["src/*"]
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
"include": ["src", "node_modules/vitest/globals.d.ts"]
|
|
19
|
-
}
|
package/vite.config.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import react from "@vitejs/plugin-react";
|
|
2
|
-
import dts from "unplugin-dts/vite";
|
|
3
|
-
import { defineConfig } from "vite";
|
|
4
|
-
import { resolve } from "node:path";
|
|
5
|
-
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
plugins: [
|
|
8
|
-
react(),
|
|
9
|
-
dts({
|
|
10
|
-
copyDtsFiles: true,
|
|
11
|
-
outDirs: ["dist"],
|
|
12
|
-
exclude: ["src/**/*.test.ts"],
|
|
13
|
-
beforeWriteFile: (filePath, content) => ({
|
|
14
|
-
filePath: filePath.replace(/([\\/])dist\1src\1/, "$1dist$1"),
|
|
15
|
-
content,
|
|
16
|
-
}),
|
|
17
|
-
}),
|
|
18
|
-
],
|
|
19
|
-
build: {
|
|
20
|
-
lib: {
|
|
21
|
-
entry: {
|
|
22
|
-
"rolldown/index": resolve(__dirname, "src/rolldown/index.ts"),
|
|
23
|
-
"rollup/index": resolve(__dirname, "src/rollup/index.ts"),
|
|
24
|
-
"vite/index": resolve(__dirname, "src/vite/index.ts"),
|
|
25
|
-
},
|
|
26
|
-
formats: ["es", "cjs"],
|
|
27
|
-
fileName: (format, entryName) => `${entryName}.${format}.js`,
|
|
28
|
-
},
|
|
29
|
-
rolldownOptions: {
|
|
30
|
-
output: {
|
|
31
|
-
chunkFileNames: "chunks/[name].js",
|
|
32
|
-
},
|
|
33
|
-
external: ["node:path", "node:fs"],
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
});
|
package/vitest.config.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vitest/config";
|
|
2
|
-
import { resolve } from "node:path";
|
|
3
|
-
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
resolve: {
|
|
6
|
-
alias: {
|
|
7
|
-
"@": resolve(__dirname, "src"),
|
|
8
|
-
},
|
|
9
|
-
},
|
|
10
|
-
test: {
|
|
11
|
-
environment: "node",
|
|
12
|
-
globals: true,
|
|
13
|
-
coverage: {
|
|
14
|
-
provider: "v8",
|
|
15
|
-
reportsDirectory: "./coverage",
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
});
|