In a previous article, you covered the installation and configuration of the componentized builder Storybook in a VUE project. The tools on which the VUE project relies have evolved in comparison to how long it has been written; In practice, projects with multiple historical versions coexist everywhere. The NPX SB init provided by the official system often fails to be configured, and the new or old data are hard to find on the Internet

So here’s a special sideband that documents the manual configuration methods available for storybook in both typical new and old configurations:

1. babel7 + webpack5

1.1 Installation Process

diff --git a/.babelrc b/.babelrc index e1f4817.. 71b5fe8 100644 -- a/. Babelrc +++ b/. Babelrc @@-6,7 +6,8 @@ "modules": false, "targets": "last 2 years, ie > 8" } - ] + ], + "@vue/babel-preset-jsx" ], "plugins": [ "@babel/plugin-transform-runtime", Diff --git a/.eslintignore b/.eslintignore index e2192C5..0858135 100644 -- a/.eslintignore +++ b/.eslintignore @@ -2,4 Git a/.storybook/demo. CSS b/.storybook/demo. CSS new file mode 100644 index 0000000..820f051 -- /dev/null +++ + b/.storybook/demo. CSS @@-0,0 +1,12 @@ +.demo {+ padding-right: 50px; + display: inline-block; +} +.demo .block { + margin-bottom: 30px;  +} diff --git a/.storybook/main.js b/.storybook/main.js new file mode 100644 index 0000000..ceca416 --- /dev/null +++ B /.storybook/main.js @@-0,0 +1,22 @@ +const path = require("path");  +const pathResolve = p => path.resolve(__dirname, "../", p); + +module.exports = { + stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], + addons: ["@storybook/addon-links", "@storybook/addon-essentials"], + core: { + builder: "webpack5" + }, + webpackFinal: config => { + config.resolve.alias = { + ...config.resolve.alias, + "@": pathResolve("src"), + "~": pathResolve("node_modules") + }; + config.module.rules.push({ + test: /\.scss$/, + use: ["vue-style-loader", "css-loader", "sass-loader"] + }); + return config; + } +};  diff --git a/.storybook/manager-head.html b/.storybook/manager-head.html new file mode 100644 index 0000000..c5c2955 -- /dev/null +++ b/.storybook/manager-head. HTML @@-0,0 +1,14 @@ +<style> +. center; + } + .sidebar-header > div > a { + font-size: 28px;  + } +</style> diff --git a/.storybook/manager.js b/.storybook/manager.js new file mode 100644 index 0000000..c2321a4 -- /dev/null +++ b/.storybook/manager.js @@-0,0 +1,10 @@ +import {addons} from "@storybook/addons";  +import { create } from "@storybook/theming"; + +addons.setConfig({ + theme: create({ + base: "light", + brandImage: null, + brandTitle: "Front-end component" +}) +});  diff --git a/.storybook/preview.js b/.storybook/preview.js new file mode 100644 index 0000000..55d75d7 --- /dev/null +++ b/.storybook/preview.js @@-0,0 +1,23 @@+ import "./demo.css"; ++ export const parameters = {+ actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/ + } + }, + // https://github.com/storybookjs/storybook/pull/9090/commits/2db3faa727fed585fb5d9e6db23cc3835fc88829 + viewMode: "docs" +}; Diff --git a/package.json b/package.json index 673f3a9..c0b7b27 100644 -- a/package.json +++ b/package.json @@-1,19 +1,23 @@ + "storybook": "start-storybook -p 6006 --no-manager-cache", + "build-storybook": "Build-storybook ", "dependencies": {+ "@babel/ syntax-jsx": "^ 6.2.7," + "@ storybook/addon - essentials" : "^" 6.2.7, + "@ storybook/addon - links" : "^ 6.2.7," + "@ storybook/builder - webpack5" : "^" 6.2.7, + "@ storybook/theming" : "^ 6.2.8", + "@ storybook/vue" : "^ 6.2.7," + "@ vue/Babel - helper - vue - JSX - merge - props" : "^" 1.2.1, + "@ vue/Babel - preset - JSX" : "^ 1", "Babel - plugin - transform - vue - JSX" : "~ 3.7.0", diff --git a/src/utils/utils.js b/src/utils/utils.js new file mode 100644 index 0000000..3e8413d --- /dev/null +++ @@ +export const formatCode = jsCode => json.stringify (+ jsCode, + // eslint-disable-next-line + (key, value) => { + if (typeof value === 'function') { + return value.toString();  + } else { + return value; + } + }, + 2 + ).replace(/\\n/g, '\n');  diff --git a/src/utils/storyUtils.js b/src/utils/storyUtils.js new file mode 100644 index 0000000..4ad5149 --- / dev/null + + + b/SRC/utils/storyUtils js @ @ - 0, 0, + 1,49 @ @ + import {formatCode} from '. / utils; + * @param {String} path - the hierarchical path of the component, Split by '/' + * @param {Object} storyComponent - use case for presentation + * @param {String} markDown - Document + * @param {Object} [originComponent] - Optional, if you need to automatically generate apis from jSDOC inside the original component, + * @return {Object} story - {metadata, named} + * @see https://github.com/storybookjs/storybook/issues/8527 + */ +export const storyOf = (path, storyComponent, markdown, originComponent) => { + const pathArr = path.split('/').map(p => { + // https://storybook.js.org/docs/vue/writing-stories/args#setting-args-through-the-url + if (! /^[0-9a-zA-Z]/.test(p)) { + return '#' + p; + } + return p; + }); + const storyName = pathArr[pathArr.length - 1];  + + const metadata = { + component: originComponent || void 0, + title: pathArr.join('/'), + decorators: [ + () => ({template: '<div class="demo"><story></story></div>'}) + ] + }; + + const named = () => storyComponent;  + named.storyName = storyName; + named.parameters = { + docs: { + description: { + component: markdown || '&nbsp;' + }, + source: { + // type: 'dynamic' + type: 'code', + code: formatCode(storyComponent) + } + } + }; + + return { + metadata, + named + }; +};Copy the code

1.2 Components and Use cases

Case 1:

import { Meta, Preview, Description } from '@storybook/addon-docs/blocks'
import readme from './README.md'
import pathPrefix from './pathPrefix.js'

<Meta title={pathPrefix + "/API"} />

<Description markdown={readme} />
Copy the code

Component 2:

<template functional> <x-table v-bind="{ ... data.attrs, ... props }" v-on="listeners" > <! -... --> </x-table> </template> <script> export default { props: {/** * add the ability to define component__ in template. */ columns: {type: Array, default: () => []}}, emits: [/ * * * if the event with the same custom components, will be listening to the table of containers; * parameters for ` key,... values ` * / 'column - action]}. </script>Copy the code

Case 2:

import {storyOf} from '@/utils/storyUtils';
import Comp from '@/components/SimpleTable';

const title = 'Example/SimpleTable | full configuration change form';

const markdown = '> an extension based on \' x-table\ 'that can accept its original attributes and events;

const comp = {
    template: ` 
       `.data() {
        return {
            / /...
        };
    },
    methods: {
        onColAction(act, value){ alert([act, value]); }}};const {metadata, named} = storyOf(title, comp, markdown, Comp);
export default metadata;
export const story = named;
Copy the code

2. babel6 + webpack4

2.1 Installation Process

diff --git a/.storybook/addons.js b/.storybook/addons.js new file mode 100644 index 0000000.. 7106272 -- /dev/null +++ + b/.storybook/addons.js @@-0,0 +1,4 @@ +import 'storybook-addon-vue-info/lib/register'; +import '@storybook/addon-backgrounds/register'; +import '@storybook/addon-viewport/register'; +import '@storybook/addon-storysource/register'; diff --git a/.storybook/config.js b/.storybook/config.js new file mode 100644 index 0000000.. F84ef78 -- /dev/null +++ b/.storybook/config.js @@-0,0 +1,34 @@ +import {configure, addDecorator, addParameters} from '@storybook/vue'; +import {create} from '@storybook/theming'; +import {withInfo, setDefaults} from 'storybook-addon-vue-info'; +import './demo.css'; + +setDefaults({ + header: false, + useDocgen: false +}); +addDecorator(withInfo); +addParameters({+ options: {+ theme: create({+ base: 'light', + brandImage: null, + brandTitle: 'front component' +}) +} +}); +const req = require.context('.. /src', true, /\.stories\.js$/); +function loadStories() { + req.keys().forEach(filename => { + try { + req(filename); + } catch (ex) { + console.log('storybook-req', ex); + +}}); +} +configure(loadStories, module); diff --git a/.storybook/manager-head.html b/.storybook/manager-head.html new file mode 100644 index 0000000.. <style> +. Sidebar -header {+ text-align: left; center; + } + .sidebar-header > div > a { + font-size: 28px; + } +</style> diff --git a/.storybook/demo.css b/.storybook/demo.css new file mode 100644 index 0000000.. /dev/null +++ + b/.storybook/demo. CSS @@-0,0 +1,12 @@ +.demo {+ padding: 50px; + display: inline-block; +} + +.demo .block { + margin-bottom: 30px; +} diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html new file mode 100644 index 0000000.. e69de29 diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js new file mode 100644 index 0000000.. D15-3186 + + + b /, / dev/null storybook/webpack config. Js @ @ - 0, 0, + 1, 32 @ @ + const path = the require (" path "); +const pathResolve = p => path.resolve(__dirname, '.. /', p); +module.exports = ({config, mode}) => { + config.resolve.alias = { + ... config.resolve.alias, + '@': pathResolve('src'), + '~': pathResolve('node_modules') + }; + config.module.rules.push({ + test: /\.scss$/, + use: ['style-loader', 'css-loader', 'sass-loader'] + }); + config.module.rules.push({ + test: /\.vue$/, + loader: 'storybook-addon-vue-info/loader', + enforce: 'post' + }); + config.module.rules.push({ + test: /\.stories\.js$/, + loaders: [require.resolve('@storybook/addon-storysource/loader')], + enforce: 'pre' + }); + if (process.env.NODE_ENV === 'production') { + config.output.filename = 'bundle.[name].js'; + config.optimization.splitChunks.automaticNameDelimiter = '.'; + config.optimization.runtimeChunk = { + name: entrypoint => `runtime.${entrypoint.name}` + }; + } + // console.log(config); + return config; +}; diff --git a/package.json b/package.json index d83bbba.. 6027c58 100644 -- a/package.json +++ b/package.json @@ -21,7 +21,9 @@ + "build-storybook": "build-storybook", + "storybook": "start-storybook -p 6006" "devDependencies": { + "@storybook/addon-backgrounds": "^ 5.3.18," + "@ storybook/addon - info", "^ 5.3.18", + "@ storybook/addon - storysource" : "^ 5.3.18," + "@ storybook/addon - the viewport" : "^ 5.3.18", + "@ storybook/addons" : "^ 5.3.18", + "@ storybook/theming" : "^ 5.3.18," + "@ storybook/vue" : "^ 5.3.18", + "storybook - addon - vue - info", "^ 1.4.2",Copy the code

2.2 use case

import {storiesOf} from '@storybook/vue';
import CustomCols from './index';

const totalColumns = [
    // ...
];

const description = {
    CustomCols: {
        props: {
            choose: 'Values for v-model'.totalColumns: 'Optional columns'.storageName: 'Local store key',},events: {
            'on-change': 'Triggered when selected columns change'}}};const info = {
    useDocgen: false.summary: 'based on XXX'
};

storiesOf('Enhanced custom table columns'.module)
    .add(
        'Natively stores results of last selection'.() = > ({
            components: {
                CustomCols
            },
            template: ` 
      
`
.data() { return { totalColumns, selColsStoName: `The ${window.location.hostname}_overview_custom_cols`.selectedCols: ['impression'.'click']}; },methods: { onChange(v) { / /... } }, description }), { info } ); Copy the code






–End–