diff --git a/package.json b/package.json index bb28745..2b08bd3 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "@rollup/plugin-json": "4.0.0", "@rollup/plugin-node-resolve": "7.0.0", "@teclone/node-utils": "1.0.4", - "@teclone/utils": "2.14.3", + "@teclone/utils": "2.16.1", "args": "5.0.1", "chalk": "3.0.0", "rollup": "1.27.9", diff --git a/src/@types/index.d.ts b/src/@types/index.d.ts index 2ab4a01..58d94c6 100644 --- a/src/@types/index.d.ts +++ b/src/@types/index.d.ts @@ -11,6 +11,21 @@ export interface CommonConfig { */ outDir?: string; + /** + * defines specific string of file patterns to process for the build + */ + include?: (string | RegExp)[]; + + /** + * defines specific string of file patterns to ignore for the build. + */ + exclude?: (string | RegExp)[]; + + /** + * defines specific string of file patterns to copy over for the builds. + */ + assets?: (string | RegExp)[]; + /** * boolean indicating if the interop rollup setting should be enabled for the build */ @@ -26,21 +41,21 @@ export interface CJSConfig extends CommonConfig { /** * build format to use. must be 'cjs' */ - format: 'cjs'; + format?: 'cjs'; } export interface ESMConfig extends CommonConfig { /** * build format to use. must be 'esm' */ - format: 'esm'; + format?: 'esm'; } export interface DistConfig extends CommonConfig { /** * build format to use. defaults to 'iife' */ - format: 'iife' | 'umd'; + format?: 'iife' | 'umd'; /** * list of modules to regard as external, defaults to empty array @@ -49,116 +64,6 @@ export interface DistConfig extends CommonConfig { } export interface Config { - /** - * plugins to apply - */ - plugins: Plugin[]; - - /** - * defines code src directory, defaults to 'src' - */ - srcDir: string; - - /** - * defaults to index.js - */ - entryFile: string; - - /** - * defaults to project package name camel-cased - */ - moduleName: string; - - /** - * allowed file extensions. defaults to .js, .ts - */ - extensions: string[]; - - /** - * defines specific string of file patterns to process for all builds - */ - include: (string | RegExp)[]; - - /** - * defines specific string of file patterns to ignore for all builds. - */ - exclude: (string | RegExp)[]; - - /** - * defines specific string of file patterns to copy over for all builds. - */ - assets: (string | RegExp)[]; - - /** - * boolean indicating if the interop rollup setting should be enabled for all builds - */ - interop: boolean; - - /** - * boolean indicating if sourcemap should be generated for all builds, - * can be true, false, or 'inline' - */ - sourcemap: true | false | 'inline'; - - /** - * boolean indicating if rollup plugin terser should be applied to the build, when in production mode - * default to false - */ - uglify: boolean; - - /** - * rollup watch config - */ - watch: object; - - /** - * rollup globals config - */ - globals: object; - - /** - * defines config settings for generating distributed codes - */ - distConfig: DistConfig; - - /** - * defines config settings for generating cjs files - */ - cjsConfig: CJSConfig; - - /** - * defines config settings for generating esm files - */ - esmConfig: ESMConfig; -} - -interface UserDistConfig extends CommonConfig { - /** - * build format to use. defaults to 'iife' - */ - format?: 'iife' | 'umd'; - - /** - * list of modules to regard as external, defaults to empty array - */ - externals?: string[]; -} - -interface UserCJSConfig extends CommonConfig { - /** - * build format to use. must be 'cjs' - */ - format?: 'cjs'; -} - -interface UserESMConfig extends CommonConfig { - /** - * build format to use. must be 'esm' - */ - format?: 'esm'; -} - -export interface UserConfig { /** * plugins to apply */ @@ -175,23 +80,22 @@ export interface UserConfig { entryFile?: string; /** - * defaults to project package.json name camel-cased + * defaults to project package name camel-cased */ moduleName?: string; /** - * allowed file extensions. defaults to .js, .ts, .jsx, .tsx + * allowed file extensions. defaults to .js, .ts */ extensions?: string[]; /** - * defines specific string of file patterns to process for all builds. defaults to everything matching the file extensions within - * the src directory + * defines specific string of file patterns to process for all builds */ include?: (string | RegExp)[]; /** - * defines specific string of file patterns to ignore for all builds. defaults to nothing + * defines specific string of file patterns to ignore for all builds. */ exclude?: (string | RegExp)[]; @@ -218,8 +122,7 @@ export interface UserConfig { uglify?: boolean; /** - * rollup watch config, you must pass in the --watch command line argument for this to - * work + * rollup watch config */ watch?: object; @@ -229,19 +132,19 @@ export interface UserConfig { globals?: object; /** - * defines config settings for generating distributed codes. + * defines config settings for generating distributed codes */ - distConfig?: UserDistConfig; + distConfig?: DistConfig; /** - * defines config settings for generating cjs codes. + * defines config settings for generating cjs files */ - cjsConfig?: UserCJSConfig; + cjsConfig?: CJSConfig; /** - * defines config settings for generating esm codes. + * defines config settings for generating esm files */ - esmConfig?: UserESMConfig; + esmConfig?: ESMConfig; } export interface Module { @@ -286,7 +189,7 @@ export interface ModuleFiles { } export interface GeneralConfig { - config?: UserConfig; + config?: Config; babelConfig?: { presets?: any[]; plugins?: any[]; diff --git a/src/config.ts b/src/config.ts index 0e73540..def68da 100644 --- a/src/config.ts +++ b/src/config.ts @@ -64,12 +64,16 @@ export const config: Config = { */ enabled: true, + exclude: [], + + include: [], + /** * defines output directory */ outDir: 'build', - format: 'cjs' + format: 'cjs', }, /** @@ -81,12 +85,16 @@ export const config: Config = { */ enabled: true, + exclude: [], + + include: [], + /** * defines output directory */ outDir: 'build/esm', - format: 'esm' + format: 'esm', }, /** @@ -98,6 +106,10 @@ export const config: Config = { */ enabled: false, + exclude: [], + + include: [], + /** * defines output directory */ @@ -108,6 +120,6 @@ export const config: Config = { */ format: 'iife', - externals: [] - } + externals: [], + }, }; diff --git a/src/modules/Bundler.ts b/src/modules/Bundler.ts index b8efd85..49a0649 100644 --- a/src/modules/Bundler.ts +++ b/src/modules/Bundler.ts @@ -3,7 +3,6 @@ import * as fs from 'fs'; import { copy, isString, camelCase } from '@teclone/utils'; import { Config, - UserConfig, CommonConfig, DistConfig, Module, @@ -106,7 +105,7 @@ class Bundler { /** * resolves the config object */ - private resolveConfig(entryPath: string, config: UserConfig): Config { + private resolveConfig(entryPath: string, config: Config): Config { const packageFile = this.loadFile(entryPath, 'package.json'); const resolvedConfig: Config = copy({}, defaultConfig, config as Config); @@ -121,12 +120,23 @@ class Bundler { this.mergeConfig(prop, resolvedConfig, resolvedConfig.esmConfig); }); + const { esmConfig, distConfig, cjsConfig } = resolvedConfig; + /** * resolve regex fields */ REGEX_FIELDS.forEach(field => { - const values = resolvedConfig[field] as Array; - resolvedConfig[field] = values.map(this.resolveRegex); + esmConfig[field] = (resolvedConfig[field] as Array) + .concat(esmConfig[field] as Array) + .map(this.resolveRegex); + + distConfig[field] = (resolvedConfig[field] as Array) + .concat(distConfig[field] as Array) + .map(this.resolveRegex); + + cjsConfig[field] = (resolvedConfig[field] as Array) + .concat(cjsConfig[field] as Array) + .map(this.resolveRegex); }); return resolvedConfig; @@ -211,19 +221,16 @@ class Bundler { }); } - private async getModulesFiles(): Promise { - const startAt = path.resolve(this.entryPath, this.config.srcDir); - const config = this.config; - - const modules = await this.getModules( - [], - startAt, - config.entryFile, - config.moduleName, - '', - config.extensions, - ); - + /** + * assembles files for the current build + * @param config + * @param buildConfig + */ + private getModulesFiles( + modules: Module[], + config: Config, + buildConfig: CJSConfig | ESMConfig | DistConfig, + ): ModuleFiles { const result: ModuleFiles = { assetFiles: [], buildFiles: [], @@ -241,12 +248,12 @@ class Bundler { src = oldRelativePath; if (isTypeDefinitionFile && config.cjsConfig.enabled) { result.typeDefinitionFiles.push(current); - } else if (isAssetFile && config.assets.some(regexMatches)) { + } else if (isAssetFile && buildConfig.assets.some(regexMatches)) { result.assetFiles.push(current); } else if ( isBuildFile && - (config.include.length === 0 || config.include.some(regexMatches)) && - (config.exclude.length === 0 || !config.exclude.some(regexMatches)) + (buildConfig.include.length === 0 || buildConfig.include.some(regexMatches)) && + (buildConfig.exclude.length === 0 || !buildConfig.exclude.some(regexMatches)) ) { result.buildFiles.push(current); } @@ -254,76 +261,82 @@ class Bundler { return result; } - runBuild(moduleFiles: ModuleFiles, config: DistConfig | CJSConfig | ESMConfig) { + /** + * runs a specific build + * @param modules + * @param mainConfig + * @param config + */ + runBuild( + modules: Module[], + mainConfig: Config, + config: DistConfig | CJSConfig | ESMConfig, + ) { + const moduleFiles = this.getModulesFiles(modules, mainConfig, config); const promises: Array> = []; const { assetFiles, typeDefinitionFiles, buildFiles } = moduleFiles; - if (config.enabled) { - log(chalk.yellow(`generating ${config.format} builds...\n`)); - const plugins = getRollupPlugins( - this.config, - this.generalConfig, - config.format === 'esm', - ); - const external = - config.format === 'iife' || config.format === 'umd' - ? config.externals - : allExternal; - - buildFiles.forEach(({ filePath, newRelativePath, oldRelativePath, name }) => { - const onError = ex => { - console.log(`Error occured while bundling ${oldRelativePath}`, ex.message); - }; - - const out = path.resolve(this.entryPath, config.outDir, newRelativePath); - promises.push( - rollup({ - input: filePath, - plugins, - external, + log(chalk.yellow(`generating ${config.format} builds...\n`)); + + const plugins = getRollupPlugins( + this.config, + this.generalConfig, + config.format === 'esm', + ); + const external = + config.format === 'iife' || config.format === 'umd' + ? config.externals + : allExternal; + + buildFiles.forEach(({ filePath, newRelativePath, oldRelativePath, name }) => { + const onError = ex => { + console.log(`Error occured while bundling ${oldRelativePath}`, ex.message); + }; + + const out = path.resolve(this.entryPath, config.outDir, newRelativePath); + promises.push( + rollup({ + input: filePath, + plugins, + external, + }) + .then(bundler => { + return bundler + .write({ + file: out, + format: config.format, + interop: config.interop, + sourcemap: config.sourcemap, + name, + }) + .then(() => { + if (this.bundlerOptions.generateOutputLogs) { + log(chalk.green(`${oldRelativePath} ... ${out} \n`)); + } + return null; + }); }) - .then(bundler => { - return bundler - .write({ - file: out, - format: config.format, - interop: config.interop, - sourcemap: config.sourcemap, - name, - }) - .then(() => { - if (this.bundlerOptions.generateOutputLogs) { - log(chalk.green(`${oldRelativePath} ... ${out} \n`)); - } - return null; - }); - }) - .catch(onError), - ); - }); + .catch(onError), + ); + }); - assetFiles.forEach(assetFile => { - promises.push( - this.copyFile( - assetFile.filePath, - path.resolve(this.entryPath, config.outDir, assetFile.oldRelativePath), - ), - ); - }); + assetFiles.forEach(assetFile => { + promises.push( + this.copyFile( + assetFile.filePath, + path.resolve(this.entryPath, config.outDir, assetFile.oldRelativePath), + ), + ); + }); - typeDefinitionFiles.forEach(typeDefinitionFile => { - promises.push( - this.copyFile( - typeDefinitionFile.filePath, - path.resolve( - this.entryPath, - config.outDir, - typeDefinitionFile.oldRelativePath, - ), - ), - ); - }); - } + typeDefinitionFiles.forEach(typeDefinitionFile => { + promises.push( + this.copyFile( + typeDefinitionFile.filePath, + path.resolve(this.entryPath, config.outDir, typeDefinitionFile.oldRelativePath), + ), + ); + }); return Promise.all(promises); } @@ -332,12 +345,32 @@ class Bundler { * runs the process */ async process() { - // assemble module files - const moduleFiles = await this.getModulesFiles(); + const config = this.config; + const startAt = path.resolve(this.entryPath, config.srcDir); - await this.runBuild(moduleFiles, this.config.cjsConfig); - await this.runBuild(moduleFiles, this.config.esmConfig); - await this.runBuild(moduleFiles, this.config.distConfig); + const modules = await this.getModules( + [], + startAt, + config.entryFile, + config.moduleName, + '', + config.extensions, + ); + + //run cjs build + if (config.cjsConfig.enabled) { + await this.runBuild(modules, config, config.cjsConfig); + } + + // run esm build + if (config.esmConfig.enabled) { + await this.runBuild(modules, config, config.esmConfig); + } + + // run dist build + if (config.distConfig.enabled) { + await this.runBuild(modules, config, config.distConfig); + } } } diff --git a/yarn.lock b/yarn.lock index 0c9a288..c92728d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1207,10 +1207,10 @@ dependencies: defer-to-connect "^1.0.1" -"@teclone/global@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@teclone/global/-/global-1.0.0.tgz#3c25b75514d555ec6d3f1dba03f85d942b3939e2" - integrity sha512-U20DRE3Hn7euijxlBfwUwGS7uSA7Bqi86atyK2oLpzdRkXZgldH4skFq0wtKBurBIyMwB5Rg7tohLjwyosUIEw== +"@teclone/global@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@teclone/global/-/global-1.1.0.tgz#a7792fcf57dee54bbd59e8251c01f03697e74b34" + integrity sha512-r7qqDd1hBp4hE6mO9hWSHn+3JyUOOQiUO12GhKBowYq2w8fGWY90d/N62FpFXtBDMh/kLGwqho3Qn4bR1gJl/w== "@teclone/node-utils@1.0.4": version "1.0.4" @@ -1220,12 +1220,12 @@ "@babel/plugin-transform-runtime" "7.4.3" "@babel/runtime" "7.4.3" -"@teclone/utils@2.14.3": - version "2.14.3" - resolved "https://registry.yarnpkg.com/@teclone/utils/-/utils-2.14.3.tgz#06e6999a0719e1769243836b688fef291b94e072" - integrity sha512-8FMfVUjhwypQwDfnwUkYABXLPK0WDBzkYqUQow4axK0BJp9mlVfqvEWMve6vO2Ertk9mV+Tvv+hxiV2vYhFogA== +"@teclone/utils@2.16.1": + version "2.16.1" + resolved "https://registry.yarnpkg.com/@teclone/utils/-/utils-2.16.1.tgz#df42af0c9598f1c3c10669051e7af6475243602a" + integrity sha512-rVULXc0KXpMBH3grNGntzcAlHygH1RsXykWcISnXcxyILKdvWrNO7oPhgrufYgYE+Ll/r9ipq6WXX1z8FJV09w== dependencies: - "@teclone/global" "1.0.0" + "@teclone/global" "1.1.0" "@tootallnate/once@1": version "1.0.0"