hey there. we are still using coffeescript and want to start using storybook.
however, i cannot find anywere anything about how to make storybook work with coffeescript (and meteor)
I figured out, how. Wow, that wasn’t totally easy.
- First, you need to install storybook in your resporitories directory where also your meteor root is, as described in the storybook tutorial. This creates a
.storybook
folder. - Now you create a
webpack.config.js
in inside the.storybook
folder.
this webpack config basically looks like this:
const path = require("path")
module.exports = ({ config }) => {
/* Manipulate config here */
config.resolve.extensions.push('.coffee');
config.resolve.extensions.push('.scss');
config.resolve.extensions.push('.js');
return config;
};
also, i created a preview-head.html
inside the `.storybook* directory:
<!-- Supply your CSS from Meteor, if you cannot convince storybook to build it -->
<link rel="stylesheet" href="http://localhost:3000/merged-stylesheets.css">
<script>
window.__meteor_runtime_config__ = {
"meteorRelease": "METEOR@1.8.0.2",
"meteorEnv": {
"NODE_ENV": "development",
"TEST_METADATA": "{}"
},
"PUBLIC_SETTINGS": {
},
"ROOT_URL": "http://localhost:3000",
"ROOT_URL_PATH_PREFIX": "",
"appId": "zivmvxxevpdg1xu8kc5",
"isModern": true
}
window.Package = {};
window.Roles = {
GLOBAL_GROUP: '__global_roles__'
};
</script>
now you can edit your webpack.config.js
to load coffeescript (coffeescript 2):
config.module.rules.push({
test: /\.coffee$/,
exclude: /(node_modules|bower_components)/,
loaders: [
{
loader: 'babel-loader',
query: {
plugins: ['transform-react-jsx'],
}
},
{
loader: 'coffee-loader',
}
],
})
next we want JSX-Support:
config.module.rules.push({
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader']
})
and basic CSS support:
config.module.rules.push({
test: /\.css$/,
use: ['style-loader', 'css-loader']
})
If you have a SCSS file with a single entrypoint and no meteor packages that also provide Styling code, you can add the entrypoint for the storybook scss. However, Storybook needs Tilde-Imports ~/...
instead of meteor’s {}/...
. So what I’ve done is creating a partial import scss file (starting with an underscore) that won’t be compiled by meteor’s scss compiler, that imports the scss code from the imports folder using tilde-global-imports and then within the imports folder only used relative imports
config.entry.push(path.resolve(__dirname, '../client/stylesheets/_storybook.scss'))
config.module.rules.push({
test: /\.scss$/,
use: [
"style-loader", // creates style nodes from JS strings
"css-loader", // translates CSS into CommonJS
"sass-loader" // compiles Sass to CSS, using Node Sass by default
]
})
now the coffeescript meteor global import aliases:
['imports', 'client', 'server', 'locales'].forEach((pathName) => {
config.resolve.alias['/' + pathName] = path.resolve(__dirname, '../' + pathName)
})
config.resolve.modules.push(path.resolve(__dirname, '../'))
and finally some trickery that when a component calls Meteor-Code (or at least imports it), it won’t crash:
config.resolve.alias['meteor/meteor'] = path.resolve(__dirname, './meteor-stubs/meteor.coffee')
config.resolve.alias['meteor/mongo'] = path.resolve(__dirname, './meteor-stubs/mongo.coffee')
config.resolve.alias['meteor/tracker'] = path.resolve(__dirname, './meteor-stubs/tracker.js')
config.resolve.alias['meteor/check'] = path.resolve(__dirname, './meteor-stubs/check.js')
config.resolve.alias['meteor/templating'] = path.resolve(__dirname, './meteor-stubs/templating.js')
config.resolve.alias['meteor/reactive-var'] = path.resolve(__dirname, './meteor-stubs/reactive-var.js')
config.resolve.alias['meteor/http'] = path.resolve(__dirname, './meteor-stubs/http.coffee')
config.resolve.alias['meteor/session'] = path.resolve(__dirname, './meteor-stubs/session.js')
config.resolve.alias['meteor/raix:eventemitter'] = path.resolve(__dirname, './meteor-stubs/eventemitter.js')
config.resolve.alias['meteor/aldeed:collection2'] = path.resolve(__dirname, './meteor-stubs/collection2.js')
config.resolve.alias['meteor/reactive-dict'] = path.resolve(__dirname, './meteor-stubs/reactive-dict.js')
config.resolve.alias['meteor/react-meteor-data'] = path.resolve(__dirname, './meteor-stubs/react-meteor-data.js')
for most of the stubs, I just made empty methods that do nothing.