brandonkal / linaria

Zero-runtime CSS in JS library
https://linaria.now.sh
MIT License
5 stars 0 forks source link

Linaria Uses up All Available Memory #3

Open jarodpeachey opened 4 years ago

jarodpeachey commented 4 years ago

Do you want to request a feature or report a bug? Report a bug

What is the current behavior? Linaria is set up correctly, but when I run webpack-dev-server, I get an error that says FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory. This error comes from my local machine, but it's because Linaria uses up a ton of memory.

The repo has over 144 files which use Linaria.

If there's any way to disable using the memory, that would be awesome. It seems like all the files are generated in linaria-cache, but webpack won't move on because all the memory is taken up.

If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can yarn install and yarn test.

Clone the repo, and run npm install, then run npm start https://github.com/jarodpeachey/WebApp/tree/LinariaTest

What is the expected behavior? I expect Linaria to not use up all the memory. Is there a way to disable this?

Please provide your exact Babel configuration and mention your Linaria, Node, Yarn/npm version and operating system.

brandonkal commented 4 years ago

Thanks for the issue. I will be sure to take a look at this when I have the cycles available as avoiding OOMs is important. In the meantime, here are some questions to help debug:

  1. What memory is available and used on your system? This fork does keep more in memory to speed up rebuilds, but source files are rather small so it shouldn't present an issue in itself.
  2. Do you see this with vanilla linaria? This fork has removed linaria's shaker (as it was buggy and unpredictable). This means that it will evaluate and execute more of your codebase. Eventually I hope to be able to add it back in but it is a tricky problem. PR welcome here.
  3. Do you have circular imports? This can cause problems.
  4. Does your project have any modules that do not work in node?
jarodpeachey commented 4 years ago

I'm using an HP Omen laptop with a CORE i7 processor. It's got 16GB of RAM installed. I'm using Windows 10 as my OS.

Yes, I see the bug with the original Linaria as well. I've also tried different configurations of the linaria.config.js file, but those don't work either.

Here are some of the main files in my repo. They're a bit large, but I wanted to include everything in case there are conflicts between Linaria and other plugins.

webpack.config.js

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const { InjectManifest } = require('workbox-webpack-plugin');

// const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');   // Don't delete this!

module.exports = {
  mode: 'development',
  devtool: 'source-map',
  entry: ['./src/js/index.js', './src/sass/loading-screen.scss', './src/sass/main.scss'],
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].bundle.js',
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'styles.css',
    }),
    new HtmlWebpackPlugin({
      inject: false,
      template: './src/index.html',
      filename: 'index.html',
    }),
    new CopyPlugin([
      { from: 'src/javascript/', to: 'javascript/' },
      { from: 'src/img/global/icons/', to: 'img/global/icons/' },
      { from: 'src/img/global/intro-story/', to: 'img/global/intro-story/' },
      { from: 'src/img/global/logos/', to: 'img/global/logos/' },
      { from: 'src/img/global/photos/', to: 'img/global/photos/' },
      { from: 'src/img/global/svg-icons/', to: 'img/global/svg-icons/' },
      { from: 'src/img/how-it-works/', to: 'img/how-it-works/' },
      { from: 'src/img/tools/', to: 'img/tools/' },
      { from: 'src/img/welcome/', to: 'img/welcome/' },
      { from: 'src/img/welcome/benefits/', to: 'img/welcome/benefits/' },
      { from: 'src/img/welcome/partners/', to: 'img/welcome/partners/' },
      { from: 'src/img/endorsement-extension/', to: 'img/endorsement-extension/' },
      { from: 'src/vip.html', to: '.' },
      { from: 'src/css/', to: 'css/' },
    ]),
    new InjectManifest({
      swSrc: './src/serviceWorker.js',
      swDest: 'sw.js',
    }),
    // new BundleAnalyzerPlugin(),  // Enable this to start an (amazing) bundle size analyzer tool
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: [
          { loader: 'babel-loader' },
          {
            loader: '@brandonkal/linaria/loader',
            options: {
              cacheDirectory: './src/css/linaria',
              sourceMap: false,
              writeToDisk: false,
            },
          },
        ],
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'postcss-loader',
          },
        ],
      },
      {
        test: /\.scss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'postcss-loader',
          },
          {
            loader: 'sass-loader',
          },
        ],
      },
      {
        test: /\.(png|jp(e*)g|svg|eot|woff|ttf)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              publicPath: '/',
              name: 'img/[name].[ext]',
            },
          },
        ],
      },
    ],
  },
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
    extensions: ['.js', '.jsx'],
  },
};

package.json

{
  "name": "wevoteusa",
  "version": "1.0.0",
  "description": "We Vote front end application",
  "private": true,
  "main": "server.js",
  "license": "MIT",
  "react-svg-icons": {
    "assetPath": "src/img/global/svg-icons"
  },
  "scripts": {
    "lint": "eslint --format stylish --ext .jsx --ext .js src/js",
    "lint-css": "gulp lint-css",
    "test": "npm run lint && npm run lint-css",
    "ballotTest-Android": "./node_modules/.bin/wdio ./tests/browserstack/ballotAndroid.wdio.config.js",
    "ballotTest-Browser": "./node_modules/.bin/wdio ./tests/browserstack/ballotBrowser.wdio.config.js",
    "ballotTest-iOS": "./node_modules/.bin/wdio ./tests/browserstack/ballotIos.wdio.config.js",
    "marketingTest-Browser": "./node_modules/.bin/wdio ./tests/browserstack/marketingBrowser.wdio.config.js",
    "exampleTest": "./node_modules/.bin/wdio ./tests/browserstack/example.wdio.config.js",
    "start": "webpack-dev-server --mode=development --hot",
    "start-https": "webpack-dev-server --https --cert ./src/cert/server.crt --key ./src/cert/server.key",
    "start-profile": "node --inspect-brk ./node_modules/.bin/gulp",
    "build": "webpack -p",
    "prod": "NODE_ENV=production webpack -p",
    "build-dev": "NODE_ENV=development gulp build",
    "deps": "npm run deps:missing && npm run deps:extra",
    "deps:missing": "dependency-check package.json",
    "deps:extra": "dependency-check package.json --extra --no-dev --ignore",
    "build:doc": "doctoc --github --title \"## Contents\" ./",
    "autoTest": " mocha --compilers js:@babel/register --require tests/component/index.js \"./tests/component/tests.js\" && npm run lint",
    "snyk-protect": "snyk protect",
    "prepare": "npm run snyk-protect"
  },
  "dependencies": {
    "@material-ui/core": "^4.8.0",
    "@material-ui/icons": "^4.5.1",
    "autoprefixer": "^9.7.3",
    "bootstrap": "^4.4.1",
    "classnames": "^2.2.6",
    "es6-promise": "^4.2.8",
    "flux": "^3.1.3",
    "font-awesome": "^4.7.0",
    "history": "^3.2.1",
    "iframe-resizer": "^3.6.6",
    "jquery": "^3.4.1",
    "keymirror": "^0.1.1",
    "lodash": "^4.17.14",
    "lodash.assign": "^4.2.0",
    "moment": "^2.24.0",
    "moment-timezone": "^0.5.27",
    "object-assign": "^4.0.1",
    "postcss-loader": "^3.0.0",
    "prop-types": "^15.7.2",
    "react": "^16.12.0",
    "react-bootstrap": "^1.0.0-beta.16",
    "react-copy-to-clipboard": "^5.0.2",
    "react-dom": "^16.12.0",
    "react-helmet": "^5.2.1",
    "react-iframe-resizer-super": "^0.2.2",
    "react-mixin": "^3.1.1",
    "react-phone-number-input": "^2.5.1",
    "react-player": "^1.14.2",
    "react-pure-render": "^1.0.2",
    "react-router": "^3.2.5",
    "react-router-scroll": "^0.4.4",
    "react-slick": "^0.23.2",
    "react-stripe-elements": "^4.0.2",
    "react-svg": "^7.2.14",
    "react-text-truncate": "^0.13.1",
    "react-textarea-autosize": "^7.1.2",
    "react-toastify": "^3.4.3",
    "react-toggle": "^4.1.1",
    "react-transition-group": "^2.9.0",
    "snyk": "^1.262.2",
    "styled-components": "^4.4.1",
    "superagent": "^3.8.3"
  },
  "devDependencies": {
    "@babel/core": "^7.7.5",
    "@babel/plugin-proposal-class-properties": "^7.7.4",
    "@babel/plugin-proposal-decorators": "^7.7.4",
    "@babel/plugin-proposal-do-expressions": "^7.7.4",
    "@babel/plugin-proposal-export-default-from": "^7.7.4",
    "@babel/plugin-proposal-export-namespace-from": "^7.7.4",
    "@babel/plugin-proposal-function-bind": "^7.7.4",
    "@babel/plugin-proposal-function-sent": "^7.7.4",
    "@babel/plugin-proposal-json-strings": "^7.7.4",
    "@babel/plugin-proposal-logical-assignment-operators": "^7.7.4",
    "@babel/plugin-proposal-nullish-coalescing-operator": "^7.7.4",
    "@babel/plugin-proposal-numeric-separator": "^7.7.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.7.4",
    "@babel/plugin-proposal-optional-chaining": "^7.7.5",
    "@babel/plugin-proposal-pipeline-operator": "^7.7.4",
    "@babel/plugin-proposal-throw-expressions": "^7.7.4",
    "@babel/plugin-syntax-dynamic-import": "^7.7.4",
    "@babel/plugin-syntax-import-meta": "^7.7.4",
    "@babel/plugin-transform-object-assign": "^7.7.4",
    "@babel/plugin-transform-runtime": "^7.7.6",
    "@babel/preset-env": "^7.7.6",
    "@babel/preset-react": "^7.7.4",
    "@babel/register": "^7.7.4",
    "@babel/runtime": "^7.7.6",
    "@babel/types": "^7.7.4",
    "@brandonkal/linaria": "^2.0.6",
    "@wdio/cli": "^5.17.0",
    "@wdio/local-runner": "^5.17.0",
    "@wdio/mocha-framework": "^5.16.15",
    "babel-eslint": "^10.0.3",
    "babel-loader": "^8.0.5",
    "babel-plugin-dynamic-import-node-babel-7": "^2.0.7",
    "babel-plugin-styled-components": "^1.10.6",
    "babelify": "^10.0.0",
    "blue-tape": "^1.0.0",
    "browser-sync": "^2.26.7",
    "browserify": "^13.3.0",
    "chai": "^4.2.0",
    "chai-enzyme": "^1.0.0-beta.1",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "^5.1.1",
    "css-hot-loader": "^1.4.4",
    "css-loader": "^2.1.1",
    "del": "^2.2.0",
    "dependency-check": "^2.10.1",
    "doctoc": "^1.4.0",
    "enzyme": "^3.10.0",
    "enzyme-adapter-react-16": "^1.15.1",
    "eslint": "^5.16.0",
    "eslint-config-airbnb": "^17.1.1",
    "eslint-plugin-import": "^2.19.1",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-react": "^7.17.0",
    "eslint-plugin-wdio": "^5.13.2",
    "express": "^4.17.1",
    "extract-loader": "^2.0.1",
    "fastclick": "^1.0.6",
    "file-loader": "^3.0.1",
    "gulp": "^4.0.2",
    "gulp-autoprefixer": "^6.1.0",
    "gulp-class-prefix": "^1.0.1",
    "gulp-cli": "^2.2.0",
    "gulp-livereload": "^4.0.2",
    "gulp-sass": "^4.0.2",
    "gulp-sourcemaps": "^2.6.5",
    "gulp-stylelint": "^8.0.0",
    "gulp-uglify": "^2.1.2",
    "html-webpack-plugin": "^3.2.0",
    "jsdom": "^9.12.0",
    "mini-css-extract-plugin": "^0.9.0",
    "mocha": "^5.2.0",
    "node-libs-browser": "^2.2.1",
    "node-notifier": "^5.4.3",
    "node-sass": "^4.13.0",
    "pre-commit": "^1.2.2",
    "react-hot-loader": "^1.3.1",
    "sass-loader": "^7.3.1",
    "style-loader": "^0.23.1",
    "stylelint": "^9.10.1",
    "stylelint-config-standard": "^18.3.0",
    "stylelint-declaration-use-variable": "^1.7.2",
    "tape": "^4.12.0",
    "uglifyify": "^5.0.2",
    "vinyl-buffer": "^1.0.1",
    "vinyl-source-stream": "^2.0.0",
    "watchify": "^3.11.1",
    "webdriverio": "^5.17.0",
    "webpack": "^4.41.4",
    "webpack-bundle-analyzer": "^3.6.0",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.10.0",
    "webpack-serve": "^3.2.0",
    "workbox-webpack-plugin": "^4.3.1",
    "yargs": "^6.6.0"
  },
  "repository": "https://github.com/wevote/webapp.git",
  "pre-commit": [
    "test",
    "lint"
  ],
  "snyk": true
}

.babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-react", "@brandonkal/linaria/babel"],
  "plugins": [
    "@babel/plugin-syntax-dynamic-import",
    "dynamic-import-node-babel-7",
    "@babel/plugin-syntax-import-meta",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-json-strings",
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ],
    "@babel/plugin-proposal-function-sent",
    "@babel/plugin-proposal-export-namespace-from",
    "@babel/plugin-proposal-numeric-separator",
    "@babel/plugin-proposal-throw-expressions",
    "@babel/plugin-proposal-export-default-from",
    "@babel/plugin-proposal-logical-assignment-operators",
    "@babel/plugin-proposal-optional-chaining",
    [
      "@babel/plugin-proposal-pipeline-operator",
      {
        "proposal": "minimal"
      }
    ],
    "@babel/plugin-proposal-nullish-coalescing-operator",
    "@babel/plugin-proposal-do-expressions",
    "@babel/plugin-proposal-function-bind",
    "@babel/plugin-transform-runtime"
  ]
}

linaria.config.js

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

module.exports = {
  displayName: isDev,
  writeToDisk: false,
  cacheDirectory: './src/css/@brandonkal/linaria',
  evaluate: false,
  optimize: false,
};