UNPKG

ipsos-components

Version:

Material Design components for Angular

197 lines (168 loc) 7.52 kB
import {join, dirname} from 'path'; import {uglifyJsFile} from './minify-sources'; import {buildConfig} from './build-config'; import {BuildPackage} from './build-package'; import {rollupRemoveLicensesPlugin} from './rollup-remove-licenses'; import {rollupGlobals, dashCaseToCamelCase} from './rollup-globals'; // There are no type definitions available for these imports. const rollup = require('rollup'); const rollupNodeResolutionPlugin = require('rollup-plugin-node-resolve'); const rollupAlias = require('rollup-plugin-alias'); /** Directory where all bundles will be created in. */ const bundlesDir = join(buildConfig.outputDir, 'bundles'); /** Utility for creating bundles from raw ngc output. */ export class PackageBundler { constructor(private buildPackage: BuildPackage) {} /** Creates all bundles for the package and all associated entry points (UMD, ES5, ES2015). */ async createBundles() { for (const entryPoint of this.buildPackage.secondaryEntryPoints) { await this.bundleSecondaryEntryPoint(entryPoint); } await this.bundlePrimaryEntryPoint(); } /** Bundles the primary entry-point w/ given entry file, e.g. @angular/cdk */ private async bundlePrimaryEntryPoint() { const packageName = this.buildPackage.name; return this.bundleEntryPoint({ entryFile: this.buildPackage.entryFilePath, esm5EntryFile: join(this.buildPackage.esm5OutputDir, 'index.js'), moduleName: `ng.${this.buildPackage.name}`, esm2015Dest: join(bundlesDir, `${packageName}.js`), esm5Dest: join(bundlesDir, `${packageName}.es5.js`), umdDest: join(bundlesDir, `${packageName}.umd.js`), umdMinDest: join(bundlesDir, `${packageName}.umd.min.js`), }); } /** Bundles a single secondary entry-point w/ given entry file, e.g. @angular/cdk/a11y */ private async bundleSecondaryEntryPoint(entryPoint: string) { const packageName = this.buildPackage.name; const entryFile = join(this.buildPackage.outputDir, entryPoint, 'index.js'); const esm5EntryFile = join(this.buildPackage.esm5OutputDir, entryPoint, 'index.js'); return this.bundleEntryPoint({ entryFile, esm5EntryFile, moduleName: `ng.${packageName}.${dashCaseToCamelCase(entryPoint)}`, esm2015Dest: join(bundlesDir, `${packageName}`, `${entryPoint}.js`), esm5Dest: join(bundlesDir, `${packageName}`, `${entryPoint}.es5.js`), umdDest: join(bundlesDir, `${packageName}-${entryPoint}.umd.js`), umdMinDest: join(bundlesDir, `${packageName}-${entryPoint}.umd.min.js`), }); } /** * Creates the ES5, ES2015, and UMD bundles for the specified entry-point. * @param config Configuration that specifies the entry-point, module name, and output * bundle paths. */ private async bundleEntryPoint(config: BundlesConfig) { // Build FESM-2015 bundle file. // TODO: re-add sorcery when we upgrade to Angular 5.x await this.createRollupBundle({ moduleName: config.moduleName, entry: config.entryFile, dest: config.esm2015Dest, format: 'es', }); // Build FESM-5 bundle file. // TODO: re-add sorcery when we upgrade to Angular 5.x await this.createRollupBundle({ moduleName: config.moduleName, entry: config.esm5EntryFile, dest: config.esm5Dest, format: 'es', }); // Create UMD bundle of ES5 output. // TODO: re-add sorcery when we upgrade to Angular 5.x await this.createRollupBundle({ moduleName: config.moduleName, entry: config.esm5Dest, dest: config.umdDest, format: 'umd' }); // Create a minified UMD bundle using UglifyJS // TODO: re-add sorcery when we upgrade to Angular 5.x uglifyJsFile(config.umdDest, config.umdMinDest); } /** Creates a rollup bundle of a specified JavaScript file.*/ private async createRollupBundle(config: RollupBundleConfig) { const bundleOptions = { context: 'this', external: Object.keys(rollupGlobals), entry: config.entry, onwarn: (message: string) => { // TODO(jelbourn): figure out *why* rollup warns about certain symbols not being found // when those symbols don't appear to be in the input file in the first place. if (/but never used/.test(message)) { return false; } console.warn(message); }, plugins: [ rollupRemoveLicensesPlugin, ] }; const writeOptions = { // Keep the moduleId empty because we don't want to force developers to a specific moduleId. moduleId: '', moduleName: config.moduleName || 'ng.material', banner: buildConfig.licenseBanner, format: config.format, dest: config.dest, globals: rollupGlobals, sourceMap: true }; // For UMD bundles, we need to adjust the `external` bundle option in order to include // all necessary code in the bundle. if (config.format === 'umd') { bundleOptions.plugins.push(rollupNodeResolutionPlugin()); // For all UMD bundles, we want to exclude tslib from the `external` bundle option so that // it is inlined into the bundle. let external = Object.keys(rollupGlobals); external.splice(external.indexOf('tslib'), 1); // If each secondary entry-point is re-exported at the root, we want to exclude those // secondary entry-points from the rollup globals because we want the UMD for the // primary entry-point to include *all* of the sources for those entry-points. if (this.buildPackage.exportsSecondaryEntryPointsAtRoot && config.moduleName === `ng.${this.buildPackage.name}`) { const importRegex = new RegExp(`@angular/${this.buildPackage.name}/.+`); external = external.filter(e => !importRegex.test(e)); // Use the rollup-alias plugin to map imports of the form `@angular/material/button` // to the actual file location so that rollup can resolve the imports (otherwise they // will be treated as external dependencies and not included in the bundle). bundleOptions.plugins.push( rollupAlias(this.getResolvedSecondaryEntryPointImportPaths(config.dest))); } bundleOptions.external = external; } return rollup.rollup(bundleOptions).then((bundle: any) => bundle.write(writeOptions)); } /** * Gets mapping of import aliases (e.g. `@angular/material/button`) to the path of the es5 * bundle output. * @param bundleOutputDir Path to the bundle output directory. * @returns Map of alias to resolved path. */ private getResolvedSecondaryEntryPointImportPaths(bundleOutputDir: string) { return this.buildPackage.secondaryEntryPoints.reduce((map, p) => { map[`@angular/${this.buildPackage.name}/${p}`] = join(dirname(bundleOutputDir), this.buildPackage.name, `${p}.es5.js`); return map; }, {} as {[key: string]: string}); } } /** Configuration for creating library bundles. */ interface BundlesConfig { entryFile: string; esm5EntryFile: string; moduleName: string; esm2015Dest: string; esm5Dest: string; umdDest: string; umdMinDest: string; } /** Configuration for creating a bundle via rollup. */ interface RollupBundleConfig { entry: string; dest: string; format: string; moduleName: string; }