webpack.config.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* eslint-env node */
  2. /* eslint import/no-nodejs-modules:0 */
  3. import path from 'path';
  4. import webpack from 'webpack';
  5. import appConfig from '../webpack.config';
  6. const staticPath = path.resolve(__dirname, '..', 'static', 'app');
  7. /**
  8. * Default the config parameter that storybook passes into our webpack config
  9. * to an empty object specifically for eslint, since it will load this config
  10. * without passing in a config object.
  11. */
  12. const emptyConfig: webpack.Configuration = {
  13. module: {rules: []},
  14. resolve: {alias: {}, extensions: []},
  15. plugins: [],
  16. };
  17. type Opts = {
  18. config: webpack.Configuration;
  19. };
  20. const configBuilder = ({config}: Opts = {config: emptyConfig}) => {
  21. const [firstRule, ...rules] = (config.module?.rules ?? []) as webpack.RuleSetRule[];
  22. const filteredRules = rules.filter(rule => {
  23. const isFileLoader = !!rule?.loader?.includes('file-loader');
  24. const isPostCssLoader =
  25. Array.isArray(rule.use) &&
  26. rule.use.find(
  27. use => typeof use === 'object' && use?.loader?.includes('postcss-loader')
  28. );
  29. return !isFileLoader && !isPostCssLoader;
  30. });
  31. const extensions = new Set([
  32. ...(config.resolve?.extensions ?? []),
  33. ...(appConfig.resolve?.extensions ?? []),
  34. ]);
  35. const newConfig: webpack.Configuration = {
  36. ...config,
  37. module: {
  38. ...config.module,
  39. rules: [
  40. {
  41. ...firstRule,
  42. test: /\.(mjs|[tj]sx?)$/,
  43. include: [path.join(__dirname), staticPath, path.join(__dirname, '../docs-ui')],
  44. },
  45. {
  46. test: /\.less$/,
  47. use: ['style-loader', 'css-loader', 'less-loader'],
  48. },
  49. {
  50. test: /\.pegjs/,
  51. use: {loader: 'pegjs-loader'},
  52. },
  53. {
  54. test: /\.(woff|woff2|ttf|eot|svg|png|gif|ico|jpg)($|\?)/,
  55. type: 'asset/resource',
  56. },
  57. {
  58. test: /\.po$/,
  59. use: {
  60. loader: 'po-catalog-loader',
  61. options: {
  62. referenceExtensions: ['.js', '.jsx'],
  63. domain: 'sentry',
  64. },
  65. },
  66. },
  67. ...filteredRules,
  68. ],
  69. },
  70. plugins: [
  71. ...(config.plugins ?? []),
  72. new webpack.ProvidePlugin({jQuery: 'jquery'}),
  73. new webpack.DefinePlugin({'process.env.FIXED_DYNAMIC_CONTENT': true}),
  74. ],
  75. resolve: {
  76. ...config.resolve,
  77. extensions: Array.from(extensions),
  78. alias: {
  79. ...config.resolve?.alias,
  80. ...appConfig.resolve?.alias,
  81. app: staticPath,
  82. 'docs-ui': path.resolve(__dirname, '../docs-ui'),
  83. },
  84. fallback: {
  85. ...appConfig.resolve?.fallback,
  86. // XXX(epurkhiser): As per [0] assert is required for
  87. // @storybook/addons-docs, but seems we can just noop the pollyfill.
  88. //
  89. // [0]: https://gist.github.com/shilman/8856ea1786dcd247139b47b270912324#gistcomment-3681971
  90. assert: false,
  91. },
  92. },
  93. };
  94. return newConfig;
  95. };
  96. export default configBuilder;