rollup-plugin-inject-process-env icon indicating copy to clipboard operation
rollup-plugin-inject-process-env copied to clipboard

Memory leak ending up in aborted node process.

Open meh opened this issue 5 years ago • 4 comments

I don't know if it's this plugin (honestly, reading the source code, I don't get how it could be) but when I added this to my rollup configuration I started being unable to build my Sapper project due to the node process using too much memory and dying, removing the plugin makes it not die a horrible death.

I'd really like to use this plugin tho, any advice other than crying myself to sleep due to all the life decisions that led me to this point in life?

Thanks!

meh avatar Oct 23 '20 22:10 meh

Can you supply a minimal configuration that I could examine ?

ppoulard avatar Oct 30 '20 14:10 ppoulard

I don't have a minimal configuration, but this is my rollup config without inject-process-env:

import resolve from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import commonjs from '@rollup/plugin-commonjs';
import svelte from 'rollup-plugin-svelte';
import { terser } from 'rollup-plugin-terser';
import sveltePreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript';
import json from '@rollup/plugin-json';
import config from 'sapper/config/rollup.js';
import dotenv from 'rollup-plugin-dotenv';
import visualizer from 'rollup-plugin-visualizer';
import alias from '@rollup/plugin-alias';
import url from '@rollup/plugin-url';
import svgStore from 'rollup-plugin-svg-store';
import pkg from './package.json';
import path from 'path';

// Suppress some annoying Rollup warnings.
const onwarn = (warning, onwarn) =>
	(warning.code === 'MISSING_EXPORT' && /'preload'/.test(warning.message)) ||
	(warning.code === 'CIRCULAR_DEPENDENCY' && /[/\\]@sapper[/\\]/.test(warning.message)) ||
	(warning.code === 'THIS_IS_UNDEFINED') ||
	onwarn(warning);

const dev = process.env.NODE_ENV !== 'production';

const preprocess = sveltePreprocess({
	markupTagName: 'markup',

	postcss: {
		plugins: [
			require('postcss-import'),
			require('tailwindcss'),
			require('postcss-preset-env')({
				stage: 0,
			}),
			require('postcss-font-magician'),

			...(process.env.COLORBLIND ? [
				require('postcss-colorblind')({ method: process.env.COLORBLIND })
			] : []),

			...(!dev ? [] : [
				require('cssnano')({
					preset: 'default',
					plugins: [require('autoprefixer')],
				})
			])
		]
	},
});

const env = {
	'process.env.PKG_VERSION': JSON.stringify(pkg.version),
	'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
	'process.env.RELEASE': !dev,
};

const aliases = {
	resolve: ['.js', '.mjs', '.html', '.svelte', '.ts'],
	entries:[{
		find: '~',
		replacement: path.join(__dirname, './src')
	}]
};

export default {
	client: {
		input: config.client.input().replace(/.js$/, '.ts'),
		output: config.client.output(),
		plugins: [
			dotenv(),
			replace({
				'process.browser': true,
				'process.env.BROWSER': true,
				...env
			}),
			svelte({
				dev, preprocess,
				hydratable: true,
				emitCss: true
			}),
			url({
				sourceDir: path.resolve(__dirname, 'src/node_modules/images'),
				publicPath: '/client/'
			}),
			resolve({
				browser: true,
				dedupe: ['svelte']
			}),
			alias(aliases),
			commonjs(),
			typescript({ sourceMap: dev }),
			json(),
			svgStore({
				prefix: 'icon-',
			}),
			!dev && terser({
				module: true
			}),
			!dev && visualizer({
				filename: `rollup.client.html`,
				gzipSize: true,
				brotliSize: true,
			})
		],

		preserveEntrySignatures: false,
		onwarn,
	},

	server: {
		input: { server: config.server.input().server.replace(/.js$/, ".ts") },
		output: config.server.output(),
		plugins: [
			dotenv(),
			replace({
				'process.browser': false,
				'process.env.BROWSER': false,
				...env
			}),
			svelte({
				generate: 'ssr',
				hydratable: true,
				dev, preprocess,
			}),
			url({
				sourceDir: path.resolve(__dirname, 'src/node_modules/images'),
				publicPath: '/client/',
				emitFiles: false,
			}),
			resolve({
				dedupe: ['svelte']
			}),
			alias(aliases),
			commonjs(),
			typescript({ sourceMap: dev }),
			json(),
			svgStore({
				prefix: 'icon-',
			}),
		],
		external: Object.keys(pkg.dependencies).concat(require('module').builtinModules),
		preserveEntrySignatures: 'strict',
		onwarn,
	},

	serviceworker: {
		input: config.serviceworker.input().replace(/.js$/, '.ts'),
		output: config.serviceworker.output(),
		plugins: [
			dotenv(),
			replace({
				'process.browser': true,
				'process.env.BROWSER': true,
				...env
			}),
			resolve(),
			alias(aliases),
			commonjs(),
			typescript({ sourceMap: dev }),
			json(),
			!dev && terser(),
			!dev && visualizer({
				filename: `rollup.worker.html`,
				gzipSize: true,
				brotliSize: true,
			})
		],

		preserveEntrySignatures: false,
		onwarn,
	},
};

When I add it to this, it makes the node process explode.

meh avatar Oct 31 '20 10:10 meh

So you don't have any stacktrace of the "explosion" ?

Can you try the plugin with the include option by including just a single file and tell me what is the result ?

ppoulard avatar Nov 02 '20 08:11 ppoulard

Hey, @ppoulard , I stumbled upon the same problem. And managed to sort out the issue. Although I'm a newbie at this, I'll try to provide as much details as I can. I'm a big fan of this tool, many thanks for your work.

This memory leak seems to happen if the include is too vast, for example, covering node_modules and what not. So I concluded it's probably a good idea to use the include and target it at the development files. In my case that was src folder. However, I still had the problem even after doing that. So I started digging a little bit. Enabled the "verbose" option. It pointed exactly at which file the process failed. Now inside that file, I removed chunks of codes in turn to figure out what's causing the error.

Narrowed it down the a postcss / tailwind import.

<style global lang="postcss">
	@import "./global.pcss";
</style>

This particular @import is the reason why it was breaking the process.

When I simply commented out this line, it worked perfectly. Alternatively, I just excluded this entire particular file using the exclude option, so I got to keep my @import code, and also haven't used the process.env within this file anyways, so it was safe to exclude this particular file.

Hope my explanations give some insights towards whoever facing the same issue, or towards a potential fix in future.

www-chique avatar Feb 19 '21 16:02 www-chique