codevise/pageflow

View on GitHub
rollup.config.js

Summary

Maintainability
C
1 day
Test Coverage
import alias from '@rollup/plugin-alias';
import jst from 'rollup-plugin-jst';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import replace from '@rollup/plugin-replace';
import babel from 'rollup-plugin-babel';
import postcss from 'rollup-plugin-postcss';
import reactSvg from "rollup-plugin-react-svg";
import image from '@rollup/plugin-image';
import path from 'path'

const pageflowPackageRoot = 'package';
const pageflowPagedEngineRoot = 'entry_types/paged';
const pageflowPagedPackageRoot = pageflowPagedEngineRoot + '/packages/pageflow-paged';
const pageflowPagedReactPackageRoot = pageflowPagedEngineRoot + '/packages/pageflow-paged-react';
const pageflowScrolledPackageRoot = 'entry_types/scrolled/package';

const frontendGlobals = {
  'backbone': 'Backbone',
  'jquery': 'jQuery',
  'jquery-ui': 'jQuery',
  'underscore': '_',
  'i18n-js': 'I18n',
  'iscroll': 'IScroll',
  'video.js': 'videojs'
};

const editorGlobals = {
  ...frontendGlobals,
  'backbone.babysitter': 'Backbone.ChildViewContainer',
  'cocktail': 'Cocktail',
  'jquery.minicolors': 'jQuery',
  'backbone.marionette': 'Backbone.Marionette',
  'wysihtml5': 'wysihtml5'
};

function external(id) {
  // Make all import external except
  // - relative path
  // - absolute paths (generated by @babel/plugin-transform-runtime
  //   for helper modules and the alias plugin below)
  // - aliases like $state
  return !['.', '/', '$'].includes(id[0]);
}

const plugins = ({extractCss, moduleDirectories} = {}) => [
  postcss({
    modules: true,
    extract: extractCss,
    minimize: extractCss
  }),
  babel({
    exclude: 'node_modules/**',
    extensions: ['js', 'jsx', 'svg'],

    // By default rollup-plugin-babel deduplicates runtime helpers
    // inserted by Babel. babel-preset-react-app uses
    // @babel/plugin-transform-runtime which already takes care of
    // this.
    runtimeHelpers: true
  }),
  jst(),
  resolve({
    moduleDirectories: moduleDirectories || ['node_modules'],
    extensions: ['.js', '.jsx']
  }),
  commonjs({
    exclude: ['**/node_modules/symbol-observable/es/*.js'],
    namedExports: {
      'node_modules/esrever/esrever.js': ['reverse'],
      'node_modules/react-is/index.js': ['isValidElementType'],
      'entry_types/paged/packages/pageflow-paged-react/node_modules/react-is/index.js': ['isValidElementType'],
      'entry_types/paged/packages/pageflow-paged-react/node_modules/react-draggable/dist/react-draggable.js': ['DraggableCore']
    }
  }),
  reactSvg({
    svgo: {multipass: true}
  })
];

function stateAlias(path) {
  return alias({
    entries: {
      '$state': __dirname + '/' + path,
    }
  });
}

const ignoreJSXWarning = {
  onwarn: function(warning, warn) {
    // Ignore noisy warning
    // https://github.com/babel/babel/issues/9149
    if (warning.code === 'THIS_IS_UNDEFINED') { return; }
    warn(warning);
  }
};

// pageflow

const pageflow = [
  {
    input: pageflowPackageRoot + '/src/ui/index.js',
    output: {
      file: pageflowPackageRoot + '/ui.js',
      format: 'esm'
    },
    external,
    plugins: plugins()
  },
  {
    input: pageflowPackageRoot + '/src/editor/index.js',
    output: {
      file: pageflowPackageRoot + '/editor.js',
      format: 'esm'
    },
    external,
    plugins: [
      stateAlias(pageflowPackageRoot + '/src/editor/state.js'),
      ...plugins()
    ]
  },
  {
    input: pageflowPackageRoot + '/src/testHelpers/index.js',
    output: {
      file: pageflowPackageRoot + '/testHelpers.js',
      format: 'esm'
    },
    external,
    plugins: [
      stateAlias(pageflowPackageRoot + '/src/editor/state.js'),
      ...plugins()
    ]
  },
  {
    input: pageflowPackageRoot + '/src/frontend/index.js',
    output: {
      file: pageflowPackageRoot + '/frontend.js',
      format: 'esm'
    },
    external,
    plugins: plugins()
  },
  {
    input: pageflowPackageRoot + '/src/ui/index.js',
    output: {
      file: 'app/assets/javascripts/pageflow/dist/ui.js',
      format: 'iife',
      name: 'pageflow._uiGlobalInterop',
      globals: editorGlobals
    },
    external: Object.keys(editorGlobals),
    plugins: plugins()
  }
];

// pageflow-paged

const pageflowPagedEditorGlobals = {
  ...editorGlobals,

  // Allow importing from pageflow/frontend and
  // pageflow-paged/frontend without including all of
  // the frontend code in the editor output.
  'pageflow/frontend': 'pageflow',
  'pageflow-paged/frontend': 'pageflow'
}

const pageflowPaged = [
  {
    input: pageflowPagedPackageRoot + '/src/editor/index.js',
    output: {
      file: pageflowPagedEngineRoot + '/app/assets/javascripts/pageflow_paged/dist/editor.js',
      format: 'iife',
      name: 'pageflow_paged',
      globals: pageflowPagedEditorGlobals
    },
    external: Object.keys(pageflowPagedEditorGlobals),
    plugins: [
      stateAlias(pageflowPagedPackageRoot + '/src/editor/state.js'),
      ...plugins()
    ]
  },
  {
    input: pageflowPagedPackageRoot + '/src/frontend/index.js',
    output: {
      file: pageflowPagedEngineRoot + '/app/assets/javascripts/pageflow_paged/dist/frontend.js',
      format: 'iife',
      name: 'pageflow_paged.frontend',
      globals: frontendGlobals
    },
    external: Object.keys(frontendGlobals),
    plugins: plugins()
  }
];

const pageflowPagedReact = ['client', 'server'].map(target => {
  var targetGlobals = {
    client: {
      'backbone': 'Backbone',
      'react-dom': 'ReactDOM'
    },
    server: {
      'backbone': '{}',
      'react-dom': '{}',
      'react-wavesurfer': '{}'
    }
  };

  const globals = {
    'pageflow': 'pageflow',
    'react': 'React',
    ...targetGlobals[target]
  };

  return {
    input: `${pageflowPagedReactPackageRoot}/src/index.js`,
    output: {
      file: `${pageflowPagedEngineRoot}/app/assets/javascripts/pageflow_paged/dist/react-${target}.js`,
      format: 'iife',
      name: 'pageflow.react',
      globals
    },
    external: Object.keys(globals),
    plugins: [
      alias({
        entries: {
          'redux-saga/effects': __dirname + '/entry_types/paged/packages/pageflow-paged-react/node_modules/redux-saga/es/effects',
        }
      }),
      ...plugins({
        moduleDirectories: [
          'node_modules',
          path.resolve(__dirname, `${pageflowPagedReactPackageRoot}/src`)
        ]
      }),
      replace({
        preventAssignment: true,
        values: {
          'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
        }
      })
    ]
  };
});

// pageflow-scrolled

const pageflowScrolled = [
  {
    input: pageflowScrolledPackageRoot + '/src/editor/index.js',
    output: {
      file: pageflowScrolledPackageRoot + '/editor.js',
      format: 'esm',
    },
    external,
    plugins: [
      image({include: pageflowScrolledPackageRoot + '/src/editor/views/images/*.svg'}),
      ...plugins()
    ]
  },
  {
    input: pageflowScrolledPackageRoot + '/src/frontend/index.js',
    output: {
      dir: pageflowScrolledPackageRoot + '/frontend',
      format: 'esm',
    },
    external,
    plugins: plugins({extractCss: true}),
    ...ignoreJSXWarning
  },
  {
    input: pageflowScrolledPackageRoot + '/src/frontend/server.js',
    output: {
      file: pageflowScrolledPackageRoot + '/frontend-server.js',
      format: 'esm',
    },
    external,
    plugins: plugins(),
    ...ignoreJSXWarning
  },
  {
    input: pageflowScrolledPackageRoot + '/src/testHelpers/index.js',
    output: {
      file: pageflowScrolledPackageRoot + '/testHelpers.js',
      format: 'esm'
    },
    external,
    plugins: plugins()
  },

  {
    input: pageflowScrolledPackageRoot + '/src/contentElements/editor.js',
    output: {
      file: pageflowScrolledPackageRoot + '/contentElements-editor.js',
      format: 'esm',
    },
    external,
    plugins: [
      image({include: '**/pictogram.svg'}),
      ...plugins()
    ]
  },
  {
    input: pageflowScrolledPackageRoot + '/src/contentElements/frontend.js',
    output: {
      file: pageflowScrolledPackageRoot + '/contentElements-frontend.js',
      format: 'esm',
    },
    external,
    plugins: plugins({extractCss: true}),
    ...ignoreJSXWarning
  },

  ...(['defaultNavigation', 'consentBar', 'textInlineFileRights', 'iconInlineFileRights'].map(name => (
    {
      input: `${pageflowScrolledPackageRoot}/src/widgets/${name}/index.js`,
      output: {
        file: `${pageflowScrolledPackageRoot}/widgets/${name}.js`,
        format: 'esm',
      },
      external,
      plugins: plugins({extractCss: true}),
      ...ignoreJSXWarning
    }
  )))
];

export default [
  ...pageflow,
  ...pageflowScrolled,
  ...pageflowPaged,
  ...pageflowPagedReact
]