storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.03k stars 9.24k forks source link

[Bug]: `run storybook` crashes because of a TypeError (Vue3 + Webpack 5 + Typescript) #25710

Open XmlmXmlmX opened 8 months ago

XmlmXmlmX commented 8 months ago

I installed Storybook to a existing project which is using Vue3 and Webpack 5 (npx storybook@latest init):

Install bash log

```bash ╭───────────────────────────────────────────────────────╮ │ │ │ Adding Storybook version 7.6.10 to your project.. │ │ │ ╰───────────────────────────────────────────────────────╯ • Detecting project type. ✓ • Preparing to install dependencies. ✓ • Installing dependencies removed 833 packages, changed 1 package, and audited 1010 packages in 10s 120 packages are looking for funding run `npm fund` for details 1 moderate severity vulnerability To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details. . ✓ • Adding Storybook support to your "Vue 3" app • Detected webpack project. Setting builder to webpack. ✓ ✔ Getting the correct version of 11 packages √ We have detected that you're using ESLint. Storybook provides a plugin that gives the best experience with Storybook and helps follow best practices: https://github.com/storybookjs/eslint-plugin-storybook#readme Would you like to install it? ... yes Configuring Storybook ESLint plugin at .eslintrc.json ✔ Installing Storybook dependencies . ✓ • Preparing to install dependencies. ✓ • Installing dependencies up to date, audited 1843 packages in 2s 261 packages are looking for funding run `npm fund` for details 1 moderate severity vulnerability To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details. . ✓ ╭──────────────────────────────────────────────────────────────────────────────╮ │ │ │ Storybook was successfully installed in your project! 🎉 │ │ To run Storybook manually, run npm run storybook. CTRL+C to stop. │ │ │ │ Wanna know more about Storybook? Check out https://storybook.js.org/ │ │ Having trouble or want to chat? Join us at https://discord.gg/storybook/ │ │ │ ╰──────────────────────────────────────────────────────────────────────────────╯ ```

Everything went well, until here. But when it comes to start the application, this happens:

Running Storybook

> MY_VUE_PROJECT@1.0.0 storybook
> storybook dev -p 6006 --quiet

@storybook/cli v7.6.10

info => Starting manager..
info => Starting preview..
info Using SWC compiler
info Addon-docs: using MDX2
info => Using implicit CSS loaders
info => Using default Webpack5 setup
=> Failed to build the preview
TypeError: validate is not a function
    at wdm (.\node_modules\webpack-dev-middleware\dist\index.js:171:3)
    at starter (.\node_modules\@storybook\builder-webpack5\dist\index.js:1:8952)
    at async Module.start (.\node_modules\@storybook\builder-webpack5\dist\index.js:1:11672)
    at async storybookDevServer (.\node_modules\@storybook\core-server\dist\index.js:66:2459)
    at async buildOrThrow (.\node_modules\@storybook\core-server\dist\index.js:60:8290)
    at async buildDevStandalone (.\node_modules\@storybook\core-server\dist\index.js:120:1397)
    at async withTelemetry (.\node_modules\@storybook\core-server\dist\index.js:65:3948)
    at async dev (.\node_modules\@storybook\cli\dist\generate.js:503:401)
    at async Command.<anonymous> (.\node_modules\@storybook\cli\dist\generate.js:518:225)

I'm not sure how to fix this. Do I have to update some parts of my TypeScript config? My code does contain a function called validate, but my webpack build does work well.

To Reproduce

I don't want to share my whole project. So, I paste here single parts of it: Got it now: https://stackblitz.com/edit/fsd7873udj

Source files

**vue.config.js** ```javascript /* eslint-env node */ /* eslint-disable @typescript-eslint/no-var-requires */ // This file is needed for tests to be configured const path = require('path'); module.exports = { pluginOptions: { jestSerializer: { // All available options: https://github.com/beautify-web/js-beautify/blob/master/js/src/html/options.js formatting: { indent_char: ' ', indent_inner_html: true, indent_size: 4, inline: [], sep: '\n', unformatted: ['code', 'pre'], }, removeClassTest: false, removeComments: false, removeDataTest: true, removeDataTestid: true, removeDataTestId: true, removeDataQa: false, removeDataVId: true, removeIdTest: false, removeServerRendered: true, stringifyObjects: false, }, }, }; ``` **tsconfig.json** ```json { "compilerOptions": { "baseUrl": "./", "target": "es2021", "module": "es2020", "moduleResolution": "node", "jsx": "preserve", "sourceMap": true, "strict": true, "downlevelIteration": true, // This flag is to enable support for a more accurate implementation of how modern JavaScript iterates through new concepts in older JavaScript runtimes "esModuleInterop": true, "noImplicitAny": false, "noImplicitReturns": true, "noImplicitThis": true, "allowSyntheticDefaultImports": true, "lib": ["es6", "dom", "es2017", "es2016.array.include", "es2018.promise", "ES2020.String"], "paths": { "@VueForms/*": ["../Tts.Portal.VueForms/src/*"], "@/*": ["src/*"], "*": ["node_modules/*"] } } } ``` **webpack.config.js** ```javascript /* eslint-env node */ /* eslint-disable @typescript-eslint/no-var-requires */ const path = require('path'); const webpack = require('webpack'); const VueLoaderPlugin = require('vue-loader/dist/plugin').default; const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const ncp = require('ncp').ncp; const sass = require('sass'); const Dotenv = require('dotenv-webpack'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const vueFormsBundlesDir = '../web/vue-forms-bundles'; const config = { entry: { 'cart-page': './src/bundles/cartPage.ts', 'checkout-page': './src/bundles/checkoutPage.ts', 'confirmation-commerce-page': './src/bundles/confirmationCommercePage.ts', 'shipping-hint': './src/bundles/shippingHint.ts', 'cart-service': './src/bundles/cartService.ts', 'products-teaser-slider': './src/bundles/productsTeaserSlider.ts', 'product-price-information': './src/bundles/productPriceInformationContainer.ts', 'similar-jobs': './src/bundles/jobDetailsPage.ts', 'global-vue-frontend-container': './src/bundles/globalContainer.ts', 'order-overview-page': './src/bundles/orderOverviewPage.ts', 'order-quick-view': './src/bundles/orderQuickView.ts', 'order-detail-page': './src/bundles/orderDetailPage.ts', }, output: { path: path.resolve(__dirname, vueFormsBundlesDir), filename: '[name]-bundle.js', }, resolve: { extensions: ['.ts', '.js', '.vue', '.json'], modules: [path.resolve(__dirname, 'node_modules')], alias: { 'fuse.js': 'fuse.js/dist/fuse.min.js', '@': path.resolve('src'), }, }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { isCustomElement: (tag) => tag === 'lottie-player', }, }, }, { test: /\.ts$/, exclude: /node_modules/, use: { loader: 'ts-loader', options: { onlyCompileBundledFiles: true, appendTsSuffixTo: [/\.vue$/], transpileOnly: true, }, }, }, { test: /\.scss$/, use: [ 'vue-style-loader', 'css-loader', { loader: 'sass-loader', options: { implementation: sass, sourceMap: false, // On chrome there is an issue that when changing css in dev console, it breaks page. No source map fixes it. sassOptions: { quietDeps: true, // Disable warning messages from dependencies }, }, }, ], }, ], }, watchOptions: { ignored: /node_modules/, aggregateTimeout: 150, }, plugins: [ new webpack.DefinePlugin({ __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false, }), new ForkTsCheckerWebpackPlugin({ async: true, typescript: { extensions: { vue: { enabled: true, compiler: '@vue/compiler-sfc', }, }, }, issue: { exclude: [{ code: 'TS1192' }] }, // ignore `no default export` errors as known plugin issue }), // new BundleAnalyzerPlugin(), ], optimization: { splitChunks: { cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]((?!(awesome-phonenumber)).*)[\\/]/, name: 'vendors-vue-3', chunks: 'all', minChunks: 3, reuseExistingChunk: true, }, }, }, }, }; module.exports = (env, argv) => { config.plugins.push( new Dotenv({ path: `./.env`, }) ); if (argv.mode === 'development') { config.devtool = 'source-map'; config.watch = true; config.watchOptions = { aggregateTimeout: 250, ignored: ['node_modules'], }; } return config; }; ``` **package.json** ```json { "name": "MY_VUE_PROJECT", "version": "1.0.0", "scripts": { "format": "npm run format:templates && npm run lint:fix", "format:templates": "html-beautify --replace ./src/**/*.vue", "lint": "eslint ./src/** --color --config ../../.eslintrc.json", "lint:quiet": "eslint ./src/** --quiet --config ../../.eslintrc.json", "lint:fix": "eslint ./src/** --fix --config ../../.eslintrc.json", "npm-auth": "npx vsts-npm-auth -T \"%USERPROFILE%/.npmrc\" -C ./.npmrc", "webpack:dev": "webpack --mode=development --progress --stats normal", "webpack:prod": "webpack --mode=production --progress --stats errors-only", "webpack:inspect": "webpack --profile --json > stats.json", "test:unit": "jest", "test:update": "jest -u", "test:watch": "jest --watch", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" }, "browserslist": [ "> 1%", "last 2 versions" ], "private": true, "devDependencies": { "@babel/core": "^7.23.7", "@babel/helper-compilation-targets": "^7.23.6", "@babel/preset-env": "^7.23.8", "@paypal/paypal-js": "^5.1.1", "@storybook/addon-essentials": "^7.6.10", "@storybook/addon-interactions": "^7.6.10", "@storybook/addon-links": "^7.6.10", "@storybook/blocks": "^7.6.10", "@storybook/test": "^7.6.10", "@storybook/vue3": "^7.6.10", "@storybook/vue3-webpack5": "^7.6.10", "@stripe/stripe-js": "^1.48.0", "@types/googlemaps": "^3.43.3", "@types/jest": "^29.5.11", "@types/jquery": "^3.5.16", "@typescript-eslint/eslint-plugin": "^5.46.1", "@typescript-eslint/parser": "^5.46.1", "@vee-validate/rules": "4.5.11", "@vue/babel-preset-app": "^5.0.8", "@vue/compiler-sfc": "^3.4.15", "@vue/test-utils": "2.4.1", "@vue/vue3-jest": "^29.2.6", "awesome-phonenumber": "^3.2.0", "axios": "^0.27.2", "babel-jest": "^29.7.0", "css-loader": "^6.7.1", "dotenv-webpack": "^7.0.3", "eslint": "^8.29.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-jest": "^27.1.6", "eslint-plugin-prettier-vue": "^4.2.0", "eslint-plugin-storybook": "^0.6.15", "eslint-plugin-vue": "^9.19.2", "fork-ts-checker-webpack-plugin": "^6.5.2", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "jest-serializer-vue-tjw": "^3.20.0", "jest-transform-stub": "^2.0.0", "jest-watch-typeahead": "^2.2.0", "js-beautify": "^1.14.7", "jwt-decode": "^3.1.2", "lodash": "^4.17.21", "mini-css-extract-plugin": "^2.6.0", "ncp": "^2.0.0", "nswag": "^13.15.10", "prettier": "^2.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.51.0", "sass-loader": "^12.6.0", "storybook": "^7.6.10", "ts-jest": "^29.1.1", "ts-loader": "^9.5.1", "tslib": "^2.6.2", "typescript": "5.3.3", "vee-validate": "4.5.11", "vue": "3.4.7", "vue-loader": "^17.4.2", "vue-style-loader": "^4.1.3", "vuex": "^4.1.0", "webpack": "^5.72.1", "webpack-bundle-analyzer": "^4.5.0", "webpack-cli": "^4.9.2", "yup": "^0.32.11" }, "devDependenciesComments": "@vue/test-utils version 2.4.2 breaks setProps. Should be fixed with https://github.com/vuejs/test-utils/pull/2242", "files": [ "/dist/**" ], "engines": { "node": ">=14.0.0", "npm": ">=7.0.0", "vscode": "^1.57.0" } } ```

System

Storybook Environment Info:

  System:
    OS: Windows 10 10.0.19045
    CPU: (16) x64 12th Gen Intel(R) Core(TM) i7-1270P
  Binaries:
    Node: 20.5.0 - C:\Program Files\nodejs\node.EXE
    npm: 9.8.0 - C:\Program Files\nodejs\npm.CMD <----- active
  Browsers:
    Edge: Chromium (120.0.2210.144)
  npmPackages:
    @storybook/addon-essentials: ^7.6.10 => 7.6.10
    @storybook/addon-interactions: ^7.6.10 => 7.6.10
    @storybook/addon-links: ^7.6.10 => 7.6.10
    @storybook/blocks: ^7.6.10 => 7.6.10
    @storybook/test: ^7.6.10 => 7.6.10
    @storybook/vue3: ^7.6.10 => 7.6.10
    @storybook/vue3-webpack5: ^7.6.10 => 7.6.10
    eslint-plugin-storybook: ^0.6.15 => 0.6.15
    storybook: ^7.6.10 => 7.6.10

Additional context

No response

XmlmXmlmX commented 8 months ago

I already tried to update my webpack version to ^5.89.0. This didn't help.

XmlmXmlmX commented 8 months ago

So, it must be something with the package webpack-dev-middleware, in the wdm function. validate is the first call but cannot be found somehow.

shilman commented 7 months ago

Do you a have a reproduction repo you can share? If not, can you create one? Go to https://storybook.new or see repro docs. Thank you! 🙏

XmlmXmlmX commented 7 months ago

I cannot find any working example with TS+Vue+Webpack.

XmlmXmlmX commented 7 months ago

Do you a have a reproduction repo you can share? If not, can you create one? Go to https://storybook.new or see repro docs. Thank you! 🙏

Got it now: https://stackblitz.com/edit/fsd7873udj

XmlmXmlmX commented 7 months ago

Similar but not helpful: https://github.com/webpack/schema-utils/issues/152

XmlmXmlmX commented 7 months ago

Also already tried to use storybook@next (8.0.0-beta.2), same error.

AndyOGo commented 6 months ago

The problem seems to be various versions of schema-utils.

Edit: I'm working on a monorepo which had packages installing older versions of @storybook/addon-actions, @storybook/addon-docs, etc (v6 VS v7).


$ npm ls schema-utils

│ ├─┬ @storybook/react@6.5.16
│ │ ├─┬ @pmmmwh/react-refresh-webpack-plugin@0.5.11
│ │ │ └── schema-utils@3.3.0
│ │ ├─┬ @storybook/core-common@6.5.16
│ │ │ └─┬ webpack@4.47.0
│ │ │   ├── schema-utils@1.0.0
│ │ │   └─┬ terser-webpack-plugin@1.4.5
│ │ │     └── schema-utils@1.0.0 deduped
│ │ └─┬ @storybook/core@6.5.16
│ │   └─┬ @storybook/core-server@6.5.16
│ │     ├─┬ @storybook/builder-webpack4@6.5.16
│ │     │ ├─┬ @storybook/core-common@6.5.16
│ │     │ │ └─┬ fork-ts-checker-webpack-plugin@6.5.3
│ │     │ │   └── schema-utils@2.7.0 deduped
│ │     │ ├─┬ css-loader@3.6.0
│ │     │ │ └── schema-utils@2.7.0
│ │     │ ├─┬ file-loader@6.2.0
│ │     │ │ └── schema-utils@3.3.0
│ │     │ ├─┬ postcss-loader@4.3.0
│ │     │ │ └── schema-utils@3.3.0
│ │     │ ├─┬ raw-loader@4.0.2
│ │     │ │ └── schema-utils@3.3.0
│ │     │ ├─┬ style-loader@1.3.0
│ │     │ │ └── schema-utils@2.7.0 deduped
│ │     │ ├─┬ terser-webpack-plugin@4.2.3
│ │     │ │ └── schema-utils@3.3.0
│ │     │ ├─┬ url-loader@4.1.1
│ │     │ │ └── schema-utils@3.3.0
│ │     │ └─┬ webpack@4.47.0
│ │     │   ├── schema-utils@1.0.0
│ │     │   └─┬ terser-webpack-plugin@1.4.5
│ │     │     └── schema-utils@1.0.0 deduped
│ │     ├─┬ @storybook/manager-webpack4@6.5.16
│ │     │ ├─┬ css-loader@3.6.0
│ │     │ │ └── schema-utils@2.7.1 deduped
│ │     │ ├─┬ style-loader@1.3.0
│ │     │ │ └── schema-utils@2.7.1 deduped
│ │     │ ├─┬ terser-webpack-plugin@4.2.3
│ │     │ │ └── schema-utils@3.3.0
│ │     │ └─┬ webpack@4.47.0
│ │     │   ├── schema-utils@1.0.0
│ │     │   └─┬ terser-webpack-plugin@1.4.5
│ │     │     └── schema-utils@1.0.0 deduped
│ │     ├─┬ @storybook/telemetry@6.5.16
│ │     │ └─┬ @storybook/core-common@6.5.16
│ │     │   └─┬ webpack@4.47.0
│ │     │     ├── schema-utils@1.0.0
│ │     │     └─┬ terser-webpack-plugin@1.4.5
│ │     │       └── schema-utils@1.0.0 deduped
│ │     └─┬ webpack@4.47.0
│ │       ├── schema-utils@1.0.0
│ │       └─┬ terser-webpack-plugin@1.4.5
│ │         └── schema-utils@1.0.0 deduped
│ ├─┬ babel-loader@8.3.0
│ │ └── schema-utils@2.7.1
│ ├─┬ fork-ts-checker-webpack-plugin@6.5.3
│ │ └── schema-utils@2.7.0
└─┬ @storybook/react-webpack5@7.6.17
  └─┬ @storybook/builder-webpack5@7.6.17
    ├─┬ babel-loader@9.1.3
    │ └── schema-utils@4.2.0
    ├─┬ fork-ts-checker-webpack-plugin@8.0.0
    │ └── schema-utils@3.3.0
    └─┬ webpack-dev-middleware@6.1.1
      └── schema-utils@4.2.0 deduped