const path = require('path') const nodeResolve = require('@rollup/plugin-node-resolve').default const alias = require('@rollup/plugin-alias') const dts = require('rollup-plugin-dts').default const sourceMapLoader = require('rollup-plugin-sourcemaps') const postcss = require('rollup-plugin-postcss') const { checkNoSymlinks, buildBanner } = require('./scripts/lib/new') const { externalizeStylesheets, externalizeNonRelative, injectReleaseDateAndVersion, buildAliasMap, removeStylesheetImports, removeEmptyImports } = require('./scripts/lib/new-rollup') /* needs tsc to run first but needs symlinks killed also compiles from TSC files */ const { publicPackageStructs } = require('./scripts/lib/package-index') checkNoSymlinks(publicPackageStructs) let pkgsWithBrowserGlobal = [] let browserGlobalByPkg = {} for (let struct of publicPackageStructs) { if (struct.meta.browserGlobal) { pkgsWithBrowserGlobal.push(struct) browserGlobalByPkg[struct.name] = struct.meta.browserGlobal } } browserGlobalByPkg['@fullcalendar/common'] = 'FullCalendar' const THIRD_PARTY_BROWSER_GLOBALS = { // preact: 'Preact', // we actually want this inlined rrule: 'rrule', moment: 'moment', 'moment-timezone': 'moment', luxon: 'luxon', 'ical.js': 'ICAL' } let allGlobals = { ...THIRD_PARTY_BROWSER_GLOBALS, ...browserGlobalByPkg } let externalList = Object.keys(allGlobals) let externalListNoCommon = externalList.filter((name) => name !== '@fullcalendar/common') let aliasMap = buildAliasMap(publicPackageStructs) module.exports = [ // for JS (ESM) ...publicPackageStructs.map((struct) => { return { input: path.join(struct.dir, struct.mainTscJs), output: { format: 'es', file: path.join(struct.dir, struct.mainDistJs), sourcemap: true, banner: buildBanner(struct.isPremium) }, plugins: [ externalizeVDom('.js'), externalizeNonRelative(), sourceMapLoader(), // load from transpiled-via-tsc JS files postcss({ // will use postcss.config.js extract: true }), transplantCss(struct.mainName), injectReleaseDateAndVersion() ] } }), // for JS (CJS) ...publicPackageStructs.map((struct) => { return { input: path.join(struct.dir, struct.mainTscJs), output: [{ format: 'cjs', exports: 'named', file: path.join(struct.dir, struct.mainDistJs.replace('.js', '.cjs.js')), banner: buildBanner(struct.isPremium) }], plugins: [ externalizeVDom('.cjs'), externalizeNonRelative(), removeStylesheetImports(), injectReleaseDateAndVersion(), removeEmptyImports() // because of removeStylesheetImports and CJS ] } }), // vdom from @fullcalendar/core-preact { input: 'packages/core/tsc/vdom.js', output: [ { format: 'cjs', exports: 'named', file: 'packages/core/vdom.cjs.js' }, { format: 'esm', file: 'packages/core/vdom.js' } ], plugins: [ externalizeNonRelative('@fullcalendar/core-preact'), nodeResolve() ] }, { input: 'packages/common/tsc/vdom.js', output: [ { format: 'cjs', exports: 'named', file: 'packages/common/vdom.cjs.js' }, { format: 'esm', file: 'packages/common/vdom.js' } ], plugins: [ externalizeNonRelative('@fullcalendar/core-preact'), nodeResolve() ] }, // for global variable JS ...pkgsWithBrowserGlobal.map((struct) => { return { input: path.join(struct.dir, struct.mainGlobalTscJs), external: struct.name === '@fullcalendar/core' ? externalListNoCommon : externalList, // if core, inline common output: { format: 'iife', name: struct.meta.browserGlobal, exports: 'named', file: path.join(struct.dir, struct.mainDistJs.replace('.js', '.global.js')), banner: buildBanner(struct.isPremium), globals: allGlobals }, plugins: [ // same plugins that rollup.bundle.js uses removeStylesheetImports(), alias({ entries: aliasMap // TODO: for packages like @fullcalendar/common which will be inlined }), nodeResolve(), // for tslib injectReleaseDateAndVersion() ] } }), // for DTS ...publicPackageStructs.map((struct) => { return { input: path.join(struct.dir, struct.mainTscDts), output: { format: 'es', file: path.join(struct.dir, struct.mainDistDts), }, plugins: [ fixDtsCodeIn(), ensurePremiumCommonAmbient(), externalizeVDom(''), externalizeStylesheets(), externalizeNonRelative(), dts(), fixDtsCodeOut() ] } }) ] function transplantCss(fileName) { // fileName w/o extension let hasCss = false return { resolveId(id, importer) { if (/^\./.test(id) && /\.css$/.test(id)) { // relative stylesheet hasCss = true let filePath = path.join(importer, '..', id) filePath = filePath.replace('/tsc/', '/src/') // not very robust!!! return filePath } }, intro() { if (hasCss) { return `import './${fileName}.css';` } else { return '' } } } } function externalizeVDom(addExtension) { return { resolveId(id, importer) { if (/\/vdom$/.test(id) || id.match(/^(preact|react|react-dom)$/)) { if ( importer.match('packages/common') || importer.match('packages/core') ) { return { id: './vdom' + (addExtension || ''), external: true, moduleSideEffects: true } } else { return { id: '@fullcalendar/common', external: true, moduleSideEffects: true } } } } } } function ensurePremiumCommonAmbient() { return { resolveId(id) { if (id === '@fullcalendar/premium-common') { return { id, external: true, moduleSideEffects: true } } } } } function fixDtsCodeIn() { return { /* fix problem with tsc outputting random imports like this: import("../../../packages/common/src/plugin-system-struct") import("../../../packages/common/src/main") relevant tickets: https://github.com/microsoft/TypeScript/issues/38111 - "Declaration emit reveals paths within dependency that were not referred to in the source file" */ resolveId(id, importer) { if (importer && id.match('packages/common')) { return { id: '@fullcalendar/common', external: true } } } } } function fixDtsCodeOut() { return { renderChunk(code) { // remove sourcemap comments and /// code = code.replace(/\/\/.*/g, '') /* tsc, for classes that have superclasses with getter methods, sometimes reference the return type like this: import("@fullcalendar/common/tsc/whatever").Something (and this is from WITHIN the @fullcalendar/common package) possible BUG with this hack: playing weird with TS triple-slash references relevant tickets: https://github.com/microsoft/TypeScript/issues/38111 - "Declaration emit reveals paths within dependency that were not referred to in the source file" */ code = code.replace(/(['"]@fullcalendar\/[^'"]+)\/[^'"]+(['"])/g, function(m0, m1, m2) { return m1 + m2 }) /* sometimes tsc fully resolved generic vdom declarations to preact, which makes the VNode a thing (which it shouldn't be) relevant tickets: https://github.com/microsoft/TypeScript/issues/37151 - "Declaration emit should not inline type definitions" */ code = code.replace(/VNode/g, 'VNode') if (/\b(p?react)\b/.test(code)) { throw new Error('BAD reference to preact/react in DTS') } return code } } }