Skip to content

Commit 63d641b

Browse files
authored
chore: change build lib to output library in esm (#3771)
* chore: change uild lib to output library in esm * fix: add new build target for minimal build
1 parent 66ae1d3 commit 63d641b

2 files changed

Lines changed: 138 additions & 127 deletions

File tree

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,11 @@
9292
"use-debounce": "10.0.6"
9393
},
9494
"scripts": {
95-
"start": "NODE_OPTIONS=--max-http-header-size=32000 REACT_APP_CONNECT_ENV=Testnet vite --host",
96-
"start:mainnet": "NODE_OPTIONS=--max-http-header-size=32000 REACT_APP_CONNECT_ENV=Mainnet vite --host",
95+
"start": "NODE_OPTIONS=--max-http-header-size=32000 REACT_APP_CONNECT_ENV=Testnet vite --host --force",
96+
"start:mainnet": "NODE_OPTIONS=--max-http-header-size=32000 REACT_APP_CONNECT_ENV=Mainnet vite --host --force",
9797
"build": "npm run build:lib; npm run build:hosted; npm run build:netlify",
9898
"build:lib": "NODE_ENV=production NODE_OPTIONS=--max-old-space-size=10240 vite build",
99+
"build:minimal": "VITE_BUILD_MINIMAL=1 NODE_ENV=production NODE_OPTIONS=--max-old-space-size=10240 vite build",
99100
"build:hosted": "VITE_BUILD_HOSTED=1 NODE_ENV=production NODE_OPTIONS=--max-old-space-size=10240 vite build",
100101
"build:netlify": "VITE_BUILD_NETLIFY=1 NODE_ENV=production NODE_OPTIONS=--max-old-space-size=10240 vite build",
101102
"lint": "scripts/lint.sh",

vite.config.mts

Lines changed: 135 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import path from 'path';
22
import { fileURLToPath } from 'url';
33
import { execSync } from 'child_process';
4-
import { defineConfig, loadEnv, ConfigEnv, LibraryFormats } from 'vite';
5-
import type { PreRenderedAsset } from 'rollup';
4+
import {
5+
defineConfig,
6+
loadEnv,
7+
ConfigEnv,
8+
BuildEnvironmentOptions,
9+
} from 'vite';
10+
import type { InputOption, PreRenderedAsset } from 'rollup';
611
import react from '@vitejs/plugin-react-swc';
712
import checker from 'vite-plugin-checker';
813
import { nodePolyfills } from 'vite-plugin-node-polyfills';
@@ -12,10 +17,11 @@ import packageJson from './package.json';
1217

1318
const __filename = fileURLToPath(import.meta.url);
1419
const __dirname = path.dirname(__filename);
15-
1620
const { version } = packageJson;
21+
const isAnalyze = process.env.ANALYZE === 'true';
1722

1823
let gitHash = 'unknown';
24+
1925
try {
2026
gitHash = execSync('git log -1 --format=%H').toString().replace('\n', '');
2127
} catch (e) {
@@ -27,11 +33,6 @@ console.info(
2733
`\nBuilding Wormhole Connect version=${version} hash=${gitHash}\n`,
2834
);
2935

30-
// There are three configs this file can return.
31-
// 1. local dev server
32-
// 2. production build, for direct import
33-
// 3. production build, hosted by unpkg.com (includes React, auto-binds to DOM)
34-
3536
// TODO: consider using the "VITE_APP_" prefix which is the default for Vite
3637
const envPrefix = 'REACT_APP_';
3738

@@ -65,12 +66,8 @@ const resolve = {
6566
};
6667

6768
const plugins = [
68-
checker({
69-
typescript: true,
70-
}),
71-
dts({
72-
insertTypesEntry: true,
73-
}),
69+
checker({ typescript: true }),
70+
dts({ insertTypesEntry: true }),
7471
react(),
7572
nodePolyfills({
7673
include: [
@@ -97,135 +94,148 @@ const plugins = [
9794
}),
9895
].filter(Boolean);
9996

100-
const optimizeDeps = {};
97+
function assetFileNames(assetInfo: PreRenderedAsset) {
98+
if (assetInfo.name === 'main.css') {
99+
return '[name][extname]';
100+
}
101101

102-
const output: {
103-
assetFileNames: (assetInfo: PreRenderedAsset) => string;
104-
inlineDynamicImports: boolean;
105-
exports: 'named' | 'default' | 'none' | 'auto';
106-
} = {
107-
assetFileNames: (assetInfo: PreRenderedAsset) => {
108-
if (assetInfo.name === 'main.css') {
109-
return '[name][extname]';
110-
}
111-
return '[name]-[hash][extname]';
102+
return '[name]-[hash][extname]';
103+
}
104+
105+
// Netlify and local dev server
106+
const sampleAppBuild: BuildEnvironmentOptions = {
107+
outDir: './build',
108+
rollupOptions: {
109+
input: {
110+
main: 'src/SampleApp.tsx',
111+
index: 'index.html',
112+
} as Record<string, string>,
113+
output: {
114+
assetFileNames,
115+
inlineDynamicImports: false,
116+
exports: 'named' as const,
117+
},
118+
},
119+
};
120+
121+
// Legacy production build, hosted by unpkg.com (includes React, auto-binds to DOM)
122+
const hostedBuild: BuildEnvironmentOptions = {
123+
outDir: './dist',
124+
rollupOptions: {
125+
input: {
126+
main: 'src/main.tsx',
127+
} as Record<string, string>,
128+
output: {
129+
entryFileNames: '[name].mjs',
130+
assetFileNames,
131+
inlineDynamicImports: false,
132+
exports: 'named' as const,
133+
},
134+
},
135+
};
136+
137+
const libEntry: InputOption = [
138+
path.resolve(__dirname, 'src/exports/index.ts'),
139+
path.resolve(__dirname, 'src/exports/mayan.ts'),
140+
path.resolve(__dirname, 'src/exports/ntt.ts'),
141+
path.resolve(__dirname, 'src/exports/hosted.ts'),
142+
path.resolve(__dirname, 'src/exports/executor.ts'),
143+
];
144+
145+
const rollupInput: InputOption = {
146+
index: 'src/exports/index.ts',
147+
mayan: 'src/exports/mayan.ts',
148+
ntt: 'src/exports/ntt.ts',
149+
hosted: 'src/exports/hosted.ts',
150+
executor: 'src/exports/executor.ts',
151+
};
152+
153+
const external = [
154+
'react',
155+
'react/jsx-runtime',
156+
'@emotion/react',
157+
'@emotion/styled',
158+
'@mui/material',
159+
'@mui/icons-material',
160+
'@mui/styled-engine',
161+
'@mui/system',
162+
];
163+
164+
// Production build, for npm import
165+
const libBuild: BuildEnvironmentOptions = {
166+
outDir: './lib',
167+
lib: {
168+
entry: libEntry,
169+
formats: isAnalyze ? ['es'] : ['es', 'cjs'],
170+
fileName: (format, entryname) => {
171+
const n = entryname.split('/').pop()!;
172+
return `${n.split('.')[0]}.${format === 'es' ? 'mjs' : 'js'}`;
173+
},
174+
},
175+
rollupOptions: {
176+
input: rollupInput,
177+
output: {
178+
assetFileNames,
179+
inlineDynamicImports: false,
180+
exports: 'named' as const,
181+
},
182+
external,
183+
},
184+
};
185+
186+
// Minimal build, for submodule import
187+
const minimalBuild: BuildEnvironmentOptions = {
188+
sourcemap: true,
189+
minify: false,
190+
outDir: './lib',
191+
lib: {
192+
entry: libEntry,
193+
formats: ['es'],
194+
},
195+
rollupOptions: {
196+
input: rollupInput,
197+
output: {
198+
entryFileNames: '[name].mjs',
199+
chunkFileNames: '[name].mjs',
200+
assetFileNames: '[name].[ext]',
201+
inlineDynamicImports: false,
202+
preserveModules: true,
203+
preserveModulesRoot: 'src',
204+
},
205+
external,
206+
},
207+
terserOptions: {
208+
mangle: false,
209+
compress: false,
112210
},
113-
inlineDynamicImports: false,
114-
exports: 'named' as const,
115211
};
116212

117213
export default defineConfig(({ command, mode }: ConfigEnv) => {
118214
const env = loadEnv(mode, process.cwd(), '');
119215
const isHosted = !!env.VITE_BUILD_HOSTED;
120216
const isNetlify = !!env.VITE_BUILD_NETLIFY;
121-
const isAnalyze = process.env.ANALYZE === 'true';
122-
123-
if (command === 'serve' || (command === 'build' && isNetlify)) {
124-
// Local development
125-
return {
126-
define,
127-
envPrefix,
128-
resolve,
129-
build: {
130-
outDir: './build',
131-
rollupOptions: {
132-
input: {
133-
main: 'src/SampleApp.tsx',
134-
index: 'index.html',
135-
} as Record<string, string>,
136-
output,
137-
},
138-
},
139-
plugins,
140-
optimizeDeps,
141-
};
142-
} else if (command === 'build') {
143-
//
144-
// Building for production
145-
// There are two possible configs here: invoked by "npm run build" and "npm run build:hosted"
146-
//
147-
// - by default, we build a component library that can be imported and used in React apps
148-
//
149-
// - alternatively, VITE_BUILD_HOSTED=1 causes Vite to build a bundle that is used
150-
// via unpkg.com hosting. This build looks for a DOM element #wormhole-connect and comes
151-
// bundled with a copy of React. This is "legacy mode" and useful only on web apps that don't
152-
// use React.
153-
//
217+
const isMinimal = !!env.VITE_BUILD_MINIMAL;
218+
const isSampleApp = command === 'serve' || (command === 'build' && isNetlify);
154219

220+
let build: BuildEnvironmentOptions | undefined = undefined;
221+
222+
if (isSampleApp) {
223+
build = sampleAppBuild;
224+
} else if (command === 'build') {
155225
if (isHosted) {
156-
return {
157-
define,
158-
envPrefix,
159-
resolve,
160-
build: {
161-
outDir: './dist',
162-
rollupOptions: {
163-
input: {
164-
main: 'src/main.tsx',
165-
} as Record<string, string>,
166-
output: {
167-
entryFileNames: '[name].js',
168-
...output,
169-
},
170-
},
171-
},
172-
plugins,
173-
optimizeDeps,
174-
};
226+
build = hostedBuild;
227+
} else if (isMinimal) {
228+
build = minimalBuild;
175229
} else {
176-
return {
177-
define,
178-
envPrefix,
179-
resolve,
180-
build: {
181-
outDir: './lib',
182-
lib: {
183-
entry: [
184-
path.resolve(__dirname, 'src/exports/index.ts'),
185-
path.resolve(__dirname, 'src/exports/mayan.ts'),
186-
path.resolve(__dirname, 'src/exports/ntt.ts'),
187-
path.resolve(__dirname, 'src/exports/hosted.ts'),
188-
path.resolve(__dirname, 'src/exports/executor.ts'),
189-
],
190-
formats: (isAnalyze ? ['es'] : ['es', 'cjs']) as LibraryFormats[],
191-
fileName: (format, entryname) => {
192-
const n = entryname.split('/').pop()!;
193-
return `${n.split('.')[0]}.${format === 'es' ? 'mjs' : 'js'}`;
194-
},
195-
},
196-
rollupOptions: {
197-
input: {
198-
index: 'src/exports/index.ts',
199-
mayan: 'src/exports/mayan.ts',
200-
ntt: 'src/exports/ntt.ts',
201-
hosted: 'src/exports/hosted.ts',
202-
executor: 'src/exports/executor.ts',
203-
},
204-
output,
205-
external: [
206-
'react',
207-
'react/jsx-runtime',
208-
'@emotion/react',
209-
'@emotion/styled',
210-
'@mui/material',
211-
'@mui/icons-material',
212-
'@mui/styled-engine',
213-
'@mui/system',
214-
],
215-
},
216-
},
217-
plugins,
218-
optimizeDeps,
219-
};
230+
build = libBuild;
220231
}
221232
}
222233

223-
// Default configuration if no conditions are met
224234
return {
235+
build,
225236
define,
226237
envPrefix,
227238
resolve,
228239
plugins,
229-
optimizeDeps,
230240
};
231241
});

0 commit comments

Comments
 (0)