webpack 不显示故事书mdx文件

eh57zj3b  于 2023-11-19  发布在  Webpack
关注(0)|答案(2)|浏览(139)

我使用默认的Storybook Webpack配置和我现有的数据。我在故事侧栏中没有看到任何 *.mdx文件。
首先,我只是从现有的webpack配置中替换了所有的config.module.rules规则,我得到了这个错误:Unexpected default error message

  1. Error: Unexpected default export without title: undefined
  2. at http://localhost:6006/vendors~main.iframe.bundle.js:96519:15
  3. at Array.forEach (<anonymous>)
  4. at http://localhost:6006/vendors~main.iframe.bundle.js:96512:11
  5. at ConfigApi.configure (http://localhost:6006/vendors~main.iframe.bundle.js:76149:7)
  6. at Object.configure (http://localhost:6006/vendors~main.iframe.bundle.js:96643:17)
  7. at configure (http://localhost:6006/vendors~main.iframe.bundle.js:95240:24)
  8. at Object.<anonymous> (http://localhost:6006/main.iframe.bundle.js:18:36)
  9. at Object../.storybook/generated-stories-entry.js (http://localhost:6006/main.iframe.bundle.js:19:30)
  10. at __webpack_require__ (http://localhost:6006/runtime~main.iframe.bundle.js:854:30)
  11. at fn (http://localhost:6006/runtime~main.iframe.bundle.js:151:20)

字符串
然后我为 *.mdx文件添加了这个加载器:

  1. {
  2. test: /\.(stories|story)\.mdx$/, use: [
  3. require.resolve('@mdx-js/loader'),
  4. ]
  5. }


因此,错误消失了,但也不显示 *.mdx文件。我试图以这种方式在“@mdx-js/loader”之前添加“babel-loader”:

  1. {
  2. test: /\.(stories|story)\.mdx$/,
  3. use: [
  4. {
  5. loader: require.resolve('babel-loader'),
  6. options: {
  7. plugins: ['@babel/plugin-transform-react-jsx'],
  8. },
  9. },
  10. {
  11. loader: '@mdx-js/loader',
  12. options: {
  13. compilers: [createMDXCompiler({})],
  14. },
  15. },
  16. ],
  17. }


另外,我检查了config.module.rules中规则的不同顺序,并将此规则直接添加到现有的“webpack.config”中。我注意到,“mdx”规则中的加载器无关紧要,例如,这可以正常工作,但文件仍然不显示:

  1. {
  2. test: /\.(stories|story)\.mdx$/,
  3. use: ['any text]
  4. };


mdx文件示例:

  1. import { Preview, IconGallery, IconItem } from '@storybook/addon-docs/blocks';
  2. ...
  3. import { appConfig } from '../../config/AppConfig';
  4. <Meta title='Theming/Icons' />
  5. # Icons
  6. <AppConfigContext.Provider value={appConfig}>
  7. <IconGallery>
  8. <IconItem name='ArrowDown'>
  9. <Icon variant='ArrowDown' />
  10. </IconItem>
  11. ...
  12. </AppConfigContext.Provider>


我的webpack.config.js:

  1. 'use strict';
  2. const fs = require('fs');
  3. const path = require('path');
  4. const webpack = require('webpack');
  5. const resolve = require('resolve');
  6. const PnpWebpackPlugin = require('pnp-webpack-plugin');
  7. const HtmlWebpackPlugin = require('html-webpack-plugin');
  8. const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
  9. const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
  10. const TerserPlugin = require('terser-webpack-plugin');
  11. const MiniCssExtractPlugin = require('mini-css-extract-plugin');
  12. const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
  13. const safePostCssParser = require('postcss-safe-parser');
  14. const ManifestPlugin = require('webpack-manifest-plugin');
  15. const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
  16. const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
  17. const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
  18. const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
  19. const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
  20. const ESLintPlugin = require('eslint-webpack-plugin');
  21. const paths = require('./paths');
  22. const modules = require('./modules');
  23. const getClientEnvironment = require('./env');
  24. const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
  25. const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
  26. const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
  27. const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
  28. const sites = require('./sites');
  29. const postcssNormalize = require('postcss-normalize');
  30. const appPackageJson = require(paths.appPackageJson);
  31. // Source maps are resource heavy and can cause out of memory issue for large source files.
  32. const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
  33. const webpackDevClientEntry = require.resolve(
  34. 'react-dev-utils/webpackHotDevClient'
  35. );
  36. const reactRefreshOverlayEntry = require.resolve(
  37. 'react-dev-utils/refreshOverlayInterop'
  38. );
  39. // Some apps do not need the benefits of saving a web request, so not inlining the chunk
  40. // makes for a smoother build process.
  41. const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
  42. const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === 'true';
  43. const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === 'true';
  44. const imageInlineSizeLimit = parseInt(
  45. process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
  46. );
  47. const SITE = process.env.SITE?.toLowerCase() || sites[0];
  48. if (!sites.includes(SITE)) {
  49. throw new Error(
  50. `Value of SITE: ${SITE} is not valid value. Please use one of the following [${sites.toString()}]`
  51. );
  52. }
  53. // Check if TypeScript is setup
  54. const useTypeScript = fs.existsSync(paths.appTsConfig);
  55. // Get the path to the uncompiled service worker (if it exists).
  56. const swSrc = paths.swSrc;
  57. // style files regexes
  58. const cssRegex = /\.css$/;
  59. const cssModuleRegex = /\.module\.css$/;
  60. const sassRegex = /\.(scss|sass)$/;
  61. const sassModuleRegex = /\.module\.(scss|sass)$/;
  62. const hasJsxRuntime = (() => {
  63. if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
  64. return false;
  65. }
  66. try {
  67. require.resolve('react/jsx-runtime');
  68. return true;
  69. } catch (e) {
  70. return false;
  71. }
  72. })();
  73. const getRegexForIgnoreStyles = (app) => {
  74. const test = new RegExp(
  75. `\\.(${sites.filter((site) => site !== app).join('|')})\\.scss`
  76. );
  77. return { test, loader: require.resolve('ignore-loader') };
  78. };
  79. // This is the production and development configuration.
  80. // It is focused on developer experience, fast rebuilds, and a minimal bundle.
  81. module.exports = function (webpackEnv) {
  82. const isEnvDevelopment = webpackEnv === 'development';
  83. const isEnvProduction = webpackEnv === 'production';
  84. // Variable used for enabling profiling in Production
  85. // passed into alias object. Uses a flag if passed into the build command
  86. const isEnvProductionProfile =
  87. isEnvProduction && process.argv.includes('--profile');
  88. // We will provide `paths.publicUrlOrPath` to our app
  89. // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
  90. // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
  91. // Get environment variables to inject into our app.
  92. const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
  93. const shouldUseReactRefresh = env.raw.FAST_REFRESH;
  94. // common function to get style loaders
  95. const getStyleLoaders = (cssOptions, preProcessor) => {
  96. const loaders = [
  97. isEnvDevelopment && require.resolve('style-loader'),
  98. isEnvProduction && {
  99. loader: MiniCssExtractPlugin.loader,
  100. // css is located in `static/css`, use '../../' to locate index.html folder
  101. // in production `paths.publicUrlOrPath` can be a relative path
  102. options: paths.publicUrlOrPath.startsWith('.')
  103. ? { publicPath: '../../' }
  104. : {}
  105. },
  106. {
  107. loader: require.resolve('css-loader'),
  108. options: { ...cssOptions, url: false }
  109. },
  110. {
  111. // Options for PostCSS as we reference these options twice
  112. // Adds vendor prefixing based on your specified browser support in
  113. // package.json
  114. loader: require.resolve('postcss-loader'),
  115. options: {
  116. // Necessary for external CSS imports to work
  117. // https://github.com/facebook/create-react-app/issues/2677
  118. ident: 'postcss',
  119. plugins: () => [
  120. require('postcss-flexbugs-fixes'),
  121. require('postcss-preset-env')({
  122. autoprefixer: {
  123. flexbox: 'no-2009'
  124. },
  125. stage: 3
  126. }),
  127. // Adds PostCSS Normalize as the reset css with default options,
  128. // so that it honors browserslist config in package.json
  129. // which in turn let's users customize the target behavior as per their needs.
  130. postcssNormalize()
  131. ],
  132. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment
  133. }
  134. }
  135. ].filter(Boolean);
  136. if (preProcessor) {
  137. const options = { sourceMap: true };
  138. if (preProcessor === 'sass-loader') {
  139. options.additionalData = `$assets-url: '${process.env.REACT_APP_ASSETS_URL}';`;
  140. }
  141. loaders.push(
  142. {
  143. loader: require.resolve('resolve-url-loader'),
  144. options: {
  145. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
  146. root: paths.appSrc
  147. }
  148. },
  149. {
  150. loader: require.resolve(preProcessor),
  151. options: {
  152. sourceMap: true
  153. }
  154. }
  155. );
  156. }
  157. return loaders;
  158. };
  159. const baseConfig = {
  160. ...
  161. }
  162. ...
  163. const baseRules = {
  164. // "oneOf" will traverse all following loaders until one will
  165. // match the requirements. When no loader matches it will fall
  166. // back to the "file" loader at the end of the loader list.
  167. oneOf: [
  168. // TODO: Merge this config once `image/avif` is in the mime-db
  169. // https://github.com/jshttp/mime-db
  170. {
  171. test: [/\.avif$/],
  172. loader: require.resolve('url-loader'),
  173. options: {
  174. limit: imageInlineSizeLimit,
  175. mimetype: 'image/avif',
  176. name: 'static/media/[name].[hash:8].[ext]'
  177. }
  178. },
  179. // "url" loader works like "file" loader except that it embeds assets
  180. // smaller than specified limit in bytes as data URLs to avoid requests.
  181. // A missing `test` is equivalent to a match.
  182. {
  183. test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
  184. loader: require.resolve('url-loader'),
  185. options: {
  186. limit: imageInlineSizeLimit,
  187. name: 'static/media/[name].[hash:8].[ext]'
  188. }
  189. },
  190. // Process application JS with Babel.
  191. // The preset includes JSX, Flow, TypeScript, and some ESnext features.
  192. {
  193. test: /\.(js|mjs|jsx|ts|tsx)$/,
  194. include: paths.appSrc,
  195. loader: require.resolve('babel-loader'),
  196. options: {
  197. customize: require.resolve(
  198. 'babel-preset-react-app/webpack-overrides'
  199. ),
  200. presets: [
  201. [
  202. require.resolve('babel-preset-react-app'),
  203. {
  204. runtime: hasJsxRuntime ? 'automatic' : 'classic'
  205. }
  206. ]
  207. ],
  208. plugins: [
  209. [
  210. require.resolve('babel-plugin-named-asset-import'),
  211. {
  212. loaderMap: {
  213. svg: {
  214. ReactComponent: '@svgr/webpack?-svgo,+titleProp,+ref![path]'
  215. }
  216. }
  217. }
  218. ]
  219. ],
  220. // This is a feature of `babel-loader` for webpack (not Babel itself).
  221. // It enables caching results in ./node_modules/.cache/babel-loader/
  222. // directory for faster rebuilds.
  223. cacheDirectory: true,
  224. // See #6846 for context on why cacheCompression is disabled
  225. cacheCompression: false,
  226. compact: isEnvProduction
  227. }
  228. },
  229. // Process any JS outside of the app with Babel.
  230. // Unlike the application JS, we only compile the standard ES features.
  231. {
  232. test: /\.(js|mjs)$/,
  233. exclude: /@babel(?:\/|\\{1,2})runtime/,
  234. loader: require.resolve('babel-loader'),
  235. options: {
  236. babelrc: false,
  237. configFile: false,
  238. compact: false,
  239. presets: [
  240. [
  241. require.resolve('babel-preset-react-app/dependencies'),
  242. { helpers: true }
  243. ]
  244. ],
  245. cacheDirectory: true,
  246. // See #6846 for context on why cacheCompression is disabled
  247. cacheCompression: false,
  248. // Babel sourcemaps are needed for debugging into node_modules
  249. // code. Without the options below, debuggers like VSCode
  250. // show incorrect code and set breakpoints on the wrong lines.
  251. sourceMaps: shouldUseSourceMap,
  252. inputSourceMap: shouldUseSourceMap
  253. }
  254. },
  255. // "postcss" loader applies autoprefixer to our CSS.
  256. // "css" loader resolves paths in CSS and adds assets as dependencies.
  257. // "style" loader turns CSS into JS modules that inject <style> tags.
  258. // In production, we use MiniCSSExtractPlugin to extract that CSS
  259. // to a file, but in development "style" loader enables hot editing
  260. // of CSS.
  261. // By default we support CSS Modules with the extension .module.css
  262. {
  263. test: cssRegex,
  264. exclude: cssModuleRegex,
  265. use: getStyleLoaders({
  266. importLoaders: 1,
  267. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment
  268. }),
  269. // Don't consider CSS imports dead code even if the
  270. // containing package claims to have no side effects.
  271. // Remove this when webpack adds a warning or an error for this.
  272. // See https://github.com/webpack/webpack/issues/6571
  273. sideEffects: true
  274. },
  275. // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
  276. // using the extension .module.css
  277. {
  278. test: cssModuleRegex,
  279. use: getStyleLoaders({
  280. importLoaders: 1,
  281. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
  282. modules: {
  283. getLocalIdent: getCSSModuleLocalIdent
  284. }
  285. })
  286. },
  287. // Opt-in support for SASS (using .scss or .sass extensions).
  288. // By default we support SASS Modules with the
  289. // extensions .module.scss or .module.sass
  290. {
  291. test: sassRegex,
  292. exclude: sassModuleRegex,
  293. use: getStyleLoaders(
  294. {
  295. importLoaders: 3,
  296. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment
  297. },
  298. 'sass-loader'
  299. ),
  300. // Don't consider CSS imports dead code even if the
  301. // containing package claims to have no side effects.
  302. // Remove this when webpack adds a warning or an error for this.
  303. // See https://github.com/webpack/webpack/issues/6571
  304. sideEffects: true
  305. },
  306. // Adds support for CSS Modules, but using SASS
  307. // using the extension .module.scss or .module.sass
  308. {
  309. test: sassModuleRegex,
  310. use: getStyleLoaders(
  311. {
  312. importLoaders: 3,
  313. sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
  314. modules: {
  315. getLocalIdent: getCSSModuleLocalIdent
  316. }
  317. },
  318. 'sass-loader'
  319. )
  320. },
  321. // "file" loader makes sure those assets get served by WebpackDevServer.
  322. // When you `import` an asset, you get its (virtual) filename.
  323. // In production, they would get copied to the `build` folder.
  324. // This loader doesn't use a "test" so it will catch all modules
  325. // that fall through the other loaders.
  326. {
  327. loader: require.resolve('file-loader'),
  328. // Exclude `js` files to keep "css" loader working as it injects
  329. // its runtime that would otherwise be processed through "file" loader.
  330. // Also exclude `html` and `json` extensions so they get processed
  331. // by webpacks internal loaders.
  332. exclude: [/\.(js|mjs|jsx|ts|tsx|ejs)$/, /\.html$/, /\.json$/],
  333. options: {
  334. name: 'static/media/[name].[hash:8].[ext]'
  335. }
  336. }
  337. // ** STOP ** Are you adding a new loader?
  338. // Make sure to add the new loader(s) before the "file" loader.
  339. ]
  340. };
  341. const configs = sites
  342. .map((brand) => {
  343. return {
  344. ...baseConfig,
  345. name: brand,
  346. entry: isEnvProduction
  347. ? { [brand]: paths.appIndexJs }
  348. : [paths.appIndexJs],
  349. module: {
  350. ...baseConfig.module,
  351. rules: [
  352. ...baseConfig.module.rules,
  353. {
  354. oneOf: [getRegexForIgnoreStyles(brand), ...baseRules.oneOf]
  355. }
  356. ]
  357. },
  358. plugins: [...baseConfig.plugins].filter(Boolean)
  359. };
  360. })
  361. .reduce((acc, item) => {
  362. return { ...acc, [item.name]: item };
  363. }, {});
  364. return isEnvProduction ? [...Object.values(configs)] : configs[SITE];
  365. };

uxh89sit

uxh89sit1#

所以,主要的事情是,*.mdx文件加载成功只使用默认的Storybook配置,因此它排除了任何语法错误.作为最后的决定,我只是从Storybook中删除所有*.mdx文件,并创建新的*.tsx在目标Storybook列表块使用所有需要的额外样式相同的内容.

7rfyedvj

7rfyedvj2#

TL;DR

  • 遵循Storybook默认的*.stories.mdx命名约定
  • 确保在<Meta title="..." />标记后面没有尾随的;-类似这样的东西打破了故事<Meta title="..." />;
  • 此外,隐藏文件夹中的故事(文件夹名称以.开头-例如.stories/my.stories.ts)也将被忽略。在这些情况下,从文件夹名称中删除.
  • 当您在<Story><Canvas>(或任何其他storybook-mdx-component)之后添加一些html标签(例如<br/>)时,请确保在<Story><br/>之间添加换行符。否则,这也会导致错误,使文件消失。

详情

在我的例子中,问题是我不想使用Storybook的默认命名约定*.stories.mdx,我试图省略.stories部分(即拥有像button.mdx而不是button.stories.mdx这样的文件)并相应地重新配置main.js。但这似乎不起作用-没有mdx-一旦我恢复到.stories.mdx,mdx文件再次显示在故事书侧栏中。

更新

我注意到的另一个问题非常微妙,很容易被忽略。如果你或你的代码格式化程序在你的<Meta title="...">标签后添加了;,你的文件将不会显示在侧边栏中。所以要注意:

  1. <!-- note the trailing ";" -->
  2. <Meta title="My/Title" />;
  3. <!-- after removing it, your file will show again -->
  4. <Meta title="My/Title" />

字符串

展开查看全部

相关问题