rollup#OutputOptions TypeScript Examples

The following examples show how to use rollup#OutputOptions. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From vite-ssr with MIT License 6 votes vote down vote up
async function generatePackageJson(
  viteConfig: ResolvedConfig,
  clientBuildOptions: InlineConfig,
  serverBuildOptions: NonNullable<BuildOptions['serverOptions']>
) {
  if (serverBuildOptions.packageJson === false) return

  const outputFile = (
    serverBuildOptions.build?.rollupOptions?.output as OutputOptions
  )?.file

  const ssrOutput = path.parse(
    outputFile ||
      ((viteConfig.build?.ssr || serverBuildOptions.build?.ssr) as string)
  )

  const moduleFormat =
    (viteConfig.build?.rollupOptions?.output as OutputOptions)?.format ||
    (serverBuildOptions.build?.rollupOptions?.output as OutputOptions)?.format

  const packageJson = {
    main: outputFile ? ssrOutput.base : ssrOutput.name + '.js',
    type: /^esm?$/i.test(moduleFormat || '') ? 'module' : 'commonjs',
    ssr: {
      // This can be used later to serve static assets
      assets: (
        await fs.readdir(clientBuildOptions.build?.outDir as string)
      ).filter((file) => !/(index\.html|manifest\.json)$/i.test(file)),
    },
    ...(serverBuildOptions.packageJson || {}),
  }

  await fs.writeFile(
    path.join(serverBuildOptions.build?.outDir as string, 'package.json'),
    JSON.stringify(packageJson, null, 2),
    'utf-8'
  )
}
Example #2
Source File: rollup-plugin.test.ts    From vanilla-extract with MIT License 6 votes vote down vote up
async function build(outputOptions: OutputOptions) {
  const bundle = await rollup({
    input: require.resolve('@fixtures/themed'),
    plugins: [
      vanillaExtractPlugin({
        cwd: path.dirname(require.resolve('@fixtures/themed/package.json')),
      }),
      esbuild(),
      json(),
    ],
    external: ['@vanilla-extract/dynamic'],
  });
  const { output } = await bundle.generate(outputOptions);
  output.sort((a, b) => a.fileName.localeCompare(b.fileName));
  return output;
}
Example #3
Source File: rollup-plugin.test.ts    From vanilla-extract with MIT License 6 votes vote down vote up
async function buildAndMatchSnapshot(outputOptions: OutputOptions) {
  const output = await build(outputOptions);
  expect(
    output.map((chunkOrAsset) => [
      chunkOrAsset.fileName,
      chunkOrAsset.type === 'asset' ? chunkOrAsset.source : chunkOrAsset.code,
    ]),
  ).toMatchSnapshot();
}
Example #4
Source File: gulpfile.ts    From gdir with Do What The F*ck You Want To Public License 6 votes vote down vote up
gulp.task('worker.rollup', async () => {
    const output: OutputOptions = {
        file: './dist/worker.js',
        format: 'iife',
        sourcemap: true,
    };
    const input: RollupOptions = {
        input: './worker/index.ts',
        plugins: [
            resolve({
                extensions: ['.js', '.ts'],
            }),
            commonjs({
                include: 'node_modules/**',
                extensions: ['.js', '.ts'],
            }),
            typescriptPlugin({
                tsconfig: './worker/tsconfig.json',
            }),
        ],
    };
    const bundle = await rollup(input);
    await bundle.write(output);
});
Example #5
Source File: buildTask.ts    From Cromwell with MIT License 5 votes vote down vote up
rollupBuild = async (moduleInfo: TPackageCromwellConfig, moduleConfig?: TModuleConfig, watch?: boolean): Promise<boolean> => {
    if (!moduleInfo || !moduleInfo.type) return false;
    let rollupBuildSuccess = false;
    const { rollup, watch: rollupWatch } = require('rollup');

    try {
        const { rollupConfigWrapper } = require('@cromwell/utils');
        const rollupConfig = await rollupConfigWrapper(moduleInfo, moduleConfig, watch);

        if (rollupConfig.length === 0) {
            logger.error('Failed to find input files');
            return false;
        }

        if (watch) {
            const watcher = rollupWatch(rollupConfig);

            let eventHandler = onRollupEvent;
            if (moduleInfo.type === 'theme') {
                eventHandler = onRollupEventShort;
            }
            rollupBuildSuccess = await new Promise(done => {
                watcher.on('event', eventHandler(done));
            });
        } else {

            for (const optionsObj of rollupConfig) {
                const outputFiles: (string | undefined)[] = []

                if (optionsObj?.output && Array.isArray(optionsObj?.output)) {
                    optionsObj.output.forEach(out => {
                        outputFiles.push(out.dir ?? out.file);
                    });
                } else if (optionsObj?.output && typeof optionsObj?.output === 'object') {
                    outputFiles.push((optionsObj.output as OutputOptions).dir ?? (optionsObj.output as OutputOptions).file)
                }

                onRollupEvent()({
                    code: 'BUNDLE_START',
                    input: optionsObj.input,
                    output: (outputFiles.filter(Boolean) as string[])
                });
                const dateStart = Date.now();

                const bundle = await rollup(optionsObj);

                if (optionsObj?.output && Array.isArray(optionsObj?.output)) {
                    await Promise.all(optionsObj.output.map(bundle.write));

                } else if (optionsObj?.output && typeof optionsObj?.output === 'object') {
                    await bundle.write(optionsObj.output as OutputOptions)
                }

                const dateEnd = Date.now();

                onRollupEvent()({
                    code: 'BUNDLE_END',
                    input: optionsObj.input,
                    output: (outputFiles.filter(Boolean) as string[]),
                    result: bundle,
                    duration: (dateEnd - dateStart)
                });

                await bundle.close();
            }
            rollupBuildSuccess = true;
        }

    } catch (e) {
        logger.error(e);
    }
    return rollupBuildSuccess;
}
Example #6
Source File: normalizeRollupConfig.ts    From icepkg with MIT License 5 votes vote down vote up
getRollupOutputs = ({
  userConfig,
  pkg,
  outputDir,
  isES2017,
}: {
  userConfig: UserConfig;
  outputDir: string;
  pkg: PkgJson;
  isES2017: boolean;
}): OutputOptions[] => {
  const outputs: OutputOptions[] = [];

  const uncompressedDevelopment = userConfig?.bundle?.development;
  const outputFormats = (userConfig?.bundle?.formats || []).filter((format) => format !== 'es2017') as Array<'umd' | 'esm'>;

  const filename = userConfig?.bundle?.filename ?? 'index';
  const name = userConfig?.bundle?.name ?? pkg.name;

  const sourceMaps = userConfig?.sourceMaps ?? false;

  outputFormats.forEach((format) => {
    const commonOption = {
      name,
      format,
      sourcemap: sourceMaps,
    };

    const filenamePrefix = `${filename}${format === 'umd' ? '.umd' : ''}${isES2017 ? '.es2017' : ''}`;
    outputs.push({
      ...commonOption,
      file: join(outputDir, `${filenamePrefix}.production.js`),
      plugins: [minify({ minifyOption: true, sourceMaps })],
    });

    if (uncompressedDevelopment) {
      outputs.push({
        ...commonOption,
        file: join(outputDir, `${filenamePrefix}.development.js`),
      });
    }
  });

  return outputs;
}
Example #7
Source File: test-helpers.ts    From stencil-tailwind with MIT License 5 votes vote down vote up
export default async function(bundle: RollupBuild, customOptions: OutputOptions  = {}) {
  const options = Object.assign({ format: 'cjs' }, customOptions);
  return (await bundle.generate(options)).output[0].code;
}
Example #8
Source File: compile.ts    From mantine with MIT License 5 votes vote down vote up
export default async function compile(config: RollupOptions) {
  const build = await rollup(config);
  const outputs: OutputOptions[] = Array.isArray(config.output) ? config.output : [config.output];

  return Promise.all(outputs.map((output) => build.write(output)));
}
Example #9
Source File: rollup-plugin-html.test.ts    From web with MIT License 5 votes vote down vote up
outputConfig: OutputOptions = {
  format: 'es',
  dir: 'dist',
}
Example #10
Source File: rollupPluginPolyfillsLoader.test.ts    From web with MIT License 5 votes vote down vote up
defaultOutputOptions: OutputOptions[] = [
  {
    format: 'es',
    dir: 'dist',
  },
]
Example #11
Source File: rollup.ts    From Cromwell with MIT License 4 votes vote down vote up
rollupConfigWrapper = async (moduleInfo: TPackageCromwellConfig, moduleConfig?: TModuleConfig, watch?: boolean): Promise<RollupOptions[]> => {

    if (!moduleInfo) throw new Error(`CromwellPlugin Error. Provide config as second argument to the wrapper function`);
    if (!moduleInfo?.type) throw new Error(`CromwellPlugin Error. Provide one of types to the CromwellConfig: 'plugin', 'theme'`);

    try {
        const pckg: TPackageJson = require(resolve(process.cwd(), 'package.json'));
        if (pckg?.name) moduleInfo.name = pckg.name;
    } catch (e) {
        logger.error('Failed to find package.json in project root');
        logger.error(e);
    }

    if (!moduleInfo.name) throw new Error(`CromwellPlugin Error. Failed to find name of the package in working directory`);

    const strippedName = moduleInfo.name.replace(/\W/g, '_');


    const packagePaths = await globPackages(process.cwd());
    const packages = collectPackagesInfo(packagePaths);
    const frontendDeps = await collectFrontendDependencies(packages, false);

    let specifiedOptions: TRollupConfig | undefined = moduleConfig?.rollupConfig?.() as any;
    if (isPromise(specifiedOptions)) specifiedOptions = await specifiedOptions as any;

    const inputOptions = specifiedOptions?.main;
    const outOptions: RollupOptions[] = [];

    const resolveFileExtension = (basePath: string): string | undefined => {
        const globStr = `${normalizePath(resolve(process.cwd(), basePath))}.+(ts|tsx|js|jsx)`;
        const files = glob.sync(globStr);
        return files[0]
    }


    if (moduleInfo.type === 'plugin') {
        const pluginConfig = moduleConfig as TPluginConfig | undefined;

        let frontendInputFile = pluginConfig?.frontendInputFile;
        if (!frontendInputFile) {
            frontendInputFile = resolveFileExtension('src/frontend/index');
        }

        if (frontendInputFile) {
            // Plugin frontend

            const options: RollupOptions = (Object.assign({}, specifiedOptions?.frontend ?? inputOptions));
            const inputPath = isAbsolute(frontendInputFile) ? normalizePath(frontendInputFile) :
                normalizePath(resolve(process.cwd(), frontendInputFile));

            const optionsInput = '$$' + moduleInfo.name + '/' + frontendInputFile;
            options.input = optionsInput;
            options.output = Object.assign({}, options.output, {
                file: resolve(process.cwd(), buildDirName, pluginFrontendBundlePath),
                format: "iife",
                exports: 'default',
                name: strippedName,
                banner: '(function() {',
                footer: `return ${strippedName};})();`
            } as OutputOptions);

            options.plugins = [...(options.plugins ?? [])];

            options.plugins.push(virtual({
                [optionsInput]: `
                        import defaultComp from '${inputPath}';
                        export default defaultComp;
                        `
            }))
            options.plugins.push(await rollupPluginCromwellFrontend({
                moduleInfo,
                moduleConfig,
                frontendDeps,
            }));
            outOptions.push(options);

            // Plugin frontend cjs (for getStaticPaths at server)
            const cjsOptions = Object.assign({}, specifiedOptions?.frontendCjs ?? inputOptions);

            cjsOptions.input = optionsInput;
            cjsOptions.output = Object.assign({}, cjsOptions.output, {
                file: resolve(process.cwd(), buildDirName, pluginFrontendCjsPath),
                format: "cjs",
                name: moduleInfo.name,
                exports: "auto"
            } as OutputOptions)

            cjsOptions.plugins = [...(cjsOptions.plugins ?? [])];

            cjsOptions.plugins.push(virtual({
                [optionsInput]: `
                    import * as allExports from '${inputPath}';
                    export default allExports;
                    `
            }))
            cjsOptions.plugins.push(await rollupPluginCromwellFrontend({
                generateMeta: false,
                moduleInfo,
                moduleConfig,
            }));
            outOptions.push(cjsOptions);

        }

        // Plugin admin panel
        let adminInputFile = pluginConfig?.adminInputFile;
        if (!adminInputFile) {
            adminInputFile = resolveFileExtension('src/admin/index');
        }

        if (adminInputFile) {
            const options = (Object.assign({}, specifiedOptions?.frontend ?? inputOptions));
            const inputPath = isAbsolute(adminInputFile) ? normalizePath(adminInputFile) :
                normalizePath(resolve(process.cwd(), adminInputFile));

            const optionsInput = '$$' + moduleInfo.name + '/' + adminInputFile;
            options.input = optionsInput;
            options.output = Object.assign({}, options.output, {
                file: resolve(process.cwd(), buildDirName, pluginAdminBundlePath),
                format: "iife",
                name: strippedName,
            } as OutputOptions);

            options.plugins = [...(options.plugins ?? [])];

            options.plugins.push(virtual({
                [optionsInput]: `
                        import '${inputPath}';
                        `
            }))
            options.plugins.push(await rollupPluginCromwellFrontend({
                moduleInfo,
                moduleConfig,
                frontendDeps,
            }));
            outOptions.push(options);
        }

        // Plugin backend
        const backendInputFile = resolveFileExtension(pluginConfig?.backend ?? 'src/backend/index');
        if (backendInputFile) {
            const cjsOptions = Object.assign({}, specifiedOptions?.backend ?? inputOptions);

            cjsOptions.input = backendInputFile;
            cjsOptions.output = Object.assign({}, cjsOptions.output, {
                file: getPluginBackendPath(resolve(process.cwd(), buildDirName)),
                format: "cjs",
                name: moduleInfo.name,
                exports: "auto"
            } as OutputOptions)

            cjsOptions.plugins = [...(cjsOptions.plugins ?? [])];

            cjsOptions.external = isExternalForm;

            outOptions.push(cjsOptions);
        }

        // Copy static into public
        if (watch) {
            startStaticWatcher(moduleInfo.name, 'plugin');
        } else {
            const pluginStaticDir = await getModuleStaticDir(moduleInfo.name)
            if (pluginStaticDir && await fs.pathExists(pluginStaticDir)) {
                try {
                    const publicPluginsDir = getPublicPluginsDir();
                    await fs.ensureDir(publicPluginsDir);
                    await fs.copy(pluginStaticDir, resolve(publicPluginsDir, moduleInfo.name));
                } catch (e) { logger.log(e) }
            }
        }
    }

    if (moduleInfo.type === 'theme') {
        const buildDir = normalizePath(getThemeTempRollupBuildDir());
        if (!buildDir) throw new Error(`CromwellPlugin Error. Failed to find package directory of ` + moduleInfo.name);

        let srcDir = process.cwd();
        let pagesDirChunk = 'pages';
        let pagesDir = resolve(srcDir, pagesDirChunk);

        if (!fs.existsSync(pagesDir)) {
            srcDir = resolve(process.cwd(), 'src');
            pagesDir = resolve(srcDir, 'pages');
            pagesDirChunk = 'src/pages';
        }

        if (!fs.pathExistsSync(pagesDir)) {
            throw new Error('Pages directory was not found')
        }

        // Theme frontend
        const options: RollupOptions = (Object.assign({}, specifiedOptions?.themePages ? specifiedOptions.themePages : inputOptions));
        const globStr = `${pagesDir}/**/*.+(ts|tsx|js|jsx)`;
        const pageFiles = glob.sync(globStr);

        const pagesMetaInfo = await collectPages({
            buildDir,
            pagesDir,
        });

        const dependencyOptions: RollupOptions[] = [];

        if (pageFiles && pageFiles.length > 0) {
            options.plugins = [...(options.plugins ?? [])];

            options.input = getThemePagesVirtualPath(buildDir);

            options.output = Object.assign({}, options.output, {
                dir: buildDir,
                format: "esm",
                preserveModules: true
            } as OutputOptions);

            options.plugins.push(scssExternalPlugin());

            if (!options.plugins.find(plugin => typeof plugin === 'object' && plugin?.name === '@rollup/plugin-babel' ||
                typeof plugin === 'object' && plugin?.name === 'babel'))
                options.plugins.push(babel({
                    extensions: ['.js', '.jsx', '.ts', '.tsx'],
                    babelHelpers: 'bundled',
                    presets: ['@babel/preset-react']
                }));

            options.plugins.push(await rollupPluginCromwellFrontend({
                pagesMetaInfo, buildDir, srcDir, moduleInfo,
                moduleConfig, watch,
                generatePagesMeta: true,
                frontendDeps, dependencyOptions,
                type: 'themePages',
                pagesDir,
            }));

            if (!options.plugins.find(plugin => typeof plugin === 'object' && plugin?.name === '@rollup/plugin-node-resolve'
                || typeof plugin === 'object' && plugin?.name === 'node-resolve'))
                options.plugins.push(nodeResolve({
                    extensions: ['.js', '.jsx', '.ts', '.tsx'],
                }));

            outOptions.push(options);

            if (watch) {
                startPagesWatcher(buildDir, pagesDir);
            }
        } else {
            throw new Error('CromwellPlugin Error. No pages found at: ' + pagesDir);
        }


        // Copy static into public
        if (watch) {
            startStaticWatcher(moduleInfo.name, 'theme');
        } else {
            const themeStaticDir = await getModuleStaticDir(moduleInfo.name);
            if (themeStaticDir && await fs.pathExists(themeStaticDir)) {
                try {
                    const publicThemesDir = getPublicThemesDir();
                    await fs.ensureDir(publicThemesDir);
                    await fs.copy(themeStaticDir, resolve(publicThemesDir, moduleInfo.name), {
                        overwrite: false,
                    });
                } catch (e) { logger.log(e) }
            }
        }


        // Theme admin panel page-controller 
        const adminPanelDirChunk = 'admin-panel';
        const adminPanelDir = resolve(srcDir, adminPanelDirChunk);
        if (!watch && fs.pathExistsSync(adminPanelDir)) {
            const adminOptions: RollupOptions = (Object.assign({}, specifiedOptions?.themePages ? specifiedOptions.themePages : inputOptions));

            adminOptions.plugins = [...(adminOptions.plugins ?? [])];

            const optionsInput = '$$' + moduleInfo.name + '/' + adminPanelDirChunk;
            adminOptions.plugins.push(virtual({
                [optionsInput]: `import settings from '${normalizePath(adminPanelDir)}'; export default settings`
            }));
            adminOptions.input = optionsInput;

            adminOptions.output = Object.assign({}, adminOptions.output, {
                dir: resolve(buildDir, 'admin', '_settings'),
                format: "iife",
            } as OutputOptions);

            adminOptions.plugins.push(await rollupPluginCromwellFrontend({
                pagesMetaInfo, buildDir, srcDir,
                moduleInfo, moduleConfig, frontendDeps,
                pagesDir,
            }));

            outOptions.push(adminOptions);
        }
    }

    return outOptions;
}
Example #12
Source File: config.ts    From backstage with Apache License 2.0 4 votes vote down vote up
export async function makeRollupConfigs(
  options: BuildOptions,
): Promise<RollupOptions[]> {
  const configs = new Array<RollupOptions>();
  const targetDir = options.targetDir ?? paths.targetDir;
  const onwarn = ({ code, message }: RollupWarning) => {
    if (code === 'EMPTY_BUNDLE') {
      return; // We don't care about this one
    }
    if (options.logPrefix) {
      console.log(options.logPrefix + message);
    } else {
      console.log(message);
    }
  };

  const distDir = resolvePath(targetDir, 'dist');

  if (options.outputs.has(Output.cjs) || options.outputs.has(Output.esm)) {
    const output = new Array<OutputOptions>();
    const mainFields = ['module', 'main'];

    if (options.outputs.has(Output.cjs)) {
      output.push({
        dir: distDir,
        entryFileNames: 'index.cjs.js',
        chunkFileNames: 'cjs/[name]-[hash].cjs.js',
        format: 'commonjs',
        sourcemap: true,
      });
    }
    if (options.outputs.has(Output.esm)) {
      output.push({
        dir: distDir,
        entryFileNames: 'index.esm.js',
        chunkFileNames: 'esm/[name]-[hash].esm.js',
        format: 'module',
        sourcemap: true,
      });
      // Assume we're building for the browser if ESM output is included
      mainFields.unshift('browser');
    }

    configs.push({
      input: resolvePath(targetDir, 'src/index.ts'),
      output,
      onwarn,
      preserveEntrySignatures: 'strict',
      // All module imports are always marked as external
      external: (source, importer, isResolved) =>
        Boolean(importer && !isResolved && !isFileImport(source)),
      plugins: [
        resolve({ mainFields }),
        commonjs({
          include: /node_modules/,
          exclude: [/\/[^/]+\.(?:stories|test)\.[^/]+$/],
        }),
        postcss(),
        forwardFileImports({
          exclude: /\.icon\.svg$/,
          include: [
            /\.svg$/,
            /\.png$/,
            /\.gif$/,
            /\.jpg$/,
            /\.jpeg$/,
            /\.eot$/,
            /\.woff$/,
            /\.woff2$/,
            /\.ttf$/,
          ],
        }),
        json(),
        yaml(),
        svgr({
          include: /\.icon\.svg$/,
          template: svgrTemplate,
        }),
        esbuild({
          target: 'es2019',
          minify: options.minify,
        }),
      ],
    });
  }

  if (options.outputs.has(Output.types) && !options.useApiExtractor) {
    const typesInput = paths.resolveTargetRoot(
      'dist-types',
      relativePath(paths.targetRoot, targetDir),
      'src/index.d.ts',
    );

    const declarationsExist = await fs.pathExists(typesInput);
    if (!declarationsExist) {
      const path = relativePath(targetDir, typesInput);
      throw new Error(
        `No declaration files found at ${path}, be sure to run ${chalk.bgRed.white(
          'yarn tsc',
        )} to generate .d.ts files before packaging`,
      );
    }

    configs.push({
      input: typesInput,
      output: {
        file: resolvePath(distDir, 'index.d.ts'),
        format: 'es',
      },
      external: [
        /\.css$/,
        /\.scss$/,
        /\.sass$/,
        /\.svg$/,
        /\.eot$/,
        /\.woff$/,
        /\.woff2$/,
        /\.ttf$/,
      ],
      onwarn,
      plugins: [dts()],
    });
  }

  return configs;
}
Example #13
Source File: create-package-config.ts    From mantine with MIT License 4 votes vote down vote up
export default async function createPackageConfig(config: PkgConfigInput): Promise<RollupOptions> {
  const packageJson = JSON.parse(
    fs.readFileSync(path.join(config.basePath, './package.json')).toString('utf-8')
  );
  const pkgList = await getPackagesList();

  const aliasEntries: Alias[] = pkgList.map((pkg) => ({
    find: new RegExp(`^${pkg.packageJson.name}`),
    replacement: path.resolve(pkg.path, 'src'),
  }));

  const plugins = [
    commonjs(),
    nodeExternals(),
    nodeResolve({ extensions: ['.ts', '.tsx', '.js', '.jsx'] }),
    esbuild({
      minify: config.format === 'umd',
      sourceMap: false,
      tsconfig: path.resolve(process.cwd(), 'tsconfig.json'),
    }),
    json(),
    alias({ entries: aliasEntries }),
    replace({ preventAssignment: true }),
  ];

  let externals;

  if (config.format === 'umd') {
    externals = [
      ...(config?.externals || []),
      ...Object.keys({
        ...packageJson.peerDependencies,
      }),
    ];
  } else {
    externals = [
      '@emotion/server/create-instance',
      'dayjs/locale/ru',
      ...(config?.externals || []),
      ...Object.keys({
        ...packageJson.peerDependencies,
        ...packageJson.dependencies,
      }),
    ];
  }

  const output: OutputOptions = {
    name: packageJson.name,
    format: config.format as ModuleFormat,
    externalLiveBindings: false,
    sourcemap: config.sourcemap,
  };

  if (config.format === 'es') {
    output.dir = path.resolve(config.basePath, 'esm');
    output.preserveModules = true;
  }

  if (config.format === 'cjs') {
    output.dir = path.resolve(config.basePath, 'cjs');
    output.preserveModules = true;
    output.exports = 'named';
  }

  if (config.format === 'umd') {
    output.file = path.resolve(config.basePath, 'lib/index.umd.js');
    output.globals = {
      ...pkgList
        .map((pkg) => ({
          [pkg.packageJson.name]: pkg.packageJson.name,
        }))
        .reduce((globals, pkgGlobal) => ({ ...globals, ...pkgGlobal }), {}),
      react: 'React',
      dayjs: 'dayjs',
      'react-dom': 'ReactDOM',
    };
  }

  if (config.analyze && config.format === 'es') {
    plugins.push(
      visualizer({
        title: packageJson.name,
        filename: path.join(config.basePath, 'lib/stats.html'),
        projectRoot: path.join(config.basePath, 'src'),
        sourcemap: true,
        gzipSize: true,
      }),
      visualizer({
        title: packageJson.name,
        filename: path.join(config.basePath, 'lib/stats.json'),
        projectRoot: path.join(config.basePath, 'src'),
        json: true,
        sourcemap: true,
        gzipSize: true,
      })
    );
  }

  return {
    input: config?.entry || path.resolve(config.basePath, 'src/index.ts'),
    output,
    external: externals,
    plugins,
  };
}
Example #14
Source File: rollupPluginPolyfillsLoader.test.ts    From web with MIT License 4 votes vote down vote up
describe('rollup-plugin-polyfills-loader', function describe() {
  // bootup of the first test can take a long time in CI to load all the polyfills
  this.timeout(5000);

  it('can inject a polyfills loader with a single output', async () => {
    const inputOptions: RollupOptions = {
      plugins: [
        html({
          input: {
            html: `<script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js"></script>`,
          },
        }),
        polyfillsLoader({
          polyfills: { hash: false, fetch: true },
        }),
      ],
    };

    await testSnapshot({
      name: 'single-output',
      fileName: 'index.html',
      inputOptions,
      outputOptions: defaultOutputOptions,
    });
  });

  it('can inject a polyfills loader with multiple entrypoints', async () => {
    const inputOptions: RollupOptions = {
      plugins: [
        html({
          input: {
            html: `
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js"></script>
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-b.js"></script>`,
          },
        }),
        polyfillsLoader({
          polyfills: { hash: false, fetch: true },
        }),
      ],
    };

    await testSnapshot({
      name: 'multiple-entrypoints',
      fileName: 'index.html',
      inputOptions,
      outputOptions: defaultOutputOptions,
    });
  });

  it('retains attributes on script tags when injecting a polyfills loader with multiple entrypoints', async () => {
    const inputOptions: RollupOptions = {
      plugins: [
        html({
          input: {
            html: `
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js" keep-this-attribute></script>
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-b.js"></script>`,
          },
        }),
        polyfillsLoader({
          polyfills: { hash: false, fetch: true },
        }),
      ],
    };

    await testSnapshot({
      name: 'multiple-entrypoints-retain-attributes',
      fileName: 'index.html',
      inputOptions,
      outputOptions: defaultOutputOptions,
    });
  });

  it('can inject a polyfills loader with non-flat inputs, flattenOutput: true', async () => {
    const inputOptions: RollupOptions = {
      plugins: [
        html({
          rootDir: `${relativeUrl}/fixtures/`,
          input: `non-flat/index.html`,
          flattenOutput: true,
        }),
        polyfillsLoader({
          polyfills: { hash: false, fetch: true },
        }),
      ],
    };

    await testSnapshot({
      name: 'flattened',
      fileName: `index.html`,
      inputOptions,
      outputOptions: defaultOutputOptions,
    });
  });

  it('can inject a polyfills loader with non-flat inputs, flattenOutput: false', async () => {
    const inputOptions: RollupOptions = {
      plugins: [
        html({
          rootDir: `${relativeUrl}/fixtures/`,
          input: `non-flat/index.html`,
          flattenOutput: false,
        }),
        polyfillsLoader({
          polyfills: { hash: false, fetch: true },
        }),
      ],
    };

    await testSnapshot({
      name: 'non-flattened',
      fileName: path.normalize(`non-flat/index.html`),
      inputOptions,
      outputOptions: defaultOutputOptions,
    });
  });

  it('injects the correct preload for systemjs output', async () => {
    const inputOptions: RollupOptions = {
      plugins: [
        html({
          input: {
            html: `
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js"></script>
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-b.js"></script>`,
          },
        }),
        polyfillsLoader(),
      ],
    };

    await testSnapshot({
      name: 'systemjs',
      fileName: 'index.html',
      inputOptions,
      outputOptions: [
        {
          format: 'system',
          dir: 'dist',
        },
      ],
    });
  });

  it('can set polyfills to load', async () => {
    const inputOptions = {
      plugins: [
        html({
          input: {
            html: `<script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js"></script>`,
          },
        }),
        polyfillsLoader({
          polyfills: {
            hash: false,
            webcomponents: true,
            fetch: true,
          },
        }),
      ],
    };

    const output = await testSnapshot({
      name: 'polyfills',
      fileName: 'index.html',
      inputOptions,
      outputOptions: defaultOutputOptions,
    });

    expect(output.find(o => o.fileName.startsWith('polyfills/webcomponents'))).to.exist;
    expect(output.find(o => o.fileName.startsWith('polyfills/fetch'))).to.exist;
  });

  it('can inject with multiple build outputs', async () => {
    const htmlPlugin = html({
      input: {
        html: `<script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js"></script>`,
      },
    });
    const inputOptions = {
      plugins: [
        htmlPlugin,
        polyfillsLoader({
          modernOutput: { name: 'modern' },
          legacyOutput: [{ name: 'legacy', test: "!('noModule' in HTMLScriptElement.prototype)" }],
          polyfills: { hash: false, webcomponents: true, fetch: true },
        }),
      ],
    };

    const outputOptions: OutputOptions[] = [
      {
        format: 'system',
        dir: 'dist',
        plugins: [htmlPlugin.api.addOutput('legacy')],
      },
      {
        format: 'es',
        dir: 'dist',
        plugins: [htmlPlugin.api.addOutput('modern')],
      },
    ];

    await testSnapshot({
      name: 'multiple-outputs',
      fileName: 'index.html',
      inputOptions,
      outputOptions,
    });
  });

  it('can customize the file type', async () => {
    const htmlPlugin = html({
      input: {
        html: `<script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js"></script>`,
      },
    });
    const inputOptions = {
      plugins: [
        htmlPlugin,
        polyfillsLoader({
          modernOutput: { name: 'modern', type: 'systemjs' },
          polyfills: { hash: false, webcomponents: true, fetch: true },
        }),
      ],
    };

    const outputOptions: OutputOptions[] = [
      {
        format: 'es',
        dir: 'dist',
      },
    ];

    await testSnapshot({
      name: 'customize-filetype',
      fileName: 'index.html',
      inputOptions,
      outputOptions,
    });
  });

  it('can customize the file type for multiple outputs', async () => {
    const htmlPlugin = html({
      input: {
        html: `<script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js"></script>`,
      },
    });
    const inputOptions = {
      plugins: [
        htmlPlugin,
        polyfillsLoader({
          modernOutput: { name: 'modern', type: 'script' },
          legacyOutput: [
            {
              name: 'legacy',
              type: 'script',
              test: "!('noModule' in HTMLScriptElement.prototype)",
            },
          ],
          polyfills: { hash: false, webcomponents: true, fetch: true },
        }),
      ],
    };

    const outputOptions: OutputOptions[] = [
      {
        format: 'system',
        dir: 'dist',
        plugins: [htmlPlugin.api.addOutput('legacy')],
      },
      {
        format: 'es',
        dir: 'dist',
        plugins: [htmlPlugin.api.addOutput('modern')],
      },
    ];

    await testSnapshot({
      name: 'customize-filetype-multi-output',
      fileName: 'index.html',
      inputOptions,
      outputOptions,
    });
  });

  it('injects preload when there are no polyfills to inject', async () => {
    const inputOptions: RollupOptions = {
      plugins: [
        html({
          input: {
            html: `
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js"></script>
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-b.js"></script>`,
          },
        }),
        polyfillsLoader(),
      ],
    };

    await testSnapshot({
      name: 'no-polyfills',
      fileName: 'index.html',
      inputOptions,
      outputOptions: defaultOutputOptions,
    });
  });

  it('will retain attributes of script tags if there are no polyfills to inject', async () => {
    const inputOptions: RollupOptions = {
      plugins: [
        html({
          input: {
            html: `
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js" keep-this-attribute></script>
            <script type="module" src="${relativeUrl}/fixtures/entrypoint-b.js"></script>`,
          },
        }),
        polyfillsLoader(),
      ],
    };

    await testSnapshot({
      name: 'no-polyfills-retain-attributes',
      fileName: 'index.html',
      inputOptions,
      outputOptions: defaultOutputOptions,
    });
  });

  it('can inject a polyfills loader as an external script', async () => {
    const inputOptions: RollupOptions = {
      plugins: [
        html({
          input: {
            html: `<script type="module" src="${relativeUrl}/fixtures/entrypoint-a.js"></script>`,
          },
        }),
        polyfillsLoader({
          polyfills: { hash: false, fetch: true },
          externalLoaderScript: true,
        }),
      ],
    };

    await testSnapshot({
      name: 'external-script',
      fileName: 'index.html',
      inputOptions,
      outputOptions: defaultOutputOptions,
    });
  });
});
Example #15
Source File: buildCjs.ts    From gitmars with GNU General Public License v3.0 4 votes vote down vote up
export async function buildCjs() {
    const externals = [
        'js-cool',
        '@gitmars/core',
        '@gitmars/docs',
        '@gitmars/server',
        '@gitmars/ui'
    ]
    const builds = pkgs.map(
        async ({
            globals = {},
            name,
            external = [],
            submodules,
            iife,
            build,
            cjs,
            mjs,
            dts,
            target,
            exportType = 'auto'
        }) => {
            // if (build === false) return
            const pkg = require(resolve(PACKAGE, name, 'package.json'))
            const banner =
                '/*!\n' +
                ' * ' +
                pkg.name +
                ' v' +
                pkg.version +
                '\n' +
                ' * ' +
                pkg.description +
                '\n' +
                ' * (c) 2021-' +
                new Date().getFullYear() +
                ' saqqdy<https://github.com/saqqdy> \n' +
                ' * Released under the MIT License.\n' +
                ' */'
            // const deps = Object.keys(pkg.dependencies || {})
            const iifeGlobals = {
                'js-cool': 'JsCool',
                '@gitmars/utils': 'EslintSets',
                '@gitmars/core': 'EslintSets',
                ...globals
            }
            const iifeName = 'Gitmars'
            const fileList = excludeFiles(
                glob.sync('**/*.ts', {
                    cwd: resolve(PACKAGE, name, 'src'),
                    ignore: ['node_modules'],
                    // absolute: true,
                    onlyFiles: true
                })
            )

            // submodules
            // if (submodules) {
            //     functionNames.push(
            //         ...glob
            //             .sync('*/index.ts', {
            //                 cwd: resolve(`packages/${name}`)
            //             })
            //             .map(i => i.split('/')[0])
            //     )
            // }
            for (const fn of fileList) {
                const input = resolve(PACKAGE, name, 'src', fn)

                const writeOptions: OutputOptions[] = []
                // output mjs
                if (mjs !== false) {
                    writeOptions.push({
                        file: resolve(
                            PACKAGE,
                            name,
                            'es',
                            fn.replace(/\.ts$/, '.mjs')
                        ),
                        exports: exportType,
                        banner,
                        format: 'es'
                    })
                }
                // output cjs
                if (cjs !== false) {
                    writeOptions.push({
                        file: resolve(
                            PACKAGE,
                            name,
                            'lib',
                            fn.replace(/\.ts$/, '.js')
                        ),
                        exports: exportType,
                        banner,
                        format: 'cjs'
                    })
                }
                // output iife
                if (iife !== false) {
                    writeOptions.push(
                        {
                            file: resolve(
                                PACKAGE,
                                name,
                                'dist',
                                fn.replace(/\.ts$/, 'iife.js')
                            ),
                            format: 'iife',
                            // exports: 'named',
                            // exports: exportType,
                            name: iifeName,
                            extend: true,
                            globals: iifeGlobals,
                            banner,
                            plugins: [
                                // injectEslintSetsCore,
                            ]
                        },
                        {
                            file: resolve(
                                PACKAGE,
                                name,
                                'dist',
                                fn.replace(/\.ts$/, 'iife.min.js')
                            ),
                            format: 'iife',
                            // exports: 'named',
                            // exports: exportType,
                            name: iifeName,
                            extend: true,
                            globals: iifeGlobals,
                            plugins: [
                                // injectEslintSetsCore,
                                minify({
                                    minify: true
                                }),
                                bannerPlugin(),
                                filesize
                            ]
                        }
                    )
                }

                const rollupConfig = {
                    input,
                    plugins: [
                        alias({
                            entries: [
                                {
                                    find: /^@\//,
                                    replacement: resolve(PACKAGE, name, 'src')
                                }
                            ],
                            customResolver: nodeResolve() as ResolverObject
                        }),
                        nodeResolve(),
                        json,
                        commonjs,
                        shebang(),
                        esbuild(),
                        // target ? esbuild({ target }) : esbuild(),
                        filesize
                    ],
                    external: generateExternal({ name, input }, [
                        ...externals,
                        ...external
                    ])
                }
                const bundle = await rollup(rollupConfig)
                await Promise.all(
                    writeOptions.map(option => bundle.write(option))
                )

                // dts
                if (dts !== false) {
                    const rollupDtsConfig = {
                        input,
                        plugins: [nodeExternals(), dtsPlugin],
                        external: [...externals, ...external]
                    }
                    const writeEsmDtsOptions: OutputOptions[] = [
                        {
                            file: resolve(
                                PACKAGE,
                                name,
                                'es',
                                fn.replace(/\.ts$/, '.d.ts')
                            ),
                            // exports: 'auto',
                            // exports: exportType,
                            // banner,
                            format: 'es'
                        }
                    ]
                    const writeCjsDtsOptions: OutputOptions[] = [
                        {
                            file: resolve(
                                PACKAGE,
                                name,
                                'lib',
                                fn.replace(/\.ts$/, '.d.ts')
                            ),
                            // exports: 'auto',
                            // exports: exportType,
                            // banner,
                            format: 'es'
                        }
                    ]
                    const dtsBundle = await rollup(rollupDtsConfig)
                    await Promise.all([
                        writeEsmDtsOptions.map(option =>
                            dtsBundle.write(option)
                        ),
                        writeCjsDtsOptions.map(option =>
                            dtsBundle.write(option)
                        )
                    ])
                }
            }
        }
    )
    await Promise.all(builds)
}