-
-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tsup build failing with ERR_WORKER_OUT_OF_MEMORY #920
Comments
Same with Tsup version 7.0.0 (Using pnpm, turbo) I have to rollback to Tsup 6.5.0 to make it work Context: React library import { defineConfig } from 'tsup'
export default defineConfig((options) => {
return {
entry: ['src'],
sourcemap: true,
minify: !options.watch,
dts: false,
clean: true,
format: ['esm'],
external: ['react', 'react-hook-form'],
// https://github.com/shuding/react-wrap-balancer/blob/main/tsup.config.ts#L10-L13
esbuildOptions(options) {
options.banner = {
js: '"use client"',
}
},
}
}) Terminal output on build script:
|
Luckily they have a build function import glob from "glob"
import { build } from 'tsup'
import _ from 'lodash';
async function buildStage({ clean, entry }) {
console.log("🚀 ~ building entry ", entry)
try {
await build({
dts: true,
minify: true,
sourcemap: true,
treeshake: true,
splitting: true,
outDir: 'dist',
clean,
entry,
external: ['react', 'react-dom'],
format: ['esm', 'cjs'],
// outExtension({ format }) {
// return {
// js: `.${format}.js`,
// };
// },
});
} catch (error) {
console.log("🚀 ~ error while building entries :", entry);
console.log(error);
throw error;
}
}
export async function buildAllStages() {
const root_file = glob.sync('src/index.ts');
const files = glob.sync('src/components/**/index.ts');
const chunkSize = 3;
const chunks = _.chunk(files, chunkSize);
// await buildStage({ clean:true, entry: chunks[0] });
for await (const [index, chunk] of chunks.entries()) {
console.log('🚀 ~ chnk === ', chunk);
await buildStage({ clean:index===0, entry: chunk });
}
await buildStage({ clean:false, entry: root_file });
// await buildStage({ clean:true, entry: root_file });
}
export function invokeBuild(){
buildAllStages().then(()=>{
console.log("🚀 ~ buildAllStages success");
}).catch((error)=>{
console.log("🚀 ~ buildAllStages error === ", error);
})
}
invokeBuild() fixing it might not be that hard , might try it later |
Rolling back to version |
Unable to migrate back because I need Same error
|
My config if helpful import { defineConfig, Options } from 'tsup';
export default defineConfig((options: Options) => ({
entry: {
'Button/index': 'src/components/atoms/Button/Button.tsx',
// lots more components
},
splitting: false,
format: ['esm', 'cjs'],
dts: true,
minify: true,
external: ['react'],
...options,
})); On |
Is there any work around for this? |
Thanks @rajat1saxena. I can confirm that something in On my MBP ( I have not measured memory usage yet but I am also seem OOM in Github Actions. |
Same here, with this conf when watching for changes (--watch):
It's not systematic, but sometimes after a few minutes we're affected. version 6.6.0 doesn't have this problem. (as mentioned above) |
I'm using
{
"scripts": {
"build": "NODE_OPTIONS='--max-old-space-size=16384' tsup",
"dev": "NODE_OPTIONS='--max-old-space-size=16384' tsup --watch",
}
} |
Duplicate of #875 |
Thanks, worked magically in my case. |
It works for you now but wait a bit while your project grows and it will start to fail. Also while it doesn't fail, it takes significant amount of time that will also cost via your CI. |
I tried running the build commands sequentially like this: const { build } = require("tsup");
const {
buildAllConfig,
buildBlocksConfig,
buildCoreConfig,
buildElementsConfig
} = require("./tsup.config");
async function sequentialBuild() {
await build(buildAllConfig);
await build(buildCoreConfig);
await build(buildBlocksConfig);
await build(buildElementsConfig);
}
sequentialBuild().catch((err) => {
console.error(err);
process.exit(1);
}); where my tsup configurations are split like this: export const buildAllConfig = defineConfig({
name: "Build All",
clean: true,
dts: true,
target: "es2019",
entry: { index: "components/index.ts" },
format: ["cjs", "esm"]
});
export const buildCoreConfig = defineConfig({
name: "Build Core",
clean: true,
dts: true,
target: "es2019",
format: ["cjs", "esm"],
entry: {
// CORE
"types/index": "components/types/index.ts",
"hooks/index": "components/hooks/index.ts",
"blocks/index": "components/blocks/index.ts",
"layout/index": "components/layout/index.ts",
"elements/index": "components/elements/index.ts"
}
});
export const buildBlocksConfig = defineConfig({
name: "Build Blocks",
clean: true,
dts: true,
target: "es2019",
format: ["cjs", "esm"],
entry: {
// BLOCKS
"blocks/misc/index": "components/blocks/misc/index.ts",
"blocks/auth/index": "components/blocks/auth/index.ts",
"blocks/pricing/index": "components/blocks/pricing/index.ts",
"blocks/feedback/index": "components/blocks/feedback/index.ts"
}
});
export const buildElementsConfig = defineConfig({
name: "Build Elements",
clean: true,
dts: true,
target: "es2019",
format: ["cjs", "esm"],
entry: {
// ELEMENTS
"card/index": "components/elements/card/index.ts",
"chip/index": "components/elements/chip/index.ts",
"tabs/index": "components/elements/tabs/index.ts",
"sheet/index": "components/elements/sheet/index.ts",
"logos/index": "components/elements/logos/index.ts",
"radio/index": "components/elements/radio/index.ts",
"table/index": "components/elements/table/index.ts",
"alert/index": "components/elements/alert/index.ts",
"label/index": "components/elements/label/index.ts",
"input/index": "components/elements/input/index.ts",
"badge/index": "components/elements/badge/index.ts",
"dialog/index": "components/elements/dialog/index.ts",
"button/index": "components/elements/button/index.ts",
"select/index": "components/elements/select/index.ts",
"avatar/index": "components/elements/avatar/index.ts",
"switch/index": "components/elements/switch/index.ts",
"command/index": "components/elements/command/index.ts",
"popover/index": "components/elements/popover/index.ts",
"loading/index": "components/elements/loading/index.ts",
"tooltip/index": "components/elements/tooltip/index.ts",
"skeleton/index": "components/elements/skeleton/index.ts",
"combobox/index": "components/elements/combobox/index.ts",
"textarea/index": "components/elements/textarea/index.ts",
"pinInput/index": "components/elements/pinInput/index.ts",
"checkbox/index": "components/elements/checkbox/index.ts",
"progress/index": "components/elements/progress/index.ts",
"accordion/index": "components/elements/accordion/index.ts",
"backToTop/index": "components/elements/backToTop/index.ts",
"dataTable/index": "components/elements/dataTable/index.ts",
"appStores/index": "components/elements/appStores/index.ts",
"sortButton/index": "components/elements/sortButton/index.ts",
"scrollArea/index": "components/elements/scrollArea/index.ts",
"breadcrumb/index": "components/elements/breadcrumb/index.ts",
"phoneInput/index": "components/elements/phoneInput/index.ts",
"splitButton/index": "components/elements/splitButton/index.ts",
"dropdownMenu/index": "components/elements/dropdownMenu/index.ts",
"fileDropzone/index": "components/elements/fileDropzone/index.ts",
"navigationMenu/index": "components/elements/navigationMenu/index.ts",
"stopPropagationWrapper/index":
"components/elements/stopPropagationWrapper/index.ts"
}
});
But I'm still getting the same error:
|
Try only building 3 files at a time |
That actually worked! thanks so much @tigawanna |
Thanks @tigawanna your workaround worked. I was able to build up to 6 files at a time without issues.
Such grouping reduced the number of files built in a set and also made the code look a bit organised. It does rids us of this ERR_WORKER_OUT_OF_MEMORY error until a permanent fix is issued from @egoist |
Glad it helped the fix might be spawning a new worker for every ~4 files , but it feels like such a niche use case that the workaround will be fine for most |
Any news @egoist on this point ? it's preventing us from upgrading to the latest tsup version 😞 (we are stuck on 6.x) |
build: rolled back to tsup 6.6.0 to avoid this issue egoist/tsup#920
Just faced the same issue. Would love if someone from the tsup team can look into patching this |
Getting the same issue on a library with ~100 entrypoints. Running locally I have no problems but in CI seeing the OOM error. Splitting the config into chunks of 2,4,6 basically grinds the whole process to a halt locally. Interestingly |
I have the same issue with |
I played around with a chunking approach where the async function runRollup(options: RollupConfig, chunkSize: number) {
const { rollup } = await import('rollup')
try {
const start = Date.now()
const getDuration = () => {
return `${Math.floor(Date.now() - start)}ms`
}
logger.info('dts', 'Build start')
if (!options.inputConfig.input) {
logger.error('dts', 'No input')
return
}
for (const input of chunkInput(options.inputConfig.input, chunkSize)) {
const inputConfig = {
...options.inputConfig,
input,
}
const bundle = await rollup(inputConfig)
const results = await Promise.all(options.outputConfig.map(bundle.write))
const outputs = results.flatMap((result) => result.output)
logger.success('dts', `⚡️ Chunk build success in ${getDuration()}`)
reportSize(
logger,
'dts',
outputs.reduce((res, info) => {
const name = path.relative(
process.cwd(),
path.join(options.outputConfig[0].dir || '.', info.fileName)
)
return {
...res,
[name]:
info.type === 'chunk' ? info.code.length : info.source.length,
}
}, {})
)
}
} catch (error) {
handleError(error)
logger.error('dts', 'Build error')
}
} What do y'all think? |
Using |
I'm having the same issue with the following defineConfig({
entry: ['src/index.ts'],
target: 'es2022',
format: ['cjs', 'esm'],
clean: true,
sourcemap: true,
dts: false,
}); and the following TypeScript config: {
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Default",
"compilerOptions": {
"outDir": "dist",
"lib": ["ES2022", "dom"],
"module": "ESNext",
"target": "ES2022",
"composite": false,
"emitDeclarationOnly": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"inlineSources": false,
"isolatedModules": true,
"moduleResolution": "node",
"noUnusedLocals": false,
"noUnusedParameters": false,
"preserveWatchOutput": true,
"skipLibCheck": true,
"strict": true,
"resolveJsonModule": true
},
"exclude": ["node_modules", "dist"]
} I noticed that if I set I guess it has something to do with the fact that I also wonder how Turborepo contributes to memory utilization. Is it OK to spawn so many
|
I have been using This approach was better than // tsup.config.ts
import { copyFile } from 'node:fs/promises'
import { exec } from 'node:child_process'
import { promisify } from 'node:util'
import glob from 'tiny-glob'
import { defineConfig } from 'tsup'
const pexec = promisify(exec)
export default defineConfig({
cjsInterop: true,
clean: true,
entry: ['src/**/*.ts', '!src/**/*.test.ts'],
format: ['cjs', 'esm'],
shims: true,
sourcemap: false,
splitting: true,
target: 'node20',
//
async onSuccess () {
try {
await pexec('tsc --emitDeclarationOnly --declaration')
const files = await glob('dist/**/*.d.ts')
await Promise.all(files.map(file => copyFile(file, file.replace('.d.ts', '.d.mts')))) // or to `.d.cjs` for `"type": "module"` projects
} catch (err) {
console.error()
console.error('Typescript compilation error:')
console.error()
console.error(err.stdout)
throw err
}
}
}) Don't forget to add |
I doubt that |
Can someone please confirm if this issue still exists when using Node.js v21 or above? This may have been fixed upstream in Node.js as per nodejs/node#25382 in nodejs/node@ce4102e (part of Node from v21.0.0 onwards), which changes the way that heap memory is allocated to forked child threads. |
Hi, we have observed that the latest v21 is slightly better as it was able to compute more folders but it eventually encounter the same issue.
|
Still the case with Node 22.7.0
|
tsup build is failing on me when dts is enabled
cli output
Upvote & Fund
The text was updated successfully, but these errors were encountered: