main.js (7174B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* eslint-env node */ 5 6 const path = require("path"); 7 const webpack = require("webpack"); 8 const { rewriteChromeUri, rewriteMozSrcUri } = require("./moz-uri-utils.js"); 9 const mdIndexer = require("./markdown-story-indexer.js"); 10 11 const projectRoot = path.resolve(__dirname, "../../../../"); 12 13 module.exports = { 14 // The ordering for this stories array affects the order that they are displayed in Storybook 15 stories: [ 16 // Show the Storybook document first in the list 17 // so that navigating to firefoxux.github.io/firefox-desktop-components/ 18 // lands on the ComponentStatus.stories.md file 19 `../**/component-status.stories.mjs`, 20 // and lands on the Storybook.stories.md file 21 "../**/README.storybook.stories.md", 22 // Docs section 23 "../**/README.*.stories.md", 24 // UI Widgets section 25 `${projectRoot}/toolkit/content/widgets/**/*.stories.@(js|jsx|mjs|ts|tsx|md)`, 26 // about:logins components stories 27 `${projectRoot}/browser/components/aboutlogins/content/components/**/*.stories.mjs`, 28 // ASRouter components stories 29 `${projectRoot}/browser/components/asrouter/content/**/*.stories.mjs`, 30 // Backup components stories 31 `${projectRoot}/browser/components/backup/content/**/*.stories.mjs`, 32 // Settings components stories 33 `${projectRoot}/browser/components/preferences/widgets/**/*.stories.mjs`, 34 // Search components stories 35 `${projectRoot}/browser/components/search/**/*.stories.mjs`, 36 // Reader View components stories 37 `${projectRoot}/toolkit/components/reader/**/*.stories.mjs`, 38 // megalist components stories 39 `${projectRoot}/toolkit/components/satchel/megalist/content/**/*.stories.mjs`, 40 // WebRTC components stories 41 `${projectRoot}/browser/components/webrtc/content/**/*.stories.mjs`, 42 // AI Window components stories 43 `${projectRoot}/browser/components/aiwindow/ui/**/*.stories.mjs`, 44 // Multiline editor components stories 45 `${projectRoot}/browser/components/multilineeditor/**/*.stories.mjs`, 46 // Everything else 47 "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx|md)", 48 // Design system files 49 `${projectRoot}/toolkit/themes/shared/design-system/**/*.stories.@(js|jsx|mjs|ts|tsx|md)`, 50 ], 51 staticDirs: [ 52 `${projectRoot}/toolkit/themes/shared/design-system/docs/`, 53 // This allows static images to be correctly served when placed in 54 // a folder outside of the design-system/docs/ folder 55 { 56 from: `${projectRoot}/browser/components/storybook/docs/img`, 57 to: "/img", 58 }, 59 ], 60 addons: [ 61 "@storybook/addon-themes", 62 "@storybook/addon-links", 63 { 64 name: "@storybook/addon-essentials", 65 options: { 66 backgrounds: false, 67 measure: false, 68 outline: false, 69 }, 70 }, 71 "@storybook/addon-a11y", 72 path.resolve(__dirname, "addon-fluent"), 73 path.resolve(__dirname, "addon-component-status"), 74 ], 75 framework: { 76 name: "@storybook/web-components-webpack5", 77 options: {}, 78 }, 79 80 experimental_indexers: async existingIndexers => { 81 const customIndexer = { 82 test: /(stories|story)\.md$/, 83 createIndex: mdIndexer, 84 }; 85 return [...existingIndexers, customIndexer]; 86 }, 87 webpackFinal: async config => { 88 // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION' 89 // You can change the configuration based on that. 90 // 'PRODUCTION' is used when building the static version of storybook. 91 92 // Make whatever fine-grained changes you need 93 config.resolve.alias = { 94 browser: `${projectRoot}/browser`, 95 third_party: `${projectRoot}/third_party`, 96 toolkit: `${projectRoot}/toolkit`, 97 "toolkit-widgets": `${projectRoot}/toolkit/content/widgets/`, 98 "lit.all.mjs": `${projectRoot}/toolkit/content/widgets/vendor/lit.all.mjs`, 99 react: "browser/components/storybook/node_modules/react", 100 "react/jsx-runtime": 101 "browser/components/storybook/node_modules/react/jsx-runtime", 102 "@storybook/addon-docs": 103 "browser/components/storybook/node_modules/@storybook/addon-docs", 104 }; 105 106 config.plugins.push( 107 // Rewrite chrome:// URI imports to file system paths. 108 new webpack.NormalModuleReplacementPlugin(/^chrome:\/\//, resource => { 109 resource.request = rewriteChromeUri(resource.request); 110 }) 111 ); 112 113 config.plugins.push( 114 // Rewrite moz-src:/// URI imports to file system paths. 115 new webpack.NormalModuleReplacementPlugin(/^moz-src:\/\/\//, resource => { 116 resource.request = rewriteMozSrcUri(resource.request); 117 }) 118 ); 119 120 config.module.rules.push({ 121 test: /\.ftl$/, 122 type: "asset/source", 123 }); 124 125 config.module.rules.push({ 126 test: /\.m?js$/, 127 exclude: /\.storybook/, 128 use: [{ loader: path.resolve(__dirname, "./moz-styles-loader.js") }], 129 }); 130 131 // Replace the default CSS rule with a rule to emit a separate CSS file and 132 // export the URL. This allows us to rewrite the source to use CSS imports 133 // via the moz-styles-loader. 134 let cssFileTest = /\.css$/.toString(); 135 let cssRuleIndex = config.module.rules.findIndex( 136 rule => rule.test.toString() === cssFileTest 137 ); 138 config.module.rules[cssRuleIndex] = { 139 test: /\.css$/, 140 exclude: [/\.storybook/, /node_modules/], 141 type: "asset/resource", 142 generator: { 143 filename: "[name].[contenthash].css", 144 }, 145 }; 146 147 // We're adding a rule for files matching this pattern in order to support 148 // writing docs only stories in plain markdown. 149 const MD_STORY_REGEX = /(stories|story)\.md$/; 150 151 // Find the existing rule for MDX stories. 152 let mdxStoryTest = /(stories|story)\.mdx$/.toString(); 153 let mdxRule = config.module.rules.find( 154 rule => rule.test.toString() === mdxStoryTest 155 ); 156 157 // Use a custom Webpack loader to transform our markdown stories into MDX, 158 // then run our new MDX through the same loaders that Storybook usually uses 159 // for MDX files. This is how we get a docs page from plain markdown. 160 config.module.rules.push({ 161 test: MD_STORY_REGEX, 162 use: [ 163 ...mdxRule.use, 164 { loader: path.resolve(__dirname, "./markdown-story-loader.js") }, 165 ], 166 }); 167 168 // Find the existing rule for markdown files. 169 let markdownTest = /\.md$/.toString(); 170 let markdownRuleIndex = config.module.rules.findIndex( 171 rule => rule.test.toString() === markdownTest 172 ); 173 let markdownRule = config.module.rules[markdownRuleIndex]; 174 175 // Modify the existing markdown rule so it doesn't process .stories.md 176 // files, but still treats any other markdown files as asset/source. 177 config.module.rules[markdownRuleIndex] = { 178 ...markdownRule, 179 exclude: MD_STORY_REGEX, 180 }; 181 182 config.optimization = { 183 splitChunks: false, 184 runtimeChunk: false, 185 sideEffects: false, 186 usedExports: false, 187 concatenateModules: false, 188 minimizer: [], 189 }; 190 191 // Return the altered config 192 return config; 193 }, 194 };