frctl / fractal

A tool to help you build and document website component libraries and design systems.
https://fractal.build
MIT License
2.11k stars 168 forks source link

mp4 video seems to crash the github actions build #1277

Open OZZlE opened 1 month ago

OZZlE commented 1 month ago

Steps to reproduce the issue

react-video.nunj

<div class="hero" style="background-image: url('{{backgroundImage}}')">
    <div data-react-component="HeroWithVideo" data-props='{"src":"../../components/raw/hero-with-video/video.mp4",
    "minWidth": "1000px"}'></div>
</div>

or video-config.yml

title: "video block"
status: wip
context:
  thumbnail: "/assets/video-block/image.png"
  forceThumbnailInMobile: false
  video: "/assets/video-block/video.mp4"

npm run build:fractal:

⚑ Exported 377 of 707 items
Could not find the language '.mp4', did you forget to load/include a language module?

<--- Last few GCs --->

[7120:000001BC59F66540]    67696 ms: Scavenge 2039.4 (2069.7) -> 2038.7 (2070.2) MB, 2.7 / 0.0 ms  (average mu = 0.303, current mu = 0.421) allocation failure; 
[7120:000001BC59F66540]    67701 ms: Scavenge 2039.9 (2070.2) -> 2039.3 (2071.0) MB, 2.7 / 0.0 ms  (average mu = 0.303, current mu = 0.421) allocation failure; 
[7120:000001BC59F66540]    67707 ms: Scavenge 2040.6 (2071.0) -> 2039.9 (2075.5) MB, 3.2 / 0.0 ms  (average mu = 0.303, current mu = 0.421) allocation failure; 

<--- JS stacktrace --->

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 00007FF7169C1B7F node_api_throw_syntax_error+203775
2: 00007FF716941556 v8::internal::MicrotaskQueue::GetMicrotasksScopeDepth+63558
3: 00007FF7169428C2 v8::internal::MicrotaskQueue::GetMicrotasksScopeDepth+68530
4: 00007FF7173E47F4 v8::Isolate::ReportExternalAllocationLimitReached+116
5: 00007FF7173CFB52 v8::Isolate::Exit+674
6: 00007FF717251BBC v8::internal::EmbedderStackStateScope::ExplicitScopeForTesting+124
7: 00007FF71725EE9D v8::internal::Heap::PublishPendingAllocations+1117
8: 00007FF71725BF27 v8::internal::Heap::PageFlagsAreConsistent+3367
9: 00007FF71724E657 v8::internal::Heap::CollectGarbage+2039
10: 00007FF717256A35 v8::internal::Heap::GlobalSizeOfObjects+341
11: 00007FF7172A60AF v8::internal::StackGuard::HandleInterrupts+863
12: 00007FF716F67DC6 v8::internal::DateCache::Weekday+6886
13: 00007FF717481E81 v8::internal::SetupIsolateDelegate::SetupHeap+558193
14: 00007FF71746661C v8::internal::SetupIsolateDelegate::SetupHeap+445452
15: 00007FF69807D7F0 
Error: Process completed with exit code 1.

Reproduces how often:

100%

Reduced test case

/*global __dirname*/
const path = require('path');

const fractal = module.exports = require('@frctl/fractal').create();

console.log(__dirname);
const pkg = require(path.join(__dirname, 'package.json'));

/**
* Metadata
*/
fractal.set('project.title', 'Eurocard Styleguide');

// Provide the package.json "version" to the templates
fractal.set('project.version', pkg.version);

/**
* Files location
*/
fractal.docs.set('path', path.join(__dirname, 'docs'));
fractal.components.set('path', path.join(__dirname, 'components'));

// fractal.web.set('static.path', path.join(__dirname, 'public'));
fractal.web.set('static.path', path.join(__dirname, 'dist'));

/**
* Build options
*/
// If you change the build destination, you should adapt webpack.common.js "output.path" too.
fractal.web.set('builder.dest', 'dist');

/**
* Templating
*/

// Use Nunjucks as the template engine
fractal.components.engine('@frctl/nunjucks');
fractal.docs.engine('@frctl/nunjucks');

// Look for templates with a ".nunj" extension
fractal.components.set('ext', '.nunj');

/**
* Server configuration
*/
fractal.web.set('server.port', 4000);
fractal.web.set('server.sync', true);

/**
* Fractal Status
*
*/

fractal.components.set('statuses', {
  doing: {
    label: 'Component is under work in progress',
    description: 'Component is under work in progress',
    color: 'red',
  },
  review: {
    label: 'Component is ready and under review.',
    description: 'Test',
    color: 'orange',
  },
  ready: {
    label: 'Ready to implement.',
    description: 'Ready to implement.',
    color: 'green',
  },
  done: {
    label: 'Component is done',
    description: 'Component is done',
    color: 'black',
  },
  wip: {
    label: 'Component is under work in progress',
    description: 'Component is under work in progress',
    color: 'red',
  },
});

/**
* Prevent Bluebird warnings like "a promise was created in a handler but was not returned from it"
* caused by Nunjucks from polluting the console
*/
const bluebird = require('bluebird');

bluebird.config({
  warnings: false,
});

const myCustomisedTheme = require('@frctl/mandelbrot')({
  skin: 'white',
  styles: ['default', '/fractal-sub-theme/index.css'], // link to the default stylesheet followed by a custom one
});

fractal.web.theme(myCustomisedTheme);

/*
* List all components in Fractal
*/
const hbs = require('@frctl/handlebars')({
  helpers: {
    componentList() {
      let ret = '<ul>';
      const options = Array.from(arguments).pop();
      for (const component of fractal.components.flatten()) {
        ret = `${ret}<li>${options.fn(component.toJSON())}</li>`;
      }
      return `${ret}</ul>`;
    }
  },
});

fractal.docs.engine(hbs);

Context

OZZlE commented 1 month ago

webpack.config:

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');

/*eslint-disable */
var dirname = __dirname;
/*eslint-enable */

const getBabelOptions = (targets, useBuiltIns = 'entry') => {
  let plugins = [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
  ];
  if (!targets.esmodules) {
    plugins.push(["@babel/plugin-proposal-class-properties", { loose: true }]);
    plugins.push(["@babel/plugin-proposal-private-methods", { loose: true }]);
  }

  return {
    "presets": [
      [
        "@babel/preset-env",
        {
          "targets": targets,
          /*
          "corejs": {
            version : "2",
            proposals : true,
          },
          modules: false,
          */
          //"useBuiltIns": useBuiltIns,
        }
      ],
      "@babel/preset-react"
    ],
    "plugins": plugins,
  };
};
const resolve = {
  modules: [
    path.resolve(dirname, 'components/atoms/'),
    path.resolve(dirname, 'components/molecules/'),
    path.resolve(dirname, 'components/organisms/'),
    path.resolve(dirname, 'static/scripts'),
    path.resolve(dirname, 'static/styles'),
    path.resolve(dirname, 'static'),
    path.resolve(dirname, 'node_modules/foundation-sites/scss'),
    'node_modules',
  ],
  extensions: ['.js', '.jsx'],
  // alias: {
  //   icons: path.resolve(dirname, 'static/icons'),
  // }
};

const output = {
  path: path.resolve(dirname, 'dist'),
  publicPath: '/',
};
const eslintRule = {
  enforce: 'pre',
  test: /\.js$/,
  exclude: /node_modules/,
  loader: 'eslint-loader',
  options: {
    configFile: '.eslintrc.js',
  },
};
const getScssRule = (env) => {
  return {
    test: /\.scss$/,
    use: [
      {
        loader:
          env === 'production'
            ? MiniCssExtractPlugin.loader
            : 'style-loader',
      },
      'css-loader',
      {
        loader: 'postcss-loader',
        options: {
          postcssOptions: {
            plugins: [
              /* eslint-disable global-require */
              require('postcss-focus')(),
              require('autoprefixer')({ grid: true }),
              require('cssnano')(),
              /* eslint-enable global-require */
            ],
          },
        },
      },
      {
        loader: 'sass-loader',
        options: {
          sassOptions: {
            includePaths: ['node_modules'],
          }
        },
      },
    ],
  }
};
const fileRule = {
  test: /\.(svg|png|jpe?g|gif|woff|woff2|eot|ttf|otf|mp4)$/,
  // exclude: [
  //   path.resolve('./static/icons/**/*'),
  //   path.resolve('./static/fonts/icons.svg'),
  // ],
  exclude: path.resolve('./static/icons'),
  use: [
    {
      loader: 'file-loader',
      options: {
        name: '[name].[ext]',
        outputPath: 'static/fonts/',
      },
    },
  ],
};
const svgSpriteRule = {
  test: /\.svg$/,
  include: path.resolve('./static/icons'),
  use: [
    {
      loader: 'svg-sprite-loader',
      options: {
        extract: true,
        spriteFilename: 'static/images/icons.svg',
        esModule: false,
      },
    },
    'svgo-loader',
  ],
};
const getPlugins = (apiEnvTarget, env = 'production') => {
  const plugins = [
    new StyleLintPlugin({
      configFile: './.stylelintrc',
    }),
    new MiniCssExtractPlugin({
      filename: './static/styles/[name].css',
    }),
    new SpriteLoaderPlugin(),
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      foundation: 'Foundation'
    }),
    // this is used to import environment specific modules like api request etc, ie api will be mocked in development
    new webpack.NormalModuleReplacementPlugin(/(.*)-ENVIRONMENT_TARGET(\.*)/, function (resource) {
      resource.request = resource.request.replace(/-ENVIRONMENT_TARGET/, `-${apiEnvTarget}`);
    })
  ];
  if (env === 'production') {
    plugins.push(new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')
    }));
  }

  return plugins;
}
const devServer = {
  historyApiFallback: true,
  compress: true,
  proxy: {
    '**': 'http://localhost:4000',
  },
  // port: 3000,
  client: {
    overlay: true,
  },
  devMiddleware: {
    stats: {
      colors: true,
    },
  },
};
const optimization = {
  splitChunks: {
    cacheGroups: {
      styles: {
        name: 'styles',
        test: /\.css$/,
        chunks: 'all',
        enforce: true,
      },
    },
  },
};
const legacyTargets = {
  "browsers": [
    ">0.25%",
    "IE 11"
  ]
};
const getApiTargetEnv = (origEnv) => {
  // Azure Styleguide used 'development' with hardcoded responses see api-development
  // No longer maintained though..
  return 'production'; // origEnv.epi ? 'development' : 'production';
}

const legacyUseBuiltIns = 'entry';
const legacyConfig = (origEnv, argv) => {
  var apiEnvTarget = getApiTargetEnv(origEnv);
  var env = origEnv.epi ? 'development' : 'production';

  return {
    mode: env,
    // devtool: 'source-map',
    resolve,
    entry: {
      react: [
        'babel-polyfill',
        path.resolve(dirname, 'static/scripts/polyfills.js'),

        // was main
        path.resolve(dirname, 'static/scripts/main.js'),
        // path.resolve(dirname, 'static/styles/main.scss'),

        path.resolve(dirname, 'static/scripts/react-bundle.js')
      ],
    },
    output: {
      path: output.path,
      publicPath: output.publicPath,
      filename: env === 'production' ? './static/scripts/[name].ver.[chunkhash].js' : './static/scripts/[name].js',
    },
    module: {
      rules: [
        eslintRule,
        {
          test: /\.(js|jsx)$/,
          exclude: /node_modules\/(?![foundation-sites])/,
          loader: 'babel-loader',
          options: getBabelOptions(legacyTargets, legacyUseBuiltIns)
        },
        getScssRule(env),
        fileRule,
        svgSpriteRule,
      ],
    },
    plugins: getPlugins(apiEnvTarget, env),
    devServer,
    optimization,
  };
}

const modernTargets = { "esmodules": true };
const modernUseBuiltIns = 'usage';

const moduleConfig = (origEnv, argv) => {
  var apiEnvTarget = getApiTargetEnv(origEnv);
  var env = origEnv.epi ? 'development' : 'production';

  return {
    mode: env,
    // devtool: 'source-map',
    resolve,
    entry: {
      main: [
        path.resolve(dirname, 'static/styles/main.scss')
      ],
      react: [

        // was main
        path.resolve(dirname, 'static/scripts/main.js'),
        // path.resolve(dirname, 'static/styles/main.scss'),

        path.resolve(dirname, 'static/scripts/react-bundle.js')
      ],
    },
    output: {
      path: output.path,
      publicPath: output.publicPath,
      filename: env === 'production' ? './static/scripts/[name].module.ver.[chunkhash].js' : './static/scripts/[name].module.js',
    },
    module: {
      rules: [
        eslintRule,
        {
          test: /\.(js|jsx)$/,
          exclude: /node_modules\/(?![foundation-sites])/,
          loader: 'babel-loader',
          options: getBabelOptions(modernTargets, modernUseBuiltIns)
        },
        getScssRule(env),
        fileRule,
        svgSpriteRule,
      ],
    },
    plugins: getPlugins(apiEnvTarget, env),
    devServer,
    optimization,
  };
}
module.exports = function config(env, argv = {}) {
  if (env.styleguide) {
    return moduleConfig({
      ...env,
      epi: true,
    }, argv);
  }

  return [
    legacyConfig(env, argv), moduleConfig(env, argv)
  ];
};
OZZlE commented 1 month ago

Github action:

name: test-styleguide-build

on:
  workflow_dispatch:
    inputs: {}
  pull_request:
    types:
      - opened
      - reopened
      - synchronize

jobs:
  build:
    env:
      runner_memoryrequest: 12000Mi
      runner_memorylimit: 12000Mi
    runs-on: windows-latest
    strategy:
      matrix:
        node-version: [20.14.0]
    steps:
      - uses: actions/checkout@v2

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
        working-directory: Mycard.FE
      - run: npm run build:fractal
        working-directory: Mycard.FE

package.json:

{
  "name": "censored-styleguide",
  "version": "0.0.1",
  "description": "censored styleguide based on Fractal using node 8.16.0",
  "fractal": {
    "main": "fractal.jss"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/censoredgroup/sk-opwenweb-censoredxx.git"
  },
  "private": true,
  "scripts": {
    "build-epi": "npm run webpack:local:epi",
    "build-epi-JS-only": "npm run lint:changed:js-win && webpack --env=epi && npm run copy:local:winscripts",
    "build-epi-CSS-only": "npm run lint:changed:scss-win && npm run webpack:prd:styles && npm run copy:winstyles",
    "run:fractal": "node ./server.js",
    "run:webpack": "webpack-dev-server --env=styleguide",
    "webpack:dev": "webpack --env=styleguide",
    "build:fractal": "fractal build",
    "webpack:prd": "npm run clean:script && webpack --env=production && npm run copy:win",
    "webpack:local:epi": "npm run lint-changed-win && webpack --env=epi && npm run webpack:prd:styles && npm run copy:local:win",
    "webpack:prod:epi": "webpack --env=production && npm run copy:win",
    "webpack:prd:styles": "webpack --env=production --config webpack.styles-only.config.js",
    "webpack:local:styles:build": "webpack --env=development --config webpack.styles-only.config.js",
    "start": "npm-run-all --parallel run:fractal run:webpack",
    "build": "npm-run-all --parallel webpack:prd build:fractal",
    "build:styles": "npm-run-all --parallel webpack:prd webpack:prd:styles",
    "copy": "node ./node_modules/cpx/bin/index.js -v './dist/static/**/*' ../censored.XX.BE/Static/",
    "copy:win": "node ./node_modules/cpx/bin/index.js -v ./dist/static/**/* ../censored.XX.BE/Static/ && npm run copy:versioned:main:script",
    "copy:local:win": "node ./node_modules/cpx/bin/index.js -v ./dist/static/**/* ../censored.XX.BE/Static/",
    "copy:winstyles": "node ./node_modules/cpx/bin/index.js -v ./dist/static/**/*.css ../censored.XX.BE/Static/",
    "copy:versioned:main:script": "node copy-main.js",
    "clean:script": "node clean.js",
    "copy:winscripts": "node ./node_modules/cpx/bin/index.js -v ./dist/static/scripts/* ../censored.XX.BE/Static/scripts/ && npm run copy:versioned:main:script",
    "copy:local:winscripts": "node ./node_modules/cpx/bin/index.js -v ./dist/static/scripts/* ../censored.XX.BE/Static/scripts/",
    "gen:bundle:stats": "webpack --env=development --config webpack.bundle-analyzer.config.js --profile --json=./dist/stats.json",
    "show:bundleanalyzer": "webpack-bundle-analyzer ./dist/stats.json",
    "test": "jest --passWithNoTests",
    "test:watch": "jest --watch",
    "lint:js": "node node_modules/eslint/bin/eslint.js components/**/*.js static/scripts/*.js static/scripts/api/**/*.jsx static/scripts/helpers/**/*.js",
    "lint:changed:js-win": "node cli-scripts/win-lint-changed-js.js",
    "lint:scss": "node node_modules/stylelint/bin/stylelint.js **/*.scss",
    "lint:changed:scss-win": "node cli-scripts/win-lint-changed-scss.js",
    "lint": "npm run lint:js && npm run lint:scss",
    "lint-changed-win": "npm run lint:changed:js-win && npm run lint:changed:scss-win"
  },
  "lint-staged": {
    "linters": {
      "*.scss": [
        "stylelint scss",
        "git add"
      ],
      "*.js": [
        "eslint --fix",
        "git add"
      ]
    },
    "ignore": [
      "**/dist/**/*.{js,json,css,md}"
    ]
  },
  "devDependencies": {
    "@babel/core": "^7.20.5",
    "@babel/plugin-proposal-class-properties": "^7.18.6",
    "@babel/plugin-transform-runtime": "^7.19.6",
    "@babel/preset-env": "^7.20.2",
    "@babel/preset-react": "^7.18.6",
    "@frctl/fractal": "^1.5.14",
    "@frctl/nunjucks": "^1.0.3",
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "autoprefixer": "^10.4.13",
    "babel-eslint": "^10.1.0",
    "babel-loader": "^9.1.0",
    "cpx": "^1.5.0",
    "css-loader": "^6.7.2",
    "css-mediaquery": "^0.1.2",
    "cssnano": "^5.1.14",
    "eslint": "^7.32.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-react": "^7.31.11",
    "file-loader": "^6.2.0",
    "husky": "^8.0.2",
    "jest": "^29.3.1",
    "jest-environment-jsdom": "^29.3.1",
    "lint-staged": "^13.1.0",
    "mini-css-extract-plugin": "^2.7.2",
    "npm-run-all": "^4.1.5",
    "postcss": "^8.4.31",
    "postcss-cli": "^10.1.0",
    "postcss-flexbugs-fixes": "^5.0.2",
    "postcss-focus": "^5.0.1",
    "postcss-loader": "^7.0.2",
    "prettier": "^2.8.1",
    "script-loader": "^0.7.2",
    "style-loader": "^3.3.1",
    "stylelint": "^14.16.0",
    "stylelint-config-recommended-scss": "^8.0.0",
    "stylelint-scss": "^4.3.0",
    "stylelint-webpack-plugin": "^3.3.0",
    "svg-sprite-loader": "^6.0.11",
    "svgo": "^3.0.2",
    "svgo-loader": "^3.0.3",
    "webpack": "^5.76.0",
    "webpack-bundle-analyzer": "^4.7.0",
    "webpack-cli": "^5.0.1",
    "webpack-dev-server": "^4.11.1",
    "webpack-merge": "^5.8.0"
  },
  "engines": {
    "node": ">=16"
  },
  "dependencies": {
    "@babel/plugin-proposal-decorators": "^7.20.5",
    "animate.css": "^4.1.1",
    "babel-polyfill": "^6.26.0",
    "body-scroll-lock": "^4.0.0-beta.0",
    "focus-trap": "^7.2.0",
    "foundation-sites": "^6.7.5",
    "iframe-resizer": "^4.3.2",
    "jquery": "^3.6.2",
    "jquery-modal": "^0.9.2",
    "jquery.scrollto": "^2.1.3",
    "js-cookie": "^3.0.1",
    "mobx": "^6.7.0",
    "mobx-react": "^7.6.0",
    "picturefill": "^3.0.3",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-modal": "^3.16.1",
    "react-responsive": "^9.0.2",
    "sanitize.css": "^13.0.0",
    "sass": "^1.69.5",
    "sass-loader": "^13.3.2",
    "scrollprogress": "^3.0.2",
    "slick-carousel": "^1.8.1",
    "stickyfilljs": "^2.1.0",
    "svgxuse": "^1.2.6",
    "universal-cookie": "^4.0.4",
    "whatwg-fetch": "^3.6.2"
  }
}

I tried updating to latest Fractal modules but this build fails in the same way then also