[READ-ONLY] Mirror of https://github.com/danielroe/siroc. Zero-config build tooling for Node
bundle node package rollup typescript
0

Configure Feed

Select the types of activity you want to include in your feed.

feat: improve rollup config generation

Daniel Roe (Jun 7, 2020, 2:11 PM +0100) 0e322bb6 5a4db66d

+131 -42
+14
src/utils.ts
··· 42 42 }) 43 43 return groups 44 44 } 45 + 46 + type ExcludeNullable<T extends Record<string, any>> = { 47 + [P in keyof T]: NonNullable<T[P]> 48 + } 49 + 50 + export const includeDefinedProperties = <T extends Record<string, any>>( 51 + options: T 52 + ) => 53 + Object.fromEntries( 54 + // eslint-disable-next-line 55 + Object.entries(options).filter(([_, value]) => value !== undefined) 56 + ) as ExcludeNullable<T> 57 + 58 + export const includeIf = <T>(test: any, item: T) => (test ? [item] : [])
+2
src/config/package-json.ts
··· 23 23 author?: PackageJsonPerson 24 24 contributors?: PackageJsonPerson[] 25 25 files?: string[] 26 + types?: string 26 27 main?: string 28 + module?: string 27 29 bin?: string | Record<string, string> 28 30 browser?: string 29 31 man?: string | string[]
+79 -27
src/config/rollup.ts
··· 1 - import path from 'path' 2 - import { readJSONSync } from 'fs-extra' 1 + import { resolve, dirname, basename } from 'path' 3 2 4 3 import aliasPlugin from '@rollup/plugin-alias' 5 4 import commonjsPlugin from '@rollup/plugin-commonjs' ··· 8 7 import nodeResolvePlugin, { 9 8 RollupNodeResolveOptions, 10 9 } from '@rollup/plugin-node-resolve' 11 - 12 - import licensePlugin from 'rollup-plugin-license' 13 10 import defu from 'defu' 14 - 11 + import { readJSONSync } from 'fs-extra' 15 12 import type { OutputOptions, RollupOptions } from 'rollup' 13 + import dts from 'rollup-plugin-dts' 14 + import esbuild from 'rollup-plugin-esbuild' 15 + import licensePlugin from 'rollup-plugin-license' 16 16 17 - import type { RequireProperties } from '../utils' 17 + import { 18 + RequireProperties, 19 + includeDefinedProperties, 20 + includeIf, 21 + } from '../utils' 18 22 import { builtins } from './node-builtins' 19 23 import type { PackageJson } from './package-json' 24 + 25 + const __NODE_ENV__ = process.env.NODE_ENV 20 26 21 27 export interface NuxtRollupOptions { 22 28 rootDir?: string 23 29 replace?: Record<string, Replacement> 24 30 alias?: { [find: string]: string } 31 + /** 32 + * Explicit externals 33 + */ 25 34 externals?: (string | RegExp)[] 26 35 resolve?: RollupNodeResolveOptions 27 36 input?: string ··· 39 48 replace = {}, 40 49 alias = {}, 41 50 externals = [], 42 - resolve = { 51 + resolve: resolveOptions = { 43 52 resolveOnly: [/lodash/, /^((?!node_modules).)*$/], 53 + preferBuiltins: true, 44 54 }, 45 55 ...options 46 56 }: RollupOptions & NuxtRollupOptions, 47 57 pkg: RequireProperties<PackageJson, 'name'> 48 - ): NuxtRollupConfig { 49 - if (!pkg) { 50 - pkg = readJSONSync(path.resolve(rootDir, 'package.json')) 58 + ): NuxtRollupConfig[] { 59 + if (!pkg) pkg = readJSONSync(resolve(rootDir, 'package.json')) 60 + 61 + const name = basename(pkg.name.replace('-edge', '')) 62 + 63 + const external = [ 64 + // Dependencies that will be installed alongside the package 65 + ...Object.keys(pkg.dependencies || {}), 66 + // Builtin node modules 67 + ...builtins, 68 + ...externals, 69 + ] 70 + 71 + const getFilenames = (filename: string | undefined, defaultSuffix = '') => { 72 + return { 73 + dir: filename 74 + ? resolve(rootDir, filename ? dirname(filename) : 'dist') 75 + : resolve(rootDir, 'dist'), 76 + entryFileNames: filename 77 + ? basename(filename) 78 + : `${name}${defaultSuffix}.js`, 79 + chunkFileNames: filename 80 + ? `${basename(filename)}-[name].js` 81 + : `${name}-[name]${defaultSuffix}.js`, 82 + } as const 51 83 } 52 84 53 - const name = path.basename(pkg.name.replace('-edge', '')) 54 - 55 - return defu({}, options, { 56 - input: path.resolve(rootDir, input), 85 + const baseConfig: NuxtRollupConfig = defu({}, options, { 86 + input: resolve(rootDir, input), 57 87 output: { 58 - dir: path.resolve(rootDir, 'dist'), 59 - entryFileNames: `${name}.js`, 60 - chunkFileNames: `${name}-[name].js`, 88 + ...getFilenames(pkg.main), 61 89 format: 'cjs', 62 90 preferConst: true, 63 91 }, 64 - external: [ 65 - // Dependencies that will be installed alongise with the nuxt package 66 - ...Object.keys(pkg.dependencies || {}), 67 - // Builtin node modules 68 - ...builtins, 69 - // Explicit externals 70 - ...externals, 71 - ], 92 + external, 72 93 plugins: [ 73 94 aliasPlugin({ 74 95 entries: alias, ··· 77 98 exclude: 'node_modules/**', 78 99 delimiters: ['', ''], 79 100 values: { 80 - __NODE_ENV__: process.env.NODE_ENV || '', 101 + ...includeDefinedProperties({ __NODE_ENV__ }), 81 102 ...replace, 82 103 }, 83 104 }), 84 - nodeResolvePlugin(resolve), 105 + nodeResolvePlugin(resolveOptions), 85 106 commonjsPlugin({ include: /node_modules/ }), 107 + esbuild({ 108 + watch: process.argv.includes('--watch'), 109 + minify: process.env.NODE_ENV === 'production', 110 + target: 'es2018', 111 + }), 86 112 jsonPlugin(), 87 113 licensePlugin({ 88 114 banner: [ ··· 99 125 }), 100 126 ].concat(plugins), 101 127 }) 128 + 129 + return [ 130 + baseConfig, 131 + ...includeIf(pkg.module, { 132 + ...baseConfig, 133 + output: { 134 + ...getFilenames(pkg.module, '-es'), 135 + format: 'es' as const, 136 + }, 137 + }), 138 + ...includeIf(pkg.types, { 139 + input: baseConfig.input, 140 + output: { 141 + file: resolve(rootDir, 'dist', 'index.d.ts'), 142 + format: 'es' as const, 143 + }, 144 + plugins: [ 145 + jsonPlugin(), 146 + dts({ 147 + compilerOptions: { 148 + allowJs: true, 149 + }, 150 + }), 151 + ], 152 + }), 153 + ] 102 154 }
+1 -1
src/package/hooks.ts
··· 8 8 config: RequireProperties<NuxtRollupOptions, 'alias' | 'replace'> 9 9 } 10 10 'build:extendRollup': { 11 - rollupConfig: NuxtRollupConfig 11 + rollupConfig: NuxtRollupConfig[] 12 12 } 13 13 'build:done': { bundle: RollupBuild } 14 14 }
+29 -12
src/package/index.ts
··· 1 - import { resolve } from 'path' 1 + import { dirname, resolve } from 'path' 2 2 import { existsSync, readJSONSync, writeFile, copy, remove } from 'fs-extra' 3 3 4 4 import consola, { Consola } from 'consola' ··· 7 7 import sortPackageJson from 'sort-package-json' 8 8 9 9 import type { PackageJson } from '../config/package-json' 10 - import { rollupConfig, NuxtRollupOptions } from '../config/rollup' 10 + import { 11 + rollupConfig, 12 + NuxtRollupOptions, 13 + NuxtRollupConfig, 14 + } from '../config/rollup' 11 15 import { sortObjectKeys, tryRequire, RequireProperties, glob } from '../utils' 12 16 import type { PackageHooks, HookOptions } from './hooks' 13 17 ··· 191 195 return packages 192 196 } 193 197 198 + async removeBuildFolders(config: NuxtRollupConfig[]) { 199 + const directories = new Set<string>() 200 + config.forEach(conf => { 201 + directories.add(conf.output.dir || dirname(conf.output.file || '')) 202 + }) 203 + for (const dir of directories) { 204 + await remove(dir) 205 + } 206 + } 207 + 194 208 async build(_watch = false) { 195 209 // Prepare rollup config 196 210 const config: RequireProperties<NuxtRollupOptions, 'alias' | 'replace'> = { ··· 219 233 await this.callHook('build:extendRollup', { 220 234 rollupConfig: _rollupConfig, 221 235 }) 236 + 237 + await this.removeBuildFolders(_rollupConfig) 222 238 223 239 if (_watch) { 224 240 // Watch ··· 254 270 } else { 255 271 // Build 256 272 this.logger.info('Building bundle') 257 - try { 258 - const bundle = await rollup(_rollupConfig) 259 - if (_rollupConfig.output.dir) await remove(_rollupConfig.output.dir) 260 - await bundle.write(_rollupConfig.output) 273 + for (const config of _rollupConfig) { 274 + try { 275 + const bundle = await rollup(config) 276 + await bundle.write(config.output) 261 277 262 - this.logger.success('Bundle built') 263 - await this.callHook('build:done', { bundle }) 264 - } catch (err) { 265 - const formattedError = this.formatError(err) 266 - this.logger.error(formattedError) 267 - throw formattedError 278 + this.logger.success('Bundle built') 279 + await this.callHook('build:done', { bundle }) 280 + } catch (err) { 281 + const formattedError = this.formatError(err) 282 + this.logger.error(formattedError) 283 + throw formattedError 284 + } 268 285 } 269 286 } 270 287 }
+6 -2
src/cli/commands/build.ts
··· 2 2 3 3 import { Package } from '../../package' 4 4 5 - export async function build() { 5 + export interface BuildOptions { 6 + watch?: boolean 7 + } 8 + 9 + export async function build(options: BuildOptions = {}) { 6 10 // Read package at current directory 7 11 const rootPackage = new Package() 8 12 const workspacePackages = await rootPackage.getWorkspacePackages() 9 13 10 - const watch = process.argv.includes('--watch') 14 + const { watch } = options 11 15 consola.info('starting') 12 16 if (watch) consola.info('Watch mode') 13 17