Skip to content
Snippets Groups Projects
rollup.config.js 8.64 KiB
Newer Older
import path from 'path';
import url from 'url';
import glob from 'glob';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import copy from 'rollup-plugin-copy';
import {terser} from "rollup-plugin-terser";
import json from '@rollup/plugin-json';
import serve from 'rollup-plugin-serve';
import urlPlugin from "@rollup/plugin-url";
import license from 'rollup-plugin-license';
import del from 'rollup-plugin-delete';
import md from 'rollup-plugin-md';
import emitEJS from 'rollup-plugin-emit-ejs'
import babel from '@rollup/plugin-babel'
import appConfig from './app.config.js';
import {generateTLSConfig, getBuildInfo, getPackagePath, getDistPath} from '../rollup.utils.js';

const pkg = require('./package.json');
const appEnv = (typeof process.env.APP_ENV !== 'undefined') ? process.env.APP_ENV : 'local';
const watch = process.env.ROLLUP_WATCH === 'true';
const buildFull = (!watch && appEnv !== 'test') || (process.env.FORCE_FULL !== undefined);
let useTerser = buildFull;
let useBabel = buildFull;
let checkLicenses = buildFull;
let useHTTPS = true;
console.log("APP_ENV: " + appEnv);
let config;
if (appEnv in appConfig) {
    config = appConfig[appEnv];
} else if (appEnv === 'test') {
    config = {
        basePath: '/',
        entryPointURL: 'https://test',
        keyCloakBaseURL: 'https://test',
        keyCloakClientId: '',
        matomoUrl: '',
        matomoSiteId: -1,
        nextcloudBaseURL: 'https://test',
        nextcloudName: '',
    };
} else {
    console.error(`Unknown build environment: '${appEnv}', use one of '${Object.keys(appConfig)}'`);
    process.exit(1);
}

if (config.nextcloudBaseURL) {
    config.nextcloudFileURL = config.nextcloudBaseURL + '/index.php/apps/files/?dir=';
    config.nextcloudWebAppPasswordURL = config.nextcloudBaseURL + '/index.php/apps/webapppassword';
    config.nextcloudWebDavURL = config.nextcloudBaseURL + '/remote.php/dav/files';
} else {
    config.nextcloudFileURL = '';
    config.nextcloudWebAppPasswordURL = '';
    config.nextcloudWebDavURL = '';
}
function getOrigin(url) {
    if (url)
        return new URL(url).origin;
    return '';
}
config.CSP = `default-src 'self' 'unsafe-eval' 'unsafe-inline' \
${getOrigin(config.matomoUrl)} ${getOrigin(config.keyCloakBaseURL)} ${getOrigin(config.entryPointURL)} \
httpbin.org ${getOrigin(config.nextcloudBaseURL)}; \
img-src * blob: data:`;
export default (async () => {
    let privatePath = await getDistPath(pkg.name)
    return {
    input: (appEnv != 'test') ? glob.sync('src/dbp-*.js') : glob.sync('test/**/*.js'),
    output: {
      dir: 'dist',
      entryFileNames: '[name].js',
      chunkFileNames: 'shared/[name].[hash].[format].js',
      format: 'esm',
      sourcemap: true
    },
    preserveEntrySignatures: false,
    // external: ['zlib', 'http', 'fs', 'https', 'url'],
    onwarn: function (warning, warn) {
        // ignore "suggestions" warning re "use strict"
        if (warning.code === 'MODULE_LEVEL_DIRECTIVE') {
            return;
        }
        // ignore chai warnings
        if (warning.code === 'CIRCULAR_DEPENDENCY') {
          return;
        }
        warn(warning);
    },
    plugins: [
        del({
          targets: 'dist/*'
        }),
        emitEJS({
          src: 'assets',
          include: ['**/*.ejs', '**/.*.ejs'],
          data: {
            getUrl: (p) => {
              return url.resolve(config.basePath, p);
            },
            getPrivateUrl: (p) => {
                return url.resolve(`${config.basePath}${privatePath}/`, p);
            },
            name: pkg.name,
            entryPointURL: config.entryPointURL,
            nextcloudBaseURL: config.nextcloudBaseURL,
            nextcloudWebAppPasswordURL: config.nextcloudWebAppPasswordURL,
            nextcloudWebDavURL: config.nextcloudWebDavURL,
            nextcloudFileURL: config.nextcloudFileURL,
            nextcloudName: config.nextcloudName,
            keyCloakBaseURL: config.keyCloakBaseURL,
            keyCloakClientId: config.keyCloakClientId,
            CSP: config.CSP,
            matomoUrl: config.matomoUrl,
            matomoSiteId: config.matomoSiteId,
            buildInfo: getBuildInfo(appEnv)
          }
        }),
        resolve({
          moduleDirectories: [path.join(process.cwd(), 'node_modules')],
          browser: true,
          preferBuiltins: true
        }),
        checkLicenses && license({
            banner: {
                commentStyle: 'ignored',
                content: `
License: <%= pkg.license %>
Dependencies:
<% _.forEach(dependencies, function (dependency) { if (dependency.name) { %>
<%= dependency.name %>: <%= dependency.license %><% }}) %>
`},
          thirdParty: {
            allow: {
Steinwender, Tamara's avatar
Steinwender, Tamara committed
              test: '(MIT OR BSD-3-Clause OR Apache-2.0 OR LGPL-2.1-or-later OR 0BSD)',
              failOnUnlicensed: true,
              failOnViolation: true,
            },
          },
        }),
        commonjs({
            include: 'node_modules/**',
        }),
        json(),
        md({
            include: ["../../**/*.md"],
            marked: {
                highlight: function(code) {
                    return require('highlight.js').highlightAuto(code).value;
                }
            }
        }),
        urlPlugin({
          limit: 0,
          include: [
            "node_modules/suggestions/**/*.css",
            "node_modules/select2/**/*.css",
            "node_modules/highlight.js/**/*.css",
          ],
          emitFiles: true,
          fileName: 'shared/[name].[hash][extname]'
        }),
        useTerser ? terser() : false,
        copy({
            targets: [
                {src: 'assets/*.css', dest: 'dist/' + await getDistPath(pkg.name)},
                {src: 'assets/*.ico', dest: 'dist/' + await getDistPath(pkg.name)},
                {src: 'assets/*.metadata.json', dest: 'dist'},
                {src: 'assets/*.svg', dest: 'dist/' + await getDistPath(pkg.name)},
                {src: 'assets/htaccess-shared', dest: 'dist/shared/', rename: '.htaccess'},
                {src: 'assets/icon-*.png', dest: 'dist/' + await getDistPath(pkg.name)},
                {src: 'assets/manifest.json', dest: 'dist', rename: pkg.name + '.manifest.json'},
                {src: 'assets/silent-check-sso.html', dest:'dist'},
                    src: await getPackagePath('pdfjs-dist', 'es5/build/pdf.worker.js'),
                    dest: 'dist/' + await getDistPath(pkg.name, 'pdfjs'),
                    // enable signatures in pdf preview
                    transform: (contents) => contents.toString().replace('"Sig"', '"Sig-patched-show-anyway"')
                {src: await getPackagePath('pdfjs-dist', 'cmaps/*'), dest: 'dist/' + await getDistPath(pkg.name, 'pdfjs')}, // do we want all map files?
                {src: await getPackagePath('@dbp-toolkit/font-source-sans-pro', 'files/*'), dest: 'dist/' + await getDistPath(pkg.name, 'fonts/source-sans-pro')},
                {src: await getPackagePath('@dbp-toolkit/common', 'src/spinner.js'), dest: 'dist/' + await getDistPath(pkg.name)},
                {src: await getPackagePath('@dbp-toolkit/common', 'misc/browser-check.js'), dest: 'dist/' + await getDistPath(pkg.name)},
                {src: await getPackagePath('@dbp-toolkit/common', 'assets/icons/*.svg'), dest: 'dist/' + await getDistPath('@dbp-toolkit/common', 'icons')},
                {src: await getPackagePath('tabulator-tables', 'dist/css'), dest: 'dist/' + await getDistPath('@dbp-toolkit/file-handling', 'tabulator-tables')},
                {src: await getPackagePath('qr-scanner', 'qr-scanner-worker.*'), dest: 'dist/' + await getDistPath('@dbp-toolkit/qr-code-scanner')},
            ],
        }),
        useBabel && babel({
          include: [
              'src/**',
              'node_modules/pdfjs-dist/**', // uses Promise.allSettled
          ],
          babelHelpers: 'runtime',
          babelrc: false,
          presets: [[
            '@babel/preset-env', {
              loose: true,
              bugfixes: true,
              targets: {
                esmodules: true
              }
            }
          ]],
          plugins: [[
            '@babel/plugin-transform-runtime', {
              corejs: 3,
              useESModules: true
            }
          ],
          '@babel/plugin-syntax-dynamic-import',
          '@babel/plugin-syntax-import-meta']
        }),
        watch ? serve({
          contentBase: '.',
          host: '127.0.0.1',
          historyApiFallback: config.basePath + pkg.name + '.html',
          https: useHTTPS ? await generateTLSConfig() : false,
          headers: {
              'Content-Security-Policy': config.CSP
          },
        }) : false
    ]