Skip to content

Commit 8316828

Browse files
committed
feat: add tree shaking plugin mvp
1 parent 4c60220 commit 8316828

51 files changed

Lines changed: 4693 additions & 11 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@openapi-qraft/tree-shaking-plugin": minor
3+
---
4+
5+
Add a cross-bundler tree-shaking plugin for generated context API clients.

.github/workflows/e2e.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
run: yarn install --immutable
4040

4141
- name: Build
42-
run: yarn build:publishable
42+
run: yarn build:publishable --force
4343

4444
- name: Remove Verdaccio Storage
4545
run: rm -rf e2e/verdaccio-storage

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
run: yarn install --immutable
3131

3232
- name: Build
33-
run: yarn build:publishable
33+
run: yarn build:publishable --force
3434

3535
- name: Create dummy npmrc # Prevent creation of '.npmrc' by 'changesets-gitlab' with the 'NPM_TOKEN'
3636
run: touch ".npmrc"

e2e/README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# @team-monite/e2e - End-to-End Package Testing
1+
# @qraft/e2e - End-to-End Package Testing
22

33
## Overview
44

5-
This package is dedicated to testing the functionality of the `@monite/*` packages. It allows for verification of package installation capabilities and the ability of building projects using these installed packages.
5+
This package is dedicated to testing the functionality of the `@qraft/*` packages. It allows for verification of package installation capabilities and the ability of building projects using these installed packages.
66

77
The testing process utilizes [Verdaccio](https://verdaccio.org/), a local package registry, to simulate the publication and installation of packages in a controlled environment. This approach ensures the reliability of the packages before they are released into production.
88

@@ -32,9 +32,16 @@ This command will sequentially run:
3232
- `e2e:build-projects` - Build the test projects.
3333
- `e2e:unpublish-from-private-registry` - Remove packages from the local registry for reuse in future tests.
3434

35-
## Test Stands
35+
### Local Multi-Bundler Run
3636

37-
- `projects/sdk-drop-in-with-vite` - SDK React with Vite as the bundler.
37+
To run only the `tree-shaking-bundlers` fixture in an isolated local directory, use:
38+
39+
```bash
40+
yarn e2e:tree-shaking-bundlers-local
41+
```
42+
43+
This copies `e2e/projects/tree-shaking-bundlers` into `/Users/radist/w/qraft-e2e`, sets `TEST_PROJECTS_DIR` to that directory, and then runs the same publish/update/build/unpublish flow as CI.
44+
It also builds the publishable workspace packages first, matching the GitHub workflow.
3845

3946
## Adding a New Test Stand
4047

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env sh
2+
3+
set -o errexit
4+
set -o nounset
5+
6+
BASE_DIR=$(dirname "$(readlink -f "$0")")
7+
E2E_DIR=$(dirname "$BASE_DIR")
8+
MONOREPO_ROOT=$(cd "$E2E_DIR/.." && pwd)
9+
10+
SOURCE_PROJECT="$MONOREPO_ROOT/e2e/projects/tree-shaking-bundlers"
11+
TARGET_ROOT="${TREE_SHAKING_E2E_DIR:-/Users/radist/w/qraft-e2e}"
12+
13+
NPM_PUBLISH_SCOPES="${NPM_PUBLISH_SCOPES:-openapi-qraft qraft}"
14+
NPM_PUBLISH_REGISTRY="${NPM_PUBLISH_REGISTRY:-http://localhost:4873}"
15+
TEST_PROJECTS_DIR="$TARGET_ROOT"
16+
17+
cleanup() {
18+
status=$?
19+
trap - EXIT INT TERM
20+
21+
if [ "${PUBLISHED_TO_PRIVATE_REGISTRY:-0}" -eq 1 ]; then
22+
echo "Unpublishing packages from private registry..."
23+
(
24+
cd "$E2E_DIR" &&
25+
NPM_PUBLISH_SCOPES="$NPM_PUBLISH_SCOPES" \
26+
NPM_PUBLISH_REGISTRY="$NPM_PUBLISH_REGISTRY" \
27+
yarn e2e:unpublish-from-private-registry
28+
) || echo "Warning: failed to unpublish packages from private registry." >&2
29+
fi
30+
31+
exit "$status"
32+
}
33+
34+
trap cleanup EXIT INT TERM
35+
36+
echo "Preparing local e2e workspace at $TARGET_ROOT..."
37+
rm -rf "$TARGET_ROOT"
38+
mkdir -p "$TARGET_ROOT"
39+
cp -a "$SOURCE_PROJECT" "$TARGET_ROOT/"
40+
41+
echo "Building publishable packages..."
42+
(
43+
cd "$MONOREPO_ROOT" &&
44+
yarn build:publishable
45+
)
46+
47+
rm -rf "$E2E_DIR/verdaccio-storage"
48+
49+
echo "Publishing packages to private registry..."
50+
(
51+
cd "$E2E_DIR" &&
52+
NPM_PUBLISH_SCOPES="$NPM_PUBLISH_SCOPES" \
53+
NPM_PUBLISH_REGISTRY="$NPM_PUBLISH_REGISTRY" \
54+
yarn e2e:publish-to-private-registry
55+
)
56+
PUBLISHED_TO_PRIVATE_REGISTRY=1
57+
58+
echo "Updating local test project from private registry..."
59+
(
60+
cd "$E2E_DIR" &&
61+
NPM_PUBLISH_SCOPES="$NPM_PUBLISH_SCOPES" \
62+
NPM_PUBLISH_REGISTRY="$NPM_PUBLISH_REGISTRY" \
63+
TEST_PROJECTS_DIR="$TEST_PROJECTS_DIR" \
64+
yarn e2e:update-projects-from-private-registry
65+
)
66+
67+
echo "Building local test project..."
68+
(
69+
cd "$E2E_DIR" &&
70+
TEST_PROJECTS_DIR="$TEST_PROJECTS_DIR" \
71+
yarn e2e:build-projects
72+
)

e2e/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"e2e:unpublish-from-private-registry": "NPM_PUBLISH_SCOPES='openapi-qraft qraft' yarn exec bin/unpublish-from-private-registry.sh",
1010
"e2e:update-projects-from-private-registry": "NPM_PUBLISH_SCOPES='openapi-qraft qraft' yarn exec bin/update-projects-from-private-registry.sh",
1111
"e2e:build-projects": "yarn exec bin/build-projects.sh",
12-
"e2e:test": "yarn e2e:publish-to-private-registry && yarn e2e:update-projects-from-private-registry && yarn e2e:build-projects && yarn e2e:unpublish-from-private-registry"
12+
"e2e:test": "yarn e2e:publish-to-private-registry && yarn e2e:update-projects-from-private-registry && yarn e2e:build-projects && yarn e2e:unpublish-from-private-registry",
13+
"e2e:tree-shaking-bundlers-local": "yarn exec bin/tree-shaking-bundlers-local-e2e.sh"
1314
},
1415
"packageManager": "yarn@3.5.0",
1516
"devDependencies": {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/package-lock.json
2+
/dist
3+
node_modules
4+
/src/generated-api
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
openapi: 3.1.0
2+
info:
3+
title: Tree Shaking Vite Fixture
4+
version: 1.0.0
5+
paths:
6+
/pets:
7+
get:
8+
operationId: getPets
9+
tags:
10+
- pets
11+
responses:
12+
'200':
13+
description: Pets list
14+
content:
15+
application/json:
16+
schema:
17+
type: array
18+
items:
19+
$ref: '#/components/schemas/Pet'
20+
post:
21+
operationId: createPet
22+
tags:
23+
- pets
24+
requestBody:
25+
required: true
26+
content:
27+
application/json:
28+
schema:
29+
$ref: '#/components/schemas/NewPet'
30+
responses:
31+
'200':
32+
description: Created pet
33+
content:
34+
application/json:
35+
schema:
36+
$ref: '#/components/schemas/Pet'
37+
/stores:
38+
get:
39+
operationId: getStores
40+
tags:
41+
- stores
42+
responses:
43+
'200':
44+
description: Stores list
45+
content:
46+
application/json:
47+
schema:
48+
type: array
49+
items:
50+
$ref: '#/components/schemas/Store'
51+
components:
52+
schemas:
53+
Pet:
54+
type: object
55+
additionalProperties: false
56+
required:
57+
- id
58+
- name
59+
properties:
60+
id:
61+
type: integer
62+
name:
63+
type: string
64+
NewPet:
65+
type: object
66+
additionalProperties: false
67+
required:
68+
- name
69+
properties:
70+
name:
71+
type: string
72+
Store:
73+
type: object
74+
additionalProperties: false
75+
required:
76+
- id
77+
- title
78+
properties:
79+
id:
80+
type: integer
81+
title:
82+
type: string
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "tree-shaking-bundlers",
3+
"private": true,
4+
"version": "1.0.0",
5+
"description": "End-to-end multi-bundler fixture for @openapi-qraft/tree-shaking-plugin",
6+
"type": "module",
7+
"sideEffects": false,
8+
"scripts": {
9+
"codegen": "openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript ./openapi.yaml --clean -o src/generated-api --openapi-types-import-path '../schema.ts' --openapi-types-file-name schema.ts --explicit-import-extensions --create-api-client-fn createBarrelAPIClient filename:create-barrel-api-client context:BarrelAPIClientContext --create-api-client-fn createRelativeAPIClient filename:create-relative-api-client context:RelativeAPIClientContext --create-api-client-fn createRelativeExtAPIClient filename:create-relative-ts-api-client context:RelativeExtAPIClientContext --create-api-client-fn createAliasAPIClient filename:create-alias-api-client context:AliasAPIClientContext --create-api-client-fn createAliasDirectAPIClient filename:create-alias-direct-api-client context:AliasDirectAPIClientContext",
10+
"build": "node ./scripts/build.mjs",
11+
"build:rspack": "QRAFT_TREE_SHAKE_SCENARIO=barrel-alias node ./scripts/build-rspack.mjs",
12+
"e2e:pre-build": "npm run codegen",
13+
"e2e:post-build": "node ./scripts/assert-dist.mjs"
14+
},
15+
"dependencies": {
16+
"@esbuild-plugins/tsconfig-paths": "^0.1.2",
17+
"@openapi-qraft/cli": "latest",
18+
"@openapi-qraft/react": "latest",
19+
"@openapi-qraft/tree-shaking-plugin": "latest",
20+
"@rollup/plugin-alias": "^6.0.0",
21+
"@rollup/plugin-node-resolve": "^16.0.3",
22+
"tsconfig-paths-webpack-plugin": "^4.2.0"
23+
},
24+
"devDependencies": {
25+
"@rspack/cli": "latest",
26+
"@rspack/core": "latest",
27+
"@types/node": "latest",
28+
"esbuild": "latest",
29+
"esbuild-loader": "latest",
30+
"rollup": "latest",
31+
"rollup-plugin-esbuild": "latest",
32+
"typescript": "latest",
33+
"vite": "latest",
34+
"webpack": "latest",
35+
"webpack-cli": "latest",
36+
"@rspack/resolver": "^0.4.0"
37+
}
38+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { resolve } from 'node:path';
2+
import alias from '@rollup/plugin-alias';
3+
import nodeResolve from '@rollup/plugin-node-resolve';
4+
import { qraftTreeShakeRollup } from '@openapi-qraft/tree-shaking-plugin/rollup';
5+
import esbuild from 'rollup-plugin-esbuild';
6+
import {
7+
createAPIClientFn,
8+
getBundlerOutputDir,
9+
getScenario,
10+
isExternalModuleRequest,
11+
} from './scripts/shared.mjs';
12+
13+
const scenario = getScenario(process.env.QRAFT_TREE_SHAKE_SCENARIO ?? '');
14+
15+
export default {
16+
plugins: [
17+
alias({
18+
entries: [
19+
{
20+
find: /^@\//,
21+
replacement: `${resolve(process.cwd(), 'src')}/`,
22+
},
23+
],
24+
customResolver: nodeResolve({
25+
extensions: ['.ts', '.tsx', '.mts', '.cts', '.mjs', '.js'],
26+
}),
27+
}),
28+
qraftTreeShakeRollup({ createAPIClientFn }),
29+
esbuild({
30+
include: /\.[cm]?[jt]sx?$/,
31+
sourceMap: false,
32+
minify: false,
33+
target: 'es2020',
34+
}),
35+
],
36+
input: resolve(process.cwd(), scenario.entry),
37+
external: isExternalModuleRequest,
38+
output: {
39+
dir: getBundlerOutputDir('rollup', scenario),
40+
format: 'es',
41+
entryFileNames: '[name].js',
42+
chunkFileNames: 'chunks/[name].js',
43+
assetFileNames: 'assets/[name][extname]',
44+
},
45+
treeshake: true,
46+
};

0 commit comments

Comments
 (0)