@patternfly/documentation-framework 2.0.0-alpha.2 → 2.0.0-alpha.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,15 +5,16 @@ import {
5
5
  PageSidebar,
6
6
  Brand,
7
7
  Dropdown,
8
- DropdownToggle,
9
8
  DropdownItem,
10
9
  DropdownGroup,
10
+ DropdownList,
11
11
  Divider,
12
12
  Masthead,
13
13
  MastheadToggle,
14
14
  MastheadMain,
15
15
  MastheadContent,
16
16
  MastheadBrand,
17
+ MenuToggle,
17
18
  PageToggleButton,
18
19
  Toolbar,
19
20
  ToolbarGroup,
@@ -23,7 +24,6 @@ import {
23
24
  Switch,
24
25
  SearchInput
25
26
  } from '@patternfly/react-core';
26
- import ExternalLinkAltIcon from '@patternfly/react-icons/dist/esm/icons/external-link-alt-icon';
27
27
  import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
28
28
  import GithubIcon from '@patternfly/react-icons/dist/esm/icons/github-icon';
29
29
  import { SideNav, TopNav, GdprBanner } from '../../components';
@@ -48,14 +48,9 @@ const HeaderTools = ({
48
48
  const [isSearchExpanded, setIsSearchExpanded] = React.useState(false);
49
49
 
50
50
  const getDropdownItem = (version, isLatest = false) => (
51
- <DropdownItem
52
- key={version.name}
53
- component={
54
- <a href={isLatest ? '/' : `/${version.name}`}>
55
- {`Release ${version.name}`}
56
- </a>
57
- }
58
- />
51
+ <DropdownItem itemId={version.name} key={version.name} to={isLatest ? '/' : `/${version.name}`}>
52
+ {`Release ${version.name}`}
53
+ </DropdownItem>
59
54
  );
60
55
 
61
56
  const onChange = (_evt, value) => {
@@ -82,7 +77,7 @@ const HeaderTools = ({
82
77
  </ToolbarItem>
83
78
  )}
84
79
  <ToolbarGroup
85
- alignment={{ default: 'alignRight' }}
80
+ align={{ default: 'alignRight' }}
86
81
  spaceItems={{ default: 'spacerNone', md: 'spacerMd' }}
87
82
  >
88
83
  {hasDarkThemeSwitcher && (
@@ -117,42 +112,60 @@ const HeaderTools = ({
117
112
  {hasVersionSwitcher && (
118
113
  <ToolbarItem>
119
114
  <Dropdown
120
- isFullHeight
121
115
  onSelect={() => setDropdownOpen(!isDropdownOpen)}
116
+ onOpenChange={(isOpen) => setDropdownOpen(isOpen)}
122
117
  isOpen={isDropdownOpen}
123
- toggle={(
124
- <DropdownToggle
125
- onToggle={() => setDropdownOpen(!isDropdownOpen)}
118
+ toggle={(toggleRef) => (
119
+ <MenuToggle
120
+ isFullHeight
121
+ ref={toggleRef}
122
+ onClick={() => setDropdownOpen(!isDropdownOpen)}
123
+ isExpanded={isDropdownOpen}
126
124
  >
127
125
  Release {initialVersion.name}
128
- </DropdownToggle>
126
+ </MenuToggle>
129
127
  )}
130
- dropdownItems={[
131
- <DropdownGroup key="latest" label="Latest">
128
+ >
129
+ <DropdownGroup key="Latest" label="Latest">
130
+ <DropdownList>
132
131
  {getDropdownItem(latestVersion, true)}
133
- </DropdownGroup>,
134
- <DropdownGroup key="Previous" label="Previous releases">
132
+ </DropdownList>
133
+ </DropdownGroup>
134
+ <DropdownGroup key="Previous releases" label="Previous releases">
135
+ <DropdownList>
135
136
  {Object.values(versions.Releases)
136
137
  .filter(version => !version.hidden && !version.latest)
137
138
  .slice(0,3)
138
139
  .map(version => getDropdownItem(version))}
139
- </DropdownGroup>,
140
- <Divider key="divider" className="ws-switcher-divider"/>,
141
- <DropdownItem
142
- key="PatternFly 3"
143
- className="ws-patternfly-3"
144
- target="_blank"
145
- href="https://pf3.patternfly.org/"
146
- >
147
- PatternFly 3
148
- <ExternalLinkAltIcon />
149
- </DropdownItem>
150
- ]}
151
- />
140
+ </DropdownList>
141
+ </DropdownGroup>
142
+ <Divider key="divider" className="ws-switcher-divider"/>
143
+ <DropdownGroup key="Previous versions" label="Previous versions">
144
+ <DropdownList>
145
+ <DropdownItem
146
+ key="PatternFly 4"
147
+ className="ws-patternfly-3"
148
+ isExternalLink
149
+ to="http://v4-archive.patternfly.org/v4/"
150
+ itemId="patternfly-4"
151
+ >
152
+ PatternFly 4
153
+ </DropdownItem>
154
+ <DropdownItem
155
+ key="PatternFly 3"
156
+ className="ws-patternfly-3"
157
+ isExternalLink
158
+ to="https://pf3.patternfly.org/"
159
+ itemId="patternfly-3"
160
+ >
161
+ PatternFly 3
162
+ </DropdownItem>
163
+ </DropdownList>
164
+ </DropdownGroup>
165
+ </Dropdown>
152
166
  </ToolbarItem>
153
167
  )}
154
- </ToolbarGroup>
155
- </ToolbarContent>
168
+ </ToolbarGroup></ToolbarContent>
156
169
  </Toolbar>
157
170
  );
158
171
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@patternfly/documentation-framework",
3
3
  "description": "A framework to build documentation for PatternFly.",
4
- "version": "2.0.0-alpha.2",
4
+ "version": "2.0.0-alpha.20",
5
5
  "author": "Red Hat",
6
6
  "license": "MIT",
7
7
  "private": false,
@@ -22,19 +22,19 @@
22
22
  "@babel/preset-env": "7.18.2",
23
23
  "@mdx-js/util": "1.6.16",
24
24
  "@patternfly/ast-helpers": "^0.4.57",
25
- "@reach/router": "1.3.4",
25
+ "@reach/router": "npm:@gatsbyjs/reach-router@1.3.9",
26
26
  "autoprefixer": "9.8.6",
27
- "babel-loader": "8.2.5",
27
+ "babel-loader": "9.1.2",
28
28
  "camelcase-css": "2.0.1",
29
29
  "chokidar": "3.5.3",
30
- "clean-webpack-plugin": "3.0.0",
30
+ "clean-webpack-plugin": "4.0.0",
31
31
  "codesandbox": "2.2.0",
32
32
  "commander": "4.1.1",
33
- "copy-webpack-plugin": "6.1.0",
34
- "css-loader": "4.3.0",
33
+ "copy-webpack-plugin": "11.0.0",
34
+ "css-loader": "6.7.3",
35
35
  "detab": "2.0.3",
36
36
  "express": "4.18.1",
37
- "file-loader": "6.1.0",
37
+ "file-loader": "6.2.0",
38
38
  "file-saver": "1.3.8",
39
39
  "fs-extra": "9.0.1",
40
40
  "glob": "8.0.3",
@@ -42,29 +42,30 @@
42
42
  "hast-to-hyperscript": "9.0.0",
43
43
  "hast-util-to-text": "2.0.0",
44
44
  "html-formatter": "0.1.9",
45
- "html-webpack-plugin": "4.4.1",
45
+ "html-webpack-plugin": "5.5.0",
46
46
  "js-yaml": "3.14.0",
47
47
  "mdast-util-to-hast": "9.1.1",
48
48
  "mdurl": "1.0.1",
49
- "mini-css-extract-plugin": "1.3.9",
50
- "monaco-editor": "0.21.3",
51
- "monaco-editor-webpack-plugin": "2.1.0",
52
- "null-loader": "4.0.0",
49
+ "mini-css-extract-plugin": "2.7.5",
50
+ "monaco-editor": "0.34.1",
51
+ "monaco-editor-webpack-plugin": "7.0.1",
53
52
  "parse-entities": "2.0.0",
53
+ "path-browserify": "1.0.1",
54
54
  "postcss": "7.0.32",
55
- "postcss-loader": "4.2.0",
55
+ "postcss-loader": "7.1.0",
56
+ "process": "^0.11.10",
56
57
  "puppeteer": "14.3.0",
57
58
  "puppeteer-cluster": "0.23.0",
58
59
  "react-docgen": "5.3.1",
59
- "react-monaco-editor": "0.48.0",
60
- "react-ssr-prepass": "1.2.1",
60
+ "react-monaco-editor": "^0.51.0",
61
+ "react-ssr-prepass": "1.5.0",
61
62
  "remark-footnotes": "1.0.0",
62
63
  "remark-frontmatter": "2.0.0",
63
64
  "remark-mdx": "2.0.0-next.8",
64
65
  "remark-mdxjs": "2.0.0-next.8",
65
66
  "remark-parse": "8.0.3",
66
67
  "remark-squeeze-paragraphs": "4.0.0",
67
- "responsive-loader": "2.1.1",
68
+ "responsive-loader": "3.1.2",
68
69
  "sharp": "0.30.6",
69
70
  "style-to-object": "0.3.0",
70
71
  "to-vfile": "6.1.0",
@@ -74,19 +75,19 @@
74
75
  "unist-util-visit": "2.0.3",
75
76
  "url-loader": "4.1.0",
76
77
  "vfile-reporter": "6.0.1",
77
- "webpack": "4.44.1",
78
- "webpack-bundle-analyzer": "3.8.0",
79
- "webpack-cli": "3.3.12",
80
- "webpack-dev-server": "3.11.0",
78
+ "webpack": "5.76.3",
79
+ "webpack-bundle-analyzer": "4.8.0",
80
+ "webpack-cli": "5.0.1",
81
+ "webpack-dev-server": "4.13.1",
81
82
  "webpack-merge": "5.8.0"
82
83
  },
83
84
  "peerDependencies": {
84
- "@patternfly/patternfly": "^5.0.0-alpha.13",
85
- "@patternfly/react-code-editor": "^5.0.0-alpha.7",
86
- "@patternfly/react-core": "^5.0.0-alpha.7",
87
- "@patternfly/react-table": "^5.0.0-alpha.7",
85
+ "@patternfly/patternfly": "^5.0.0-alpha.37",
86
+ "@patternfly/react-code-editor": "^5.0.0-alpha.54",
87
+ "@patternfly/react-core": "^5.0.0-alpha.53",
88
+ "@patternfly/react-table": "^5.0.0-alpha.54",
88
89
  "react": "^17.0.0 || ^18.0.0",
89
90
  "react-dom": "^17.0.0 || ^18.0.0"
90
91
  },
91
- "gitHead": "b1c7b0dd197680e7e69b9057d180b66a63af8ccc"
92
+ "gitHead": "421584878eaf3a8b4bce4f8ac45238c6b2c3557c"
92
93
  }
@@ -6,7 +6,7 @@ import {
6
6
  CardTitle,
7
7
  CardBody,
8
8
  CardFooter,
9
- CardHeaderMain,
9
+ CardHeader,
10
10
  EmptyState,
11
11
  EmptyStateBody,
12
12
  EmptyStateIcon,
@@ -36,9 +36,9 @@ const Card404 = ({
36
36
  }) => (
37
37
  <GridItem xl={3} md={6} xs={12}>
38
38
  <Card style={{ height: '340px' }}>
39
- <CardHeaderMain className="ws-404-card-header">
39
+ <CardHeader className="ws-404-card-header">
40
40
  <img src={img} alt={alt} width="64px" />
41
- </CardHeaderMain>
41
+ </CardHeader>
42
42
  <CardTitle>
43
43
  {title}
44
44
  </CardTitle>
package/routes.js CHANGED
@@ -9,6 +9,8 @@ const routes = {
9
9
  ...generatedRoutes
10
10
  };
11
11
 
12
+ const defaultOrder = 50;
13
+
12
14
  for (let route in routes) {
13
15
  const pageData = routes[route];
14
16
  if (pageData.SyncComponent) {
@@ -28,7 +30,7 @@ const isNull = o => o === null || o === undefined;
28
30
  const groupedRoutes = Object.entries(routes)
29
31
  .filter(([_slug, { id, section }]) => !isNull(id) && !isNull(section))
30
32
  .reduce((accum, [slug, pageData]) => {
31
- const { section, subsection = null, id, title, source, katacodaLayout, hideNavItem, relPath } = pageData;
33
+ const { section, subsection = null, id, title, source, katacodaLayout, hideNavItem, relPath, sortValue = null, subsectionSortValue = null } = pageData;
32
34
  pageData.slug = slug;
33
35
  // add section to groupedRoutes obj if not yet created
34
36
  accum[section] = accum[section] || {};
@@ -42,7 +44,9 @@ const groupedRoutes = Object.entries(routes)
42
44
  sources: [],
43
45
  katacodaLayout,
44
46
  hideNavItem,
45
- relPath
47
+ relPath,
48
+ ...(sortValue && { sortValue }),
49
+ ...(subsectionSortValue && { subsectionSortValue })
46
50
  }
47
51
  // add page to groupedRoutes obj section or subsection
48
52
  if (subsection) {
@@ -52,10 +56,21 @@ const groupedRoutes = Object.entries(routes)
52
56
  // add page to subsection
53
57
  accum[section][subsection][id] = accum[section][subsection][id] || data;
54
58
  accum[section][subsection][id].sources.push(pageData);
59
+ // nav item ordering
60
+ if (sortValue) {
61
+ accum[section][subsection].sortValue = sortValue;
62
+ }
63
+ if (subsectionSortValue) {
64
+ accum[section][subsection].subsectionSortValue = subsectionSortValue;
65
+ }
55
66
  } else {
56
67
  // add page to section
57
68
  accum[section][id] = accum[section][id] || data;
58
69
  accum[section][id].sources.push(pageData);
70
+ // nav item ordering
71
+ if (sortValue) {
72
+ accum[section][id].sortValue = sortValue;
73
+ }
59
74
  }
60
75
 
61
76
  return accum;
@@ -73,7 +88,6 @@ const sourceOrder = {
73
88
  'design-guidelines': 99,
74
89
  'accessibility': 100
75
90
  };
76
- const defaultOrder = 50;
77
91
 
78
92
  const sortSources = ({ source: s1 }, { source: s2 }) => {
79
93
  const s1Index = sourceOrder[s1] || defaultOrder;
@@ -108,7 +122,8 @@ Object.entries(groupedRoutes)
108
122
  // Loop through each page in expandable subsection
109
123
  if (pageData.isSubsection) {
110
124
  Object.entries(pageData).map(([section, ids]) => {
111
- if (section !== 'isSubsection') {
125
+ // only push nested page objects
126
+ if (ids && ids?.id) {
112
127
  pageDataArr.push(ids);
113
128
  }
114
129
  })
@@ -50,6 +50,11 @@ async function execFile(file, args) {
50
50
  const child_execArgv = [
51
51
  '--max-old-space-size=4096'
52
52
  ];
53
+
54
+ if (args.legacySSL) {
55
+ child_execArgv.push('--openssl-legacy-provider')
56
+ }
57
+
53
58
  const child = fork(path.join(__dirname, file), child_argv, { execArgv: child_execArgv });
54
59
  function errorHandler(err) {
55
60
  console.error(err);
@@ -78,6 +83,7 @@ async function build(cmd, options) {
78
83
  const config = getConfig(options);
79
84
  config.analyze = options.analyze;
80
85
  config.output = options.output;
86
+ config.legacySSL = options.legacySSL
81
87
 
82
88
  // These get passed to `fork`ed builds
83
89
  process.env.pathPrefix = config.pathPrefix;
@@ -26,6 +26,7 @@ program
26
26
  .command('build <server|client|all>')
27
27
  .option('-a, --analyze', 'use webpack-bundle-analyzer', false)
28
28
  .option('-o, --output <folder>', 'output folder', 'public')
29
+ .option('--legacySSL', 'use legacy version of openssl, needed to support Node 18 until we upgrade webpack to v5', false)
29
30
  .description('generates source files and runs webpack')
30
31
  .action((cmd, options) => {
31
32
  const { build } = require('./build');
@@ -6,17 +6,15 @@ const { getConfig } = require('./helpers');
6
6
  const { watchMD } = require('../md/parseMD');
7
7
 
8
8
  function startWebpackDevServer(webpackConfig) {
9
- webpackConfig.devServer.filename = webpackConfig.output.filename;
10
- webpackConfig.devServer.publicPath = webpackConfig.output.publicPath;
9
+ webpackConfig.devServer.static.publicPath = webpackConfig.output.publicPath;
11
10
  const { port } = webpackConfig.devServer;
12
11
  const compiler = webpack(webpackConfig);
13
- const server = new WebpackDevServer(compiler, webpackConfig.devServer);
12
+ const server = new WebpackDevServer(webpackConfig.devServer, compiler);
14
13
 
15
- server.listen(port, 'localhost', err => {
16
- if (err) {
17
- console.log(err);
18
- }
19
- });
14
+ (async () => {
15
+ await server.start();
16
+ console.log(`Dev server is listening on port ${port}`);
17
+ })();
20
18
  }
21
19
 
22
20
  async function start(options) {
@@ -85,6 +85,7 @@ function toReactComponent(mdFilePath, source, buildMode) {
85
85
  section: frontmatter.section || '',
86
86
  subsection: frontmatter.subsection || '',
87
87
  source,
88
+ tabName: frontmatter.tabName || null,
88
89
  slug,
89
90
  sourceLink: frontmatter.sourceLink || `https://github.com/patternfly/${
90
91
  sourceRepo}/blob/main/${
@@ -126,6 +127,12 @@ function toReactComponent(mdFilePath, source, buildMode) {
126
127
  if (frontmatter.hideNavItem) {
127
128
  pageData.hideNavItem = frontmatter.hideNavItem;
128
129
  }
130
+ if (frontmatter.sortValue) {
131
+ pageData.sortValue = frontmatter.sortValue;
132
+ }
133
+ if (frontmatter.subsectionSortValue) {
134
+ pageData.subsectionSortValue = frontmatter.subsectionSortValue;
135
+ }
129
136
  })
130
137
  // Delete HTML comments
131
138
  .use(require('./remove-comments'))
@@ -266,8 +273,11 @@ function sourceMDFile(file, source, buildMode) {
266
273
  section: pageData.section,
267
274
  subsection: pageData.subsection,
268
275
  source: pageData.source,
276
+ tabName: pageData.tabName,
269
277
  ...(pageData.katacodaLayout && { katacodaLayout: pageData.katacodaLayout }),
270
- ...(pageData.hideNavItem && { hideNavItem: pageData.hideNavItem })
278
+ ...(pageData.hideNavItem && { hideNavItem: pageData.hideNavItem }),
279
+ ...(pageData.sortValue && { sortValue: pageData.sortValue }),
280
+ ...(pageData.subsectionSortValue && { subsectionSortValue: pageData.subsectionSortValue })
271
281
  };
272
282
  }
273
283
  }
@@ -8,6 +8,7 @@ module.exports = (_env, argv) => {
8
8
  const {
9
9
  pathPrefix = '',
10
10
  mode,
11
+ googleAnalyticsID = false,
11
12
  algolia = {},
12
13
  hasGdprBanner = false,
13
14
  hasFooter = false,
@@ -27,7 +28,8 @@ module.exports = (_env, argv) => {
27
28
  output: {
28
29
  publicPath: isProd ? `${pathPrefix}/` : '/',
29
30
  pathinfo: false, // https://webpack.js.org/guides/build-performance/#output-without-path-info,
30
- hashDigestLength: 8
31
+ hashDigestLength: 8,
32
+ clean: true, // Clean the output directory before emit.
31
33
  },
32
34
  amd: false, // We don't use any AMD modules, helps performance
33
35
  mode: isProd ? 'production' : 'development',
@@ -39,9 +41,12 @@ module.exports = (_env, argv) => {
39
41
  include: [
40
42
  path.resolve(process.cwd(), 'src'),
41
43
  path.resolve(process.cwd(), 'patternfly-docs'),
44
+ path.resolve(process.cwd(), 'examples'),
42
45
  path.resolve(__dirname, '../..'), // Temporarily compile theme using webpack for development
43
46
  /react-[\w-]+\/src\/.*\/examples/,
44
47
  /react-[\w-]+\\src\\.*\\examples/, // fix for Windows
48
+ /react-[\w-]+\/patternfly-docs\/.*\/examples/, //fixes for extensions
49
+ /react-[\w-]+\\patternfly-docs\\.*\\examples/,
45
50
  ].concat(includePaths.map(path => new RegExp(path))),
46
51
  exclude: [
47
52
  path.resolve(__dirname, '../../node_modules'), // Temporarily compile theme using webpack for development
@@ -82,35 +87,28 @@ module.exports = (_env, argv) => {
82
87
  },
83
88
  {
84
89
  test: /\.(gif|svg)$/,
85
- use: {
86
- loader: 'file-loader',
87
- options: {
88
- name: '[name].[contenthash].[ext]',
89
- outputPath: 'images/'
90
- },
90
+ type: 'asset/resource',
91
+ dependency: { not: ['url'] },
92
+ generator: {
93
+ filename: 'images/[hash][ext][query]'
91
94
  }
92
95
  },
93
96
  {
94
97
  test: /\.(pdf)$/,
95
- use: {
96
- loader: 'file-loader',
97
- options: {
98
- name: '[name].[contenthash].[ext]',
99
- }
98
+ type: 'asset/resource',
99
+ dependency: { not: ['url'] },
100
+ generator: {
101
+ filename: '[hash][ext][query]'
100
102
  }
101
103
  },
102
104
  {
103
105
  test: /.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
104
- use: [
105
- {
106
- loader: 'file-loader',
107
- options: {
108
- name: '[name].[ext]',
109
- outputPath: 'fonts/'
110
- }
111
- }
112
- ]
113
- }
106
+ type: 'asset/resource',
107
+ dependency: { not: ['url'] },
108
+ generator: {
109
+ filename: 'fonts/[name][ext][query]'
110
+ }
111
+ },
114
112
  ]
115
113
  },
116
114
  resolve: {
@@ -118,21 +116,29 @@ module.exports = (_env, argv) => {
118
116
  alias: {
119
117
  'client-styles': path.resolve(process.cwd(), 'patternfly-docs/patternfly-docs.css.js'),
120
118
  './routes-client': path.resolve(process.cwd(), 'patternfly-docs/patternfly-docs.routes.js'),
121
- './routes-generated': path.resolve(process.cwd(), 'patternfly-docs/generated/index.js')
119
+ './routes-generated': path.resolve(process.cwd(), 'patternfly-docs/generated/index.js'),
120
+ process: "process/browser"
122
121
  },
123
122
  modules: [
124
123
  'node_modules',
125
124
  ...module.paths,
126
- ]
125
+ ],
126
+ fallback: {
127
+ "path": require.resolve("path-browserify")
128
+ },
127
129
  },
128
130
  // Use this module's node_modules first (for use in Core/React workspaces)
129
131
  resolveLoader: {
130
132
  modules: module.paths,
131
133
  },
132
134
  plugins: [
135
+ new webpack.ProvidePlugin({
136
+ process: 'process/browser',
137
+ }),
133
138
  new webpack.DefinePlugin({
134
139
  'process.env.NODE_ENV': JSON.stringify(mode),
135
140
  'process.env.pathPrefix': JSON.stringify(isProd ? pathPrefix : ''),
141
+ 'process.env.googleAnalyticsID': JSON.stringify(isProd ? googleAnalyticsID : ''),
136
142
  'process.env.algolia': JSON.stringify(algolia),
137
143
  'process.env.hasGdprBanner': JSON.stringify(hasGdprBanner),
138
144
  'process.env.hasFooter': JSON.stringify(hasFooter),
@@ -150,13 +156,9 @@ module.exports = (_env, argv) => {
150
156
  { from: path.join(__dirname, '../../assets'), to: 'assets' }
151
157
  ]
152
158
  }),
153
- new MonacoWebpackPlugin(),
154
- ...(isProd
155
- ? [
156
- new CleanWebpackPlugin()
157
- ]
158
- : []
159
- )
159
+ new MonacoWebpackPlugin({
160
+ globalAPI: true,
161
+ })
160
162
  ],
161
163
  stats: 'minimal'
162
164
  };
@@ -5,6 +5,7 @@ const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPl
5
5
  const MiniCssExtractPlugin = require('mini-css-extract-plugin');
6
6
  const TerserPlugin = require('terser-webpack-plugin');
7
7
  const CopyPlugin = require('copy-webpack-plugin');
8
+ const webpack = require('webpack');
8
9
  const baseConfig = require('./webpack.base.config');
9
10
  const { getHtmlWebpackPlugins } = require('./getHtmlWebpackPlugins');
10
11
 
@@ -23,18 +24,20 @@ const reactJSRegex = /react-([^\\/]*)[\\/]dist[\\/].*\.js$/
23
24
 
24
25
  const clientConfig = async (env, argv) => {
25
26
  const isProd = argv.mode === 'production';
26
-
27
27
  return {
28
28
  output: {
29
29
  path: argv.output ? path.resolve(argv.output) : path.resolve('public'),
30
- filename: '[name].[hash].bundle.js'
30
+ filename: '[name].[contenthash].bundle.js'
31
31
  },
32
32
  devServer: {
33
33
  hot: true,
34
34
  historyApiFallback: true,
35
+ compress: true,
35
36
  port: argv.port,
36
- clientLogLevel: 'info',
37
- stats: 'minimal'
37
+ client: {
38
+ logging: 'info',
39
+ },
40
+ static: {}
38
41
  },
39
42
  optimization: {
40
43
  splitChunks: {
@@ -71,10 +74,7 @@ const clientConfig = async (env, argv) => {
71
74
  },
72
75
  minimize: isProd ? true : false,
73
76
  minimizer: [
74
- new TerserPlugin({
75
- cache: path.join(process.cwd(), '.cache/terser'),
76
- ...(process.env.CI ? { parallel: 2 } : {})
77
- }),
77
+ new TerserPlugin(),
78
78
  ],
79
79
  runtimeChunk: 'single',
80
80
  },
@@ -82,7 +82,6 @@ const clientConfig = async (env, argv) => {
82
82
  rules: [
83
83
  {
84
84
  test: /\.css$/,
85
- exclude: reactCSSRegex,
86
85
  use: [
87
86
  {
88
87
  loader: MiniCssExtractPlugin.loader,
@@ -106,13 +105,12 @@ const clientConfig = async (env, argv) => {
106
105
  }
107
106
  ]
108
107
  },
109
- {
110
- test: reactCSSRegex,
111
- use: 'null-loader'
112
- },
113
108
  ]
114
109
  },
115
110
  plugins: [
111
+ new webpack.DefinePlugin({
112
+ 'process.env.PRERENDER': false,
113
+ }),
116
114
  new MiniCssExtractPlugin(!isProd ? {} : {
117
115
  filename: '[name].[contenthash].css',
118
116
  chunkFilename: '[name].[contenthash].css',