diff --git a/src/builder/bundle/index.ts b/src/builder/bundle/index.ts index 548a2d54..ce74506a 100644 --- a/src/builder/bundle/index.ts +++ b/src/builder/bundle/index.ts @@ -31,7 +31,9 @@ interface IBundleOpts { incremental?: boolean; } -function bundle(opts: Omit): Promise; +function bundle( + opts: Omit, +): Promise; function bundle(opts: IBundleOpts): Promise; async function bundle(opts: IBundleOpts): Promise { const enableCache = process.env.FATHER_CACHE !== 'none'; @@ -68,7 +70,6 @@ async function bundle(opts: IBundleOpts): Promise { devtool: config.sourcemap && 'source-map', externals: config.externals, outputPath: config.output.path, - // postcss config extraPostCSSPlugins, postcssLoader, @@ -80,7 +81,7 @@ async function bundle(opts: IBundleOpts): Promise { // compatible with IE11 by default targets: getBundleTargets(config), - jsMinifier: JSMinifier.terser, + jsMinifier: config.jsMinifier, cssMinifier: CSSMinifier.cssnano, extraBabelIncludes: [/node_modules/], @@ -165,21 +166,21 @@ async function bundle(opts: IBundleOpts): Promise { // enable webpack persistent cache ...(enableCache ? { - cache: { - buildDependencies: opts.buildDependencies, - }, - } + cache: { + buildDependencies: opts.buildDependencies, + }, + } : {}), // collect close handlers for watch mode ...(opts.watch ? { - onBuildComplete({ isFirstCompile, close }: any) { - if (isFirstCompile) closeHandlers.push(close); - // log for watch mode - else logStatus(); - }, - } + onBuildComplete({ isFirstCompile, close }: any) { + if (isFirstCompile) closeHandlers.push(close); + // log for watch mode + else logStatus(); + }, + } : {}), disableCopy: true, }); diff --git a/src/builder/config.ts b/src/builder/config.ts index 38bb47d0..e8253471 100644 --- a/src/builder/config.ts +++ b/src/builder/config.ts @@ -1,3 +1,4 @@ +import { JSMinifier } from '@umijs/bundler-webpack/dist/types'; import { winPath } from '@umijs/utils'; import { Minimatch } from 'minimatch'; import path from 'path'; @@ -24,6 +25,7 @@ export interface IBundleConfig Omit { type: IFatherBuildTypes.BUNDLE; bundler: 'webpack'; + jsMinifier: JSMinifier; entry: string; output: { filename: string; @@ -111,55 +113,80 @@ export function normalizeUserConfig( const entryConfig = umd.entry; const output = typeof umd.output === 'object' ? umd.output : { path: umd.output }; - const bundleConfig: Omit = { - type: IFatherBuildTypes.BUNDLE, - bundler: 'webpack', - ...baseConfig, + const bundleConfig: Omit = + { + type: IFatherBuildTypes.BUNDLE, + bundler: 'webpack', + ...baseConfig, - // override base configs from umd config - ...umd, - - // generate default output - output: { - // default to generate filename from package name - filename: - output.filename || `${getAutoBundleFilename(pkg.name)}.min.js`, - // default to output dist - path: output.path || 'dist/umd', - }, - }; + // override base configs from umd config + ...umd, + }; if (typeof entryConfig === 'object') { - // extract multiple entries to single configs - Object.keys(entryConfig).forEach((entry) => { - const outputConfig = entryConfig[entry].output; + Object.entries(entryConfig).forEach(([entry, singleConfig]) => { + const outputConfig = singleConfig.output; const entryOutput = typeof outputConfig === 'object' ? outputConfig : { path: outputConfig }; - configs.push({ + const unminifiedConfig = { ...bundleConfig, - - // override all configs from entry config - ...entryConfig[entry], + ...singleConfig, entry, + jsMinifier: JSMinifier.none, + sourcemap: false, + output: { + filename: entryOutput.filename || `${path.parse(entry).name}.js`, + path: entryOutput.path || output.path || 'dist/umd', + }, + }; - // override output + const minifiedConfig = { + ...bundleConfig, + ...singleConfig, + entry, + jsMinifier: JSMinifier.terser, output: { filename: entryOutput.filename || `${path.parse(entry).name}.min.js`, - path: entryOutput.path || bundleConfig.output.path, + path: entryOutput.path || output.path || 'dist/umd', }, - }); + }; + + if (singleConfig.generateUnminified) { + configs.push(unminifiedConfig, minifiedConfig); + } else { + configs.push(minifiedConfig); + } }); } else { - // generate single entry to single config + const defaultEntry = entryConfig || 'src/index'; + const defaultOutput = { + filename: + output.filename || `${getAutoBundleFilename(pkg.name)}.min.js`, + path: output.path || 'dist/umd', + }; + + if (umd.generateUnminified) { + configs.push({ + ...bundleConfig, + entry: defaultEntry, + jsMinifier: JSMinifier.none, + sourcemap: false, + output: { + filename: `${getAutoBundleFilename(pkg.name)}.js`, + path: output.path || 'dist/umd', + }, + }); + } + configs.push({ ...bundleConfig, - - // default to bundle src/index - entry: entryConfig || 'src/index', + entry: defaultEntry, + jsMinifier: JSMinifier.terser, + output: defaultOutput, }); } } diff --git a/src/features/configPlugins/schema.ts b/src/features/configPlugins/schema.ts index dc19d91b..1bfc9dd4 100644 --- a/src/features/configPlugins/schema.ts +++ b/src/features/configPlugins/schema.ts @@ -64,6 +64,7 @@ export function getSchemas(): Record any> { Joi.string(), Joi.array(), ), + generateUnminified: Joi.boolean().optional(), chainWebpack: Joi.function().optional(), extractCSS: Joi.boolean().optional(), name: Joi.string().optional(), diff --git a/src/types.ts b/src/types.ts index 8d8f2557..7de151e4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -221,6 +221,13 @@ export interface IFatherBundleConfig extends IFatherBaseConfig { * configure less variables */ theme?: Record; + + /** + * output unminified js file + * @default false + * @note When set to true, unminified js file will be generated in the same directory without sourcemap. + */ + generateUnminified?: boolean; } export interface IFatherPreBundleConfig {