Skip to content

Instantly share code, notes, and snippets.

@xgqfrms
Forked from evdama/rollup.config.js
Last active July 6, 2022 08:42
Show Gist options
  • Save xgqfrms/5fbe3604ffcf3a6e71d760d70940155b to your computer and use it in GitHub Desktop.
Save xgqfrms/5fbe3604ffcf3a6e71d760d70940155b to your computer and use it in GitHub Desktop.
rollup.config.js All In One
// @ts-nocheck //TODO: enable remove once there are typings in place
// TODO: uncomment all three eslint() occurrences once eslint warnings and errors are fixed
// for info on emitCSS etc. https://github.com/rollup/rollup-plugin-svelte#extracting-css and https://svelte.dev/docs#svelte_preprocess

// import { eslint } from 'rollup-plugin-eslint'
import { terser } from 'rollup-plugin-terser'
import babel from 'rollup-plugin-babel'
import commonjs from 'rollup-plugin-commonjs'
import config from 'sapper/config/rollup.js'
import environmentVariables from './config/env'
import getPreprocessor from 'svelte-preprocess'
import getTime from 'date-fns/getTime'
import json from '@rollup/plugin-json'
import pkg from './package.json'
import postcss from 'rollup-plugin-postcss'
import replace from '@rollup/plugin-replace'
import resolve from 'rollup-plugin-node-resolve'
import svelte from 'rollup-plugin-svelte'
import visualizer from 'rollup-plugin-visualizer'


const mode = process.env.NODE_ENV
const dev = mode === 'development'
const legacy = !!process.env.SAPPER_LEGACY_BUILD

const onwarn = ( warning, onwarn ) => ( warning.code === 'CIRCULAR_DEPENDENCY' && /[/\\]@sapper[/\\]/.test( warning.message ) ) || onwarn( warning )

const dedupe = importee => importee === 'svelte' || importee.startsWith( 'svelte/' )

const appConfig = Object.keys(environmentVariables).reduce((acc, n) => {
  acc[`${n}`] = environmentVariables[n]
  return acc
}, {})


  const svelteExtractor = ( content ) => {
    const regExp = new RegExp(/[A-Za-z0-9-_:/]+/g)
    const matchedTokens = []
    let match = regExp.exec(content)

    while (match) {
      if (match[0].startsWith('class:')) {
        matchedTokens.push(match[0].substring(6))
      } else {
        matchedTokens.push(match[0])
      }
      match = regExp.exec(content)
    }
    return matchedTokens
  }


const postcssPlugins = ( purgecss = false ) =>
  [
    require('postcss-import')(),
    require('postcss-url')(),
    require('tailwindcss')({ config: 'tailwind.config.js' }),
    require('autoprefixer')({
      overrideBrowserslist: 'last 1 version',
    }),
    // Do not purge the CSS in dev mode to be able to play with classes in the browser dev-tools.
    purgecss &&
      require('@fullhuman/postcss-purgecss')({
        content: [
          'src/**/*.html',
          'src/**/*.svelte',
          'src/**/*.css',
          'static/**/*.css',
        ],
        extractors: [
          {
            extractor: svelteExtractor,

            // Specify the file extensions to include when scanning for class names.
            extensions: [ 'svelte', 'css', 'html' ],
          },
        ],
        fontFace: true,
        // Whitelist selectors to stop Purgecss from removing them from your CSS.
        whitelist: [ 'html', 'body' ],
        whitelistPatterns: [/svelte-/]
      }),
    purgecss &&
      require('cssnano')({
        preset: 'default',
      }),
  ].filter(Boolean)

const preprocess = getPreprocessor({
  transformers: {
    postcss: {
      plugins: postcssPlugins(), // Don't need purgecss because Svelte handles unused css for you.
    },
  },
})



export default {
  client: {
    input: config.client.input(),
    output: config.client.output(),
    plugins: [
      // eslint(),
      visualizer( { filename: 'visualizer_stats/client.json', title: 'Client Bundle', json: true } ),
      replace({
        'process.browser': true,
        'process.env.NODE_ENV': JSON.stringify( mode ),
        ROLLUP_DEV_OR_PROD_URL: ( dev ? '.': appConfig.EDM_URL ),
        ROLLUP_EDM_UPDATE_TIMESTAMP: getTime( new Date() ),
        ROLLUP_GOLIVE_DATE: appConfig.GOLIVE_DATE,
        ROLLUP_RECAPTCHA_SITE_KEY: appConfig.RECAPTCHA_SITE_KEY,
      }),
      svelte({
        dev,
        hydratable: true,
        emitCss: false,
        preprocess,
      }),
      resolve({
        browser: true,
        dedupe,
      }),
      commonjs(),
      legacy &&
        babel({
          extensions: ['.js', '.mjs', '.html', '.svelte'],
          runtimeHelpers: true,
          exclude: ['node_modules/@babel/**'],
          presets: [
            [
              '@babel/preset-env',
              {
                targets: '> 0.25%, not dead',
              },
            ],
          ],
          plugins: [
            '@babel/plugin-syntax-dynamic-import',
            [
              '@babel/plugin-transform-runtime',
              {
                useESModules: true,
              },
            ],
          ],
        }),
      !dev &&
        terser({
          module: true,
        }),
    ],
    onwarn,
  },

  server: {
    input: config.server.input(),
    output: config.server.output(),
    plugins: [
      // eslint(),
      visualizer( { filename: 'visualizer_stats/server.json', title: 'Server Bundle', json: true } ),
      replace({
        'process.browser': false,
        'process.env.NODE_ENV': JSON.stringify( mode ),
        ROLLUP_DEV_OR_PROD_URL: ( dev ? '.': appConfig.EDM_URL ),
        ROLLUP_EDM_UPDATE_TIMESTAMP: getTime( new Date() ),
        ROLLUP_EXPRESS_SESSION_COOKIE_SIGNING_SECRET: appConfig.EXPRESS_SESSION_COOKIE_SIGNING_SECRET,
        ROLLUP_IPREGISTRY_KEY: appConfig.IPREGISTRY_KEY,
        ROLLUP_IPREGISTRY_URL: appConfig.IPREGISTRY_URL,
        ROLLUP_RECAPTCHA_SCORE_IS_BOT: appConfig.RECAPTCHA_SCORE_IS_BOT,
        ROLLUP_RECAPTCHA_SCORE_IS_HUMAN: appConfig.RECAPTCHA_SCORE_IS_HUMAN,
        ROLLUP_RECAPTCHA_SECRET_KEY: appConfig.RECAPTCHA_SECRET_KEY,
        ROLLUP_RECAPTCHA_VERIFY_URL: appConfig.RECAPTCHA_VERIFY_URL,
      }),
      svelte({
        generate: 'ssr',
        dev,
        preprocess,
      }),
      resolve({
        dedupe,
      }),
      commonjs(),
      postcss({
        plugins: postcssPlugins(!dev),
        extract: 'static/global.css',
      }),
      json()
    ],
    external: Object.keys(pkg.dependencies).concat(
      require('module').builtinModules ||
        Object.keys(process.binding('natives'))
    ),
    onwarn,
  },

  serviceworker: {
    input: config.serviceworker.input(),
    output: config.serviceworker.output(),
    plugins: [
      // eslint(),
      visualizer( { filename: 'visualizer_stats/service-worker.json', title: 'Service Worker Bundle', json: true } ),
      resolve(),
      replace({
        'process.browser': true,
        'process.env.NODE_ENV': JSON.stringify( mode || 'production'),
      }),
      commonjs(),
      !dev && terser(),
    ],
    onwarn,
  }
}