Webpacker: Webpacker with storybook

Created on 9 Nov 2017  ·  9Comments  ·  Source: rails/webpacker

Hello,

Has anyone used webpacker with storybook? Storybook is a live styleguide and it has its own webpack.config.js. I believe its using webpack 2.0. So if my rails app is using webpacker and storybook is using a webpack.config.js, how can I make both of them have the same configuration?

I want to be able to change one configuration file and not have to worry about configuring two things whenever something gets added. Also the task of having to configure storybook after dealing with the woahs of webpacker seem daunting, so if there is an easy way to pull in webpacker's configuration that would be great.

Most helpful comment

Storybook 5.0 and Webpacker 4.0:

.storybook/config.js

import { configure } from '@storybook/react'

// automatically import all files ending in *.stories.js
const req = require.context(
  '../app/javascript/src/stories',
  true,
  /.stories.js$/
)
function loadStories() {
  req.keys().forEach(filename => req(filename))
}

configure(loadStories, module)

.storybook/addons.js

import '@storybook/addon-actions/register'
import '@storybook/addon-links/register'

app/javascript/src/stories/Documentation.stories.js

import { storiesOf } from '@storybook/react'

import React from 'react'

storiesOf('Documentation', module)
  .add('React in Rails', () => (
    <div>
      <h1>React in Rails</h1>
      <p>The way we use React in Rails...</p>
    </div>
  ))

cc @shilman might be good for docs!

All 9 comments

@ajnassar Worth opening this issue on storybook repo or SO, asking how to use Storybook with existing webpack setup.

@ajnassar here's my config for Storybook 3.3.8 and Webpacker 3.2:

const path = require('path');
const { environment } = require('@rails/webpacker');
const genDefaultConfig = require('@storybook/react/dist/server/config/defaults/webpack.config.js');

const yamlLoader = require('./../config/webpack/loaders/yaml-loader');
const sassLoader = require('./../config/webpack/loaders/sass-loader');

module.exports = (baseConfig, env) => {
  const config = genDefaultConfig(baseConfig, env);

  // Extend Storybook Webpack's resolve paths from Webpacker config
  config.resolve.modules = environment.toWebpackConfig().resolve.modules;

  // Add Sass and Yaml Loader
  config.module.rules.push(yamlLoader);
  config.module.rules.push(sassLoader);

  return config;

Nothing pretty, but works fine (you can skip yaml and sass loader if not needed)

Storybook 5.0 and Webpacker 4.0:

.storybook/config.js

import { configure } from '@storybook/react'

// automatically import all files ending in *.stories.js
const req = require.context(
  '../app/javascript/src/stories',
  true,
  /.stories.js$/
)
function loadStories() {
  req.keys().forEach(filename => req(filename))
}

configure(loadStories, module)

.storybook/addons.js

import '@storybook/addon-actions/register'
import '@storybook/addon-links/register'

app/javascript/src/stories/Documentation.stories.js

import { storiesOf } from '@storybook/react'

import React from 'react'

storiesOf('Documentation', module)
  .add('React in Rails', () => (
    <div>
      <h1>React in Rails</h1>
      <p>The way we use React in Rails...</p>
    </div>
  ))

cc @shilman might be good for docs!

Here is my .storybook/main.js with @rails/[email protected] and @storybook/[email protected], so far it just works and I have not encountered any problem yet:

process.env.NODE_ENV = "development";
const railsWebpackEnv = require("../config/webpack/environment");

module.exports = {
  stories: ["../app/javascript/stories/*.jsx"],
  webpackFinal: (config) => ({
    ...config,
    resolve: {
      ...config.resolve,
      ...railsWebpackEnv.config.resolve,
      modules: railsWebpackEnv.resolvedModules.map((i) => i.value),
    },
    module: {
      ...config.module,
      rules: railsWebpackEnv.loaders
        .filter((i) => i.key !== "nodeModules")
        .map((i) => i.value),
    },
    plugins: [
      ...config.plugins,
      ...railsWebpackEnv.plugins.map((i) => i.value),
    ],
  }),
};

Hope it helps.

Are there any tricks or approaches to getting styles to work with storybook through webpacker? Everything else does hot module reloading but basic CSS never reloads.

@tonytonyjan any problems with this in your config? It otherwise works well for me.

@tonytonyjan any problems with this in your config? It otherwise works well for me.

Since webpacker's loaders for css and sass include MiniCssExtractPlugin, hot reloading would not work as expected, which means that you have to manually reload the page after updating css/sass files.

To fix this, you would need to modify css/sass loaders and prepend style-loader, for example:

const railsWebpackEnv = require("../config/webpack/environment");

module.exports = {
  stories: ["../app/javascript/stories/*.jsx"],
  webpackFinal: (config) => {
    return {
      ...config,
      resolve: {
        ...config.resolve,
        modules: railsWebpackEnv.resolvedModules.map((i) => i.value),
      },
      module: {
        rules: railsWebpackEnv.loaders
          .filter((i) => ["file", "css", "babel"].includes(i.key))
          .map((i) => {
            if (["css", "sass"].includes(i.key))
              return {
                ...i.value,
                use: ["style-loader", ...i.value.use.slice(1)],
              };
            else return i.value;
          }),
      },
    };
  },
};


railsWebpackEnv
Base {
loaders: ConfigList(7) [
{
key: 'file',
value: {
test: /(.jpg|.jpeg|.png|.gif|.tiff|.ico|.svg|.eot|.otf|.ttf|.woff|.woff2)$/i,
use: [
{
loader: 'file-loader',
options: { name: [Function: name], context: 'app/javascript' }
}
]
}
},
{
key: 'css',
value: {
test: /.(css)$/i,
use: [
'/usr/local/src/sanbao.icu/node_modules/@rails/webpacker/node_modules/mini-css-extract-plugin/dist/loader.js',
{
loader: 'css-loader',
options: { sourceMap: true, importLoaders: 2, modules: false }
},
{
loader: 'postcss-loader',
options: {
config: { path: '/usr/local/src/sanbao.icu' },
sourceMap: true
}
}
],
sideEffects: true,
exclude: /.module.[a-z]+$/
}
},
{
key: 'sass',
value: {
test: /.(scss|sass)(.erb)?$/i,
use: [
'/usr/local/src/sanbao.icu/node_modules/@rails/webpacker/node_modules/mini-css-extract-plugin/dist/loader.js',
{
loader: 'css-loader',
options: { sourceMap: true, importLoaders: 2, modules: false }
},
{
loader: 'postcss-loader',
options: {
config: { path: '/usr/local/src/sanbao.icu' },
sourceMap: true
}
},
{ loader: 'sass-loader', options: { sourceMap: true } }
],
sideEffects: true,
exclude: /.module.[a-z]+$/
}
},
{
key: 'moduleCss',
value: {
test: /.(css)$/i,
use: [
'/usr/local/src/sanbao.icu/node_modules/@rails/webpacker/node_modules/mini-css-extract-plugin/dist/loader.js',
{
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 2,
modules: { localIdentName: '[name]__[local]___[hash:base64:5]' }
}
},
{
loader: 'postcss-loader',
options: {
config: { path: '/usr/local/src/sanbao.icu' },
sourceMap: true
}
}
],
sideEffects: false,
include: /.module.[a-z]+$/
}
},
{
key: 'moduleSass',
value: {
test: /.(scss|sass)$/i,
use: [
'/usr/local/src/sanbao.icu/node_modules/@rails/webpacker/node_modules/mini-css-extract-plugin/dist/loader.js',
{
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 2,
modules: { localIdentName: '[name]__[local]___[hash:base64:5]' }
}
},
{
loader: 'postcss-loader',
options: {
config: { path: '/usr/local/src/sanbao.icu' },
sourceMap: true
}
},
{ loader: 'sass-loader', options: { sourceMap: true } }
],
sideEffects: false,
include: /.module.[a-z]+$/
}
},
{
key: 'nodeModules',
value: {
test: /.(js|mjs)$/,
include: /node_modules/,
exclude: /(?:@?babel(?:\/|\{1,2}|-).+)|regenerator-runtime|core-js|^webpack$|^webpack-assets-manifest$|^webpack-cli$|^webpack-sources$|^@rails\/webpacker$/,
use: [
{
loader: 'babel-loader',
options: {
babelrc: false,
presets: [ [ '@babel/preset-env', { modules: false } ] ],
cacheDirectory: 'tmp/cache/webpacker/babel-loader-node-modules',
cacheCompression: false,
compact: false,
sourceMaps: false
}
}
]
}
},
{
key: 'babel',
value: {
test: /.(js|jsx|mjs)?(.erb)?$/,
include: [ '/usr/local/src/sanbao.icu/app/javascript' ],
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: 'tmp/cache/webpacker/babel-loader-node-modules',
cacheCompression: false,
compact: false
}
}
]
}
}
],
plugins: ConfigList(4) [
{
key: 'Environment',
value: EnvironmentPlugin {
keys: [
'RUBY_MAJOR',
'DATABASE_URL',
'HOSTNAME',
'SHLVL',
'HOME',
'BUNDLE_APP_CONFIG',
'RUBY_VERSION',
'TERM',
'GCS_BUCKET_NAME',
'PATH',
'LANG',
'BEANSTALK_URL',
'GEM_HOME',
'RUBY_DOWNLOAD_SHA256',
'PWD',
'BUNDLE_SILENCE_ROOT_WARNING',
'NODE_ENV'
],
defaultValues: {
RUBY_MAJOR: '2.7',
DATABASE_URL: 'postgres://postgres:password@db/development',
HOSTNAME: '486ef5e654fa',
SHLVL: '1',
HOME: '/root',
BUNDLE_APP_CONFIG: '/usr/local/bundle',
RUBY_VERSION: '2.7.1',
TERM: 'xterm',
GCS_BUCKET_NAME: 'sanbao-icu-dev',
PATH: '/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
LANG: 'C.UTF-8',
BEANSTALK_URL: 'beanstalk://job',
GEM_HOME: '/usr/local/bundle',
RUBY_DOWNLOAD_SHA256: 'b224f9844646cc92765df8288a46838511c1cec5b550d8874bd4686a904fcee7',
PWD: '/usr/local/src/sanbao.icu',
BUNDLE_SILENCE_ROOT_WARNING: '1',
NODE_ENV: 'development'
}
}
},
{
key: 'CaseSensitivePaths',
value: CaseSensitivePathsPlugin {
options: {},
logger: {
log: [Function: bound consoleCall],
warn: [Function: bound consoleCall],
dir: [Function: bound consoleCall],
time: [Function: bound consoleCall],
timeEnd: [Function: bound consoleCall],
timeLog: [Function: bound consoleCall],
trace: [Function: bound consoleCall],
assert: [Function: bound consoleCall],
clear: [Function: bound consoleCall],
count: [Function: bound consoleCall],
countReset: [Function: bound consoleCall],
group: [Function: bound consoleCall],
groupEnd: [Function: bound consoleCall],
table: [Function: bound consoleCall],
debug: [Function: bound consoleCall],
info: [Function: bound consoleCall],
dirxml: [Function: bound consoleCall],
error: [Function: bound consoleCall],
groupCollapsed: [Function: bound consoleCall],
Console: [Function: Console],
profile: [Function: profile],
profileEnd: [Function: profileEnd],
timeStamp: [Function: timeStamp],
context: [Function: context],
[Symbol(kBindStreamsEager)]: [Function: bound ],
[Symbol(kBindStreamsLazy)]: [Function: bound ],
[Symbol(kBindProperties)]: [Function: bound ],
[Symbol(kWriteToConsole)]: [Function: bound ],
[Symbol(kGetInspectOptions)]: [Function: bound ],
[Symbol(kFormatForStdout)]: [Function: bound ],
[Symbol(kFormatForStderr)]: [Function: bound ]
},
pathCache: {},
fsOperations: 0,
primed: false
}
},
{
key: 'MiniCssExtract',
value: MiniCssExtractPlugin {
options: {
filename: 'css/[name]-[contenthash:8].css',
moduleFilename: [Function: moduleFilename],
ignoreOrder: false,
chunkFilename: 'css/[name]-[contenthash:8].chunk.css'
}
}
},
{
key: 'Manifest',
value: WebpackAssetsManifest {
hooks: {
apply: SyncHook {
_args: [ 'manifest' ],
taps: [],
interceptors: [],
call: [Function: lazyCompileHook],
promise: [Function: lazyCompileHook],
callAsync: [Function: lazyCompileHook],
_x: undefined
},
customize: SyncWaterfallHook {
_args: [ 'entry', 'original', 'manifest', 'asset' ],
taps: [],
interceptors: [],
call: [Function: lazyCompileHook],
promise: [Function: lazyCompileHook],
callAsync: [Function: lazyCompileHook],
_x: undefined
},
transform: SyncWaterfallHook {
_args: [ 'assets', 'manifest' ],
taps: [
{
type: 'sync',
fn: [Function],
name: 'WebpackAssetsManifest'
}
],
interceptors: [],
call: [Function: lazyCompileHook],
promise: [Function: lazyCompileHook],
callAsync: [Function: lazyCompileHook],
_x: undefined
},
done: SyncHook {
_args: [ 'manifest', 'stats' ],
taps: [],
interceptors: [],
call: [Function: lazyCompileHook],
promise: [Function: lazyCompileHook],
callAsync: [Function: lazyCompileHook],
_x: undefined
},
options: SyncWaterfallHook {
_args: [ 'options' ],
taps: [],
interceptors: [],
call: [Function: lazyCompileHook],
promise: [Function: lazyCompileHook],
callAsync: [Function: lazyCompileHook],
_x: undefined
},
afterOptions: SyncHook {
_args: [ 'options' ],
taps: [
{
type: 'sync',
fn: [Function],
name: 'WebpackAssetsManifest'
}
],
interceptors: [],
call: [Function: lazyCompileHook],
promise: [Function: lazyCompileHook],
callAsync: [Function: lazyCompileHook],
_x: undefined
}
},
options: {
assets: [Object: null prototype] {},
output: 'manifest.json',
replacer: null,
space: 2,
writeToDisk: true,
fileExtRegex: /.\w{2,4}.(?:map|gz)$|.\w+$/i,
sortManifest: true,
merge: false,
publicPath: '/packs/',
apply: null,
customize: null,
transform: null,
done: null,
entrypoints: true,
entrypointsKey: 'entrypoints',
integrity: false,
integrityHashes: [ 'sha256', 'sha384', 'sha512' ],
integrityPropertyName: 'integrity'
},
assets: [Object: null prototype] {},
assetNames: Map {},
currentAsset: null,
compiler: null,
stats: null,
hmrRegex: null,
[Symbol(isMerging)]: false
}
}
],
config: ConfigObject {
mode: 'development',
output: {
filename: 'js/[name]-[contenthash].js',
chunkFilename: 'js/[name]-[contenthash].chunk.js',
hotUpdateChunkFilename: 'js/[id]-[hash].hot-update.js',
path: '/usr/local/src/sanbao.icu/public/packs',
publicPath: '/packs/',
pathinfo: true
},
resolve: {
extensions: [
'.jsx', '.mjs',
'.js', '.sass',
'.scss', '.css',
'.module.sass', '.module.scss',
'.module.css', '.png',
'.svg', '.gif',
'.jpeg', '.jpg'
],
plugins: [
{
apply: [Function: nothing],
makePlugin: [Function],
moduleLoader: [Function],
topLevelLoader: { apply: [Function: nothing] },
bind: [Function],
tsLoaderOptions: [Function],
forkTsCheckerOptions: [Function]
}
]
},
resolveLoader: {
modules: [ 'node_modules' ],
plugins: [ { apply: [Function: nothing] } ]
},
node: {
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
},
cache: true,
devtool: 'cheap-module-source-map',
devServer: {
clientLogLevel: 'none',
compress: undefined,
quiet: undefined,
disableHostCheck: undefined,
host: undefined,
port: undefined,
https: undefined,
hot: undefined,
contentBase: '/usr/local/src/sanbao.icu/public/packs',
inline: undefined,
useLocalIp: undefined,
public: undefined,
publicPath: '/packs/',
historyApiFallback: { disableDotRule: true },
headers: undefined,
overlay: undefined,
stats: {
entrypoints: false,
errorDetails: true,
modules: false,
moduleTrace: false
},
watchOptions: undefined
}
},
entry: ConfigObject {
application: '/usr/local/src/sanbao.icu/app/javascript/packs/application.js',
hello_react: '/usr/local/src/sanbao.icu/app/javascript/packs/hello_react.jsx'
},
resolvedModules: ConfigList(2) [
{
key: 'source',
value: '/usr/local/src/sanbao.icu/app/javascript'
},
{ key: 'node_modules', value: 'node_modules' }
]
}


storybook default config
{
mode: 'development',
bail: false,
devtool: '#cheap-module-source-map',
entry: [
'/usr/local/src/sanbao.icu/node_modules/@storybook/core/dist/server/common/polyfills.js',
'/usr/local/src/sanbao.icu/node_modules/@storybook/core/dist/server/preview/globals.js',
'/usr/local/src/sanbao.icu/.storybook/generated-entry.js',
'/usr/local/src/sanbao.icu/node_modules/webpack-hot-middleware/client.js?reload=true&quiet=true'
],
output: {
path: '/usr/local/src/sanbao.icu/node_modules/@storybook/core/dist/public',
filename: '[name].[hash].bundle.js',
publicPath: ''
},
plugins: [
VirtualModulesPlugin {
_staticModules: {
'/usr/local/src/sanbao.icu/.storybook/generated-entry.js': '\n' +
" import { configure } from '@storybook/react';\n" +
' module._StorybookPreserveDecorators = true;\n' +
'\n' +
" configure([require.context('../app/javascript/stories', false, /^\.\/(?:(?!\.)(?=.)[^/]?\.jsx\/?)$/)\n" +
' ], module);\n' +
' '
}
},
HtmlWebpackPlugin {
options: {
template: '/usr/local/src/sanbao.icu/node_modules/@storybook/core/dist/server/templates/index.ejs',
templateContent: false,
templateParameters: [Function: templateParameters],
filename: 'iframe.html',
hash: false,
inject: false,
scriptLoading: 'blocking',
compile: true,
favicon: false,
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: false,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
},
cache: true,
showErrors: true,
chunks: 'all',
excludeChunks: [],
chunksSortMode: 'none',
meta: {},
base: false,
title: 'Webpack App',
xhtml: false,
alwaysWriteToDisk: true
},
childCompilerHash: undefined,
assetJson: undefined,
hash: undefined,
version: 4
},
DefinePlugin {
definitions: {
'process.env': {
NODE_ENV: '"development"',
NODE_PATH: '""',
PUBLIC_URL: '"."'
},
NODE_ENV: '"development"'
}
},
WatchMissingNodeModulesPlugin {
nodeModulesPath: '/usr/local/src/sanbao.icu/node_modules'
},
HotModuleReplacementPlugin {
options: {},
multiStep: undefined,
fullBuildTimeout: 200,
requestTimeout: 10000
},
CaseSensitivePathsPlugin {
options: {},
logger: {
log: [Function: bound consoleCall],
warn: [Function: bound consoleCall],
dir: [Function: bound consoleCall],
time: [Function: bound consoleCall],
timeEnd: [Function: bound consoleCall],
timeLog: [Function: bound consoleCall],
trace: [Function: bound consoleCall],
assert: [Function: bound consoleCall],
clear: [Function: bound consoleCall],
count: [Function: bound consoleCall],
countReset: [Function: bound consoleCall],
group: [Function: bound consoleCall],
groupEnd: [Function: bound consoleCall],
table: [Function: bound consoleCall],
debug: [Function: bound consoleCall],
info: [Function: bound consoleCall],
dirxml: [Function: bound consoleCall],
error: [Function: bound consoleCall],
groupCollapsed: [Function: bound consoleCall],
Console: [Function: Console],
profile: [Function: profile],
profileEnd: [Function: profileEnd],
timeStamp: [Function: timeStamp],
context: [Function: context],
[Symbol(kBindStreamsEager)]: [Function: bound ],
[Symbol(kBindStreamsLazy)]: [Function: bound ],
[Symbol(kBindProperties)]: [Function: bound ],
[Symbol(kWriteToConsole)]: [Function: bound ],
[Symbol(kGetInspectOptions)]: [Function: bound ],
[Symbol(kFormatForStdout)]: [Function: bound ],
[Symbol(kFormatForStderr)]: [Function: bound ]
},
pathCache: {},
fsOperations: 0,
primed: false
},
ProgressPlugin {
profile: false,
handler: undefined,
modulesCount: 500,
showEntries: false,
showModules: true,
showActiveModules: true
},
DefinePlugin { definitions: {} },
NormalModuleReplacementPlugin {
resourceRegExp: /core-js/,
newResource: [Function]
}
],
module: {
rules: [
{
test: /.(mjs|jsx?)$/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: '/usr/local/src/sanbao.icu/node_modules/.cache/storybook',
presets: [
[
'/usr/local/src/sanbao.icu/node_modules/@babel/preset-env/lib/index.js',
{
shippedProposals: true,
useBuiltIns: 'usage',
corejs: '3'
}
],
'/usr/local/src/sanbao.icu/node_modules/@babel/preset-react/lib/index.js',
'/usr/local/src/sanbao.icu/node_modules/@babel/preset-flow/lib/index.js'
],
plugins: [
'/usr/local/src/sanbao.icu/node_modules/@babel/plugin-proposal-object-rest-spread/lib/index.js',
'/usr/local/src/sanbao.icu/node_modules/@babel/plugin-proposal-class-properties/lib/index.js',
'/usr/local/src/sanbao.icu/node_modules/@babel/plugin-syntax-dynamic-import/lib/index.js',
[
'/usr/local/src/sanbao.icu/node_modules/babel-plugin-emotion/dist/babel-plugin-emotion.cjs.js',
{ sourceMap: true, autoLabel: true }
],
'/usr/local/src/sanbao.icu/node_modules/babel-plugin-macros/dist/index.js',
'/usr/local/src/sanbao.icu/node_modules/@babel/plugin-transform-react-constant-elements/lib/index.js',
'/usr/local/src/sanbao.icu/node_modules/babel-plugin-add-react-displayname/index.js',
[
'/usr/local/src/sanbao.icu/node_modules/babel-plugin-react-docgen/lib/index.js',
{
DOC_GEN_COLLECTION_NAME: 'STORYBOOK_REACT_CLASSES'
}
]
]
}
}
],
include: [ '/usr/local/src/sanbao.icu' ],
exclude: [ '/usr/local/src/sanbao.icu/node_modules' ]
},
{
test: /.md$/,
use: [
{
loader: '/usr/local/src/sanbao.icu/node_modules/raw-loader/dist/cjs.js'
}
]
},
{
test: /.css$/,
sideEffects: true,
use: [
'/usr/local/src/sanbao.icu/node_modules/style-loader/dist/cjs.js',
{
loader: '/usr/local/src/sanbao.icu/node_modules/css-loader/dist/cjs.js',
options: { importLoaders: 1 }
},
{
loader: '/usr/local/src/sanbao.icu/node_modules/postcss-loader/src/index.js',
options: { config: { path: '/usr/local/src/sanbao.icu' } }
}
]
},
{
test: /.(svg|ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.
)?$/,
loader: '/usr/local/src/sanbao.icu/node_modules/file-loader/dist/cjs.js',
query: { name: 'static/media/[name].[hash:8].[ext]' }
},
{
test: /.(mp4|webm|wav|mp3|m4a|aac|oga)(\?.)?$/,
loader: '/usr/local/src/sanbao.icu/node_modules/url-loader/dist/cjs.js',
query: { limit: 10000, name: 'static/media/[name].[hash:8].[ext]' }
}
]
},
resolve: {
extensions: [ '.mjs', '.js', '.jsx', '.json' ],
modules: [ 'node_modules' ],
alias: {
'babel-runtime/core-js/object/assign': '/usr/local/src/sanbao.icu/node_modules/core-js/es/object/assign.js',
react: '/usr/local/src/sanbao.icu/node_modules/react',
'react-dom': '/usr/local/src/sanbao.icu/node_modules/react-dom'
}
},
optimization: {
splitChunks: { chunks: 'all' },
runtimeChunk: true,
minimizer: [
TerserPlugin {
options: {
test: /.m?js(\?.
)?$/i,
chunkFilter: [Function: chunkFilter],
warningsFilter: [Function: warningsFilter],
extractComments: true,
sourceMap: true,
cache: true,
cacheKeys: [Function: cacheKeys],
parallel: true,
include: undefined,
exclude: undefined,
minify: undefined,
terserOptions: { mangle: false, keep_fnames: true }
}
}
]
},
performance: { hints: false }
}

@tonytonyjan Does your above configuration work with version 6? I have it kind of working on my end, however I couldn't get your first configuration to load my rails styles, but the second does load some of the CSS. It seems to be missing .scss and .erb files.

If you have any suggestions to getting this to work I wouldn't greatly appreciate it.

For storybook v6, the default configuration worked for me:

module.exports = {
  typescript: {
    check: true,
  },
  'stories': [
    '../app/javascript/stories/**/*.stories.mdx',
    '../app/javascript/stories/**/*.stories.@(js|jsx|ts|tsx)',
  ],
  'addons': [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
  ],
};

I'm using typescript, so I just added that config option as well.

PS I had to delete node_modules and run yarn to get the configuration working. 🤷‍♂️

Was this page helpful?
0 / 5 - 0 ratings