diff --git a/core/webpack-compile/src/index.ts b/core/webpack-compile/src/index.ts index 9a016d554..95f9d51e7 100644 --- a/core/webpack-compile/src/index.ts +++ b/core/webpack-compile/src/index.ts @@ -9,12 +9,14 @@ export const compile = ({ webPack, presets, configPath, + outputFolder, }: CompileProps): Promise => { return runCompiler((compiler, callback) => compiler.run(callback), { webPack, mode: 'production', presets, configPath, + outputFolder, }); }; @@ -27,6 +29,7 @@ export const watch = ({ presets, configPath, watchOptions, + outputFolder, }: WatchProps): Promise => { return runCompiler( (compiler, callback) => compiler.watch({ ...watchOptions }, callback), @@ -35,6 +38,7 @@ export const watch = ({ mode: 'development', presets, configPath, + outputFolder, }, ); }; diff --git a/core/webpack-compile/src/types.ts b/core/webpack-compile/src/types.ts index 689a5b0fa..fd430a6f0 100644 --- a/core/webpack-compile/src/types.ts +++ b/core/webpack-compile/src/types.ts @@ -18,6 +18,9 @@ export interface CompileProps { * path to the configuration file e.g : '.storybook' */ configPath?: string; + + /** public output folder for the bundle */ + outputFolder?: string; } /** diff --git a/core/webpack-compile/src/utilities.ts b/core/webpack-compile/src/utilities.ts index 14ff7afba..7246883ea 100644 --- a/core/webpack-compile/src/utilities.ts +++ b/core/webpack-compile/src/utilities.ts @@ -18,7 +18,7 @@ export type CompileRunProps = CompileProps & { }; const createConfig = (options: CompileRunProps): webpack.Configuration => { - const { webPack, presets, configPath, mode } = options; + const { webPack, presets, configPath, mode, outputFolder } = options; const plugins = [ new LoaderPlugin({ config: configPath, @@ -48,6 +48,7 @@ const createConfig = (options: CompileRunProps): webpack.Configuration => { ...(webPack || {}), }, presets, + { outputFolder }, ); //add all the aliases to avoid double loading of packages diff --git a/core/webpack-configs/src/index.ts b/core/webpack-configs/src/index.ts index ec923e891..a867bcc08 100644 --- a/core/webpack-configs/src/index.ts +++ b/core/webpack-configs/src/index.ts @@ -4,12 +4,18 @@ import { react } from './react'; import { instrument } from './instrument'; import { reactDocgen } from './react-docgen'; import { reactDocgenTypescript } from './react-docgen-typescript'; -import { RuleOptions, RuleTypes, RuleType } from './types'; +import { + RuleOptions, + RuleTypes, + RuleType, + PresetOptions, + PresetType, +} from './types'; export * from './types'; export { WebpackConfiguration }; export const presetsFactory: { - [key: string]: WebpackConfiguration; + [key: string]: PresetType; } = { 'react-docgen-typescript': reactDocgenTypescript, 'react-docgen': reactDocgen, @@ -17,6 +23,14 @@ export const presetsFactory: { react, }; +const getConfigredPreset = (name: string, options?: PresetOptions) => { + const preset = presetsFactory[name]; + if (typeof preset === 'function') { + return preset(options); + } + return preset; +}; + const arrayMerge = (dest: any[], src: any[]) => { const srcCache = src ? [...src] : []; const destItems = dest @@ -55,17 +69,21 @@ const deepMerge = (dest: any, source: any) => { * expands the presets into webpack config * @param presets custom config */ -export const getWebpackConfig = (presets: RuleTypes): WebpackConfiguration => { +export const getWebpackConfig = ( + presets: RuleTypes, + options?: PresetOptions, +): WebpackConfiguration => { const result: WebpackConfiguration = presets.reduce( (acc: WebpackConfiguration, config: RuleType) => { if (typeof config === 'string') { - const f = presetsFactory[config]; - return deepMergeWithPresets(acc, f); + const p = getConfigredPreset(config, options); + return deepMergeWithPresets(acc, p); } if (config && (config as RuleOptions).name) { const name = (config as RuleOptions).name; - if (presetsFactory[name]) { - const r: WebpackConfiguration = presetsFactory[name]; + const p = getConfigredPreset(name, options); + if (p) { + const r: WebpackConfiguration = p; const o: WebpackConfiguration = (config as RuleOptions).config; const merged: WebpackConfiguration[] = deepMergeWithPresets(r, o); return deepMergeWithPresets(acc, merged); @@ -101,10 +119,11 @@ export const deepMergeWebpackConfig = ( export const mergeWebpackConfig = ( webPack?: WebpackConfiguration, presets?: RuleTypes, + options?: PresetOptions, ): WebpackConfiguration => { if (!presets) { return {}; } - const newConfig = getWebpackConfig(presets); + const newConfig = getWebpackConfig(presets, options); return deepMerge(webPack || {}, newConfig); }; diff --git a/core/webpack-configs/src/react/index.ts b/core/webpack-configs/src/react/index.ts index d6cb5f99f..6380b141e 100644 --- a/core/webpack-configs/src/react/index.ts +++ b/core/webpack-configs/src/react/index.ts @@ -1,6 +1,6 @@ -import { Configuration } from 'webpack'; +import { PresetType, PresetOptions } from '../types'; -export const react: Configuration = { +export const react: PresetType = (options?: PresetOptions) => ({ performance: { hints: false }, module: { rules: [ @@ -20,19 +20,14 @@ export const react: Configuration = { ], }, { - test: /\.(eot|md|svg|ico|jpg|jpeg|png|gif|ttf|woff|woff2|pdf|mp4|web|wav|mp3|m4a|aac|oga)$/, + test: /\.(eot|md|svg|ico|jpg|jpeg|png|gif|ttf|woff|woff2|pdf|mp4|web|wav|mp3|m4a|aac|oga)$/i, + exclude: [/node_modules/], loader: 'url-loader', options: { limit: 25000, - }, - }, - { - test: /\.(eot|md|svg|ico|jpg|jpeg|png|gif|ttf|woff|woff2|pdf|mp4|web|wav|mp3|m4a|aac|oga)$/, - use: { - loader: 'file-loader', - options: { - name: '[path][name].[hash].[ext]', - }, + name: '[name].[hash].[ext]', + publicPath: '/static', + outputPath: options?.outputFolder, }, }, { @@ -82,4 +77,4 @@ export const react: Configuration = { resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx'], }, -}; +}); diff --git a/core/webpack-configs/src/types.ts b/core/webpack-configs/src/types.ts index a1f9afdf3..c5801fc0b 100644 --- a/core/webpack-configs/src/types.ts +++ b/core/webpack-configs/src/types.ts @@ -7,3 +7,10 @@ export interface RuleOptions { export type RuleType = string | RuleOptions; export type RuleTypes = RuleType[]; + +export interface PresetOptions { + outputFolder?: string; +} + +export type PresetCallback = (options?: PresetOptions) => Configuration; +export type PresetType = Configuration | PresetCallback; diff --git a/integrations/gatsby-theme-stories/src/gatsby-node.ts b/integrations/gatsby-theme-stories/src/gatsby-node.ts index 07aa65f33..6490de4cd 100644 --- a/integrations/gatsby-theme-stories/src/gatsby-node.ts +++ b/integrations/gatsby-theme-stories/src/gatsby-node.ts @@ -1,3 +1,4 @@ +import * as path from 'path'; import { getDocPath, getStoryPath, @@ -24,6 +25,8 @@ exports.createPages = async ( webPack: options.webpack, presets: defaultPresets, configPath: options.configPath, + outputFolder: + options.outputFolder || `${path.join(process.cwd(), 'public')}`, }; const { store } = process.env.NODE_ENV === 'development' diff --git a/integrations/gatsby-theme-stories/src/types.ts b/integrations/gatsby-theme-stories/src/types.ts index dda669ddd..c4d591d61 100644 --- a/integrations/gatsby-theme-stories/src/types.ts +++ b/integrations/gatsby-theme-stories/src/types.ts @@ -14,4 +14,9 @@ export interface LoaderOptions { * presets options that will be passed to the instrumenter. */ presets?: RuleTypes; + + /** + * output folder for generated bundle + */ + outputFolder?: string; }